Apply Logon Script to Specific AD Users

johnnasset
Contributor

I've been tasked with deploying a web clip to just teacher users in our district. The easiest way to differentiate teacher from student accounts is all students logon using their student ID number while teacher have an alpha AD username. I'd like to run this script to all users excluding those with numeric usernames. Once confirmed the account is a teacher account, I will use dockutil to add the web clip. Any thoughts on the AD username piece?

9 REPLIES 9

mm2270
Legendary Contributor III

Can this just be done by AD group instead? I'm guessing you probably already thought of that and its not an option. If so, then one thing you can do is some simple math operations when getting the logging in user's ID.

For example.

#!/bin/sh

## get logged in user (could also possibly use Casper's $3 for this instead)
loggedInUser=$( ls -l /dev/console | awk '{print $3}' )

if [[ $(expr ${loggedInUser} / ${loggedInUser} 2>/dev/null) == "1" ]]; then
    echo "The user is a student. Skipping"
else
    echo "The user is a teacher"
    ## run some function here or additional commands
fi

The above should let you differentiate between the two types. Basically, it sees if the ID can be divided by itself to result in "1" If so, its a student. If not, its a teacher. Does that make sense?

EDIT: I flipped the process around. Should run a function based on teacher as per your post and not a student. Fixed now.

spraguga
Contributor

If you don't want to write a script you can do a Smart Group with username criteria entires not like %0% or %1% up to 9 with the "or" operator all wrapped in parantheses.

tlarkin
Honored Contributor

Hi Everyone,

I hope everyone is doing well. There are actually several ways I can think of accomplishing this task, and which ever way works best for you, you can try to implement. Here they are in no particular order.

1 - Use a script like @mm2270][/url suggests
2 - If all users are using LDAP accounts, leverage LDAP info in the User and Location field of a device record
3 - Scope to LDAP group via self service
4 - use a flat file with extension attributes

A script like @mm2270][/url posted can most definitely work, and this way you can leave the policy scoped to all devices, or a broad number of devices if LDAP scoping is not an option for you. The second option would be to actually trigger a live LDAP lookup. This is most beneficial if each human has their own device. In a lab or shared computer environment this may not be the best fit, as a teacher could log into a lab computer and a false positive could trigger and then Casper would think that device is in fact a teacher device. The third and final way is to put it in self service and only scope it to the teacher's OU or security group in Active Directory. This means that the end user would have to trigger the process though, and it could not just be automated. However, the Self Service option would also allow you to build logic into your workflow where if a teacher accidentally removed/deleted the webclip from their dock, they could simply re-run the Self Service policy to get it back.

If you want to try out option #2 you would need to enable live LDAP look ups in your JSS. This should be under inventory collection options, under the check box to collect user and location information from LDAP. You would then need to pass a recon command with that end user name to trigger the live LDAP look up. At that point, all user information is now tied to that device. If you use a LDAP field to determine if the user is a teacher or a student (via department, or custom LDAP attribute) you could then just use Smart Groups to do all the scoping for you and deploy it via a policy, similar to what @spraguga][/url is suggesting. That way when users swap devices, or things get reissued the live LDAP look up will eventually toss the device into the proper group.

If none of that is an option you could also use a script like Mike suggested but instead write results to a flat file, and that flat file could then be used in an extension attribute, and then again used to populate smart groups immediately. Thus, you can use all the scoping mechanisms built into the Casper Sutie. Some examples could be:

You would need to create the file locally on each mac:

defaults write /Library/Preferences/com.attributes.jamfsoftware.plist userType unknown

plutil -convert xml1 /Library/Preferences/com.attributes.jamfsoftware.plist

here is an example script to set the value locally:

#!/bin/bash
# detect current user and test if user has numbers of letters in user name

currentUser=$(ls -l /dev/console | awk '{ print $3 }')

if [[ $(echo ${currentUser//[0-9]/}) == '' ]]
  then echo "user has numeric values"
  defaults write /Library/Preferences/com.attributes.jamfsoftware.plist userType student
  else echo "user has letter values"
  defaults write /Library/Preferences/com.attributes.jamfsoftware.plist userType teacher
fi

exit 0

In the above script I am just using bash internals to echo out the current user, and substituting any numeric value with a blank value. So, student accounts should return completely blank if they are just a numeric value to begin with. I then test the string to make sure it is blank or not, if it is blank I set the local attribute as student, if it is not blank I set it to a teacher.

The extension attribute would simply be like this:

#!/bin/bash
results=$(defaults read com.attributes.jamfsoftware.plist userType)
echo "<result>${results}</result>"

This would end up with 3 possible values, student, teacher and unknown. With unknown being the default value set by an initial command or script. That way you can scope smart groups based on those three values, and devices where a user has never logged in yet would be set as 'unknown.'

I hope this makes sense, and hopefully this will answer your question. I think live LDAP look ups would probably be the easiest way to accomplish this if that is an available option at your organization.

Thanks,
Tom

johnnasset
Contributor

Thanks @mm2270, looks great. Here is the script, however, the JSS keeps telling me the ${PlistLocation} variable isn't valid. Probably something small I'm overlooking:

#!/bin/sh

## get logged in user

loggedInUser=$( ls -l /dev/console | awk '{print $3}' )
PlistLocation=$/Users/$loggedInUser/Library/Preferences/com.apple.dock.plist

if [[ $(expr ${loggedInUser} / ${loggedInUser} 2>/dev/null) == "1" ]]; then
echo "The user is a student. Skipping"
else
echo "The user is a teacher" /usr/local/bin/dockutil --add 'https://xxx.sharepoint.com/PLC/' --label 'PLC Workspace' '${PlistLocation}'
fi

nessts
Valued Contributor II

what is $/Users/$loggedInUser
guessing if you remove the $ before the /Users it might help greatly.

mm2270
Legendary Contributor III

Yep, like @nessts mentioned, get rid of that first $ in the plist path. Its not needed and is messing things up.
I would quote the PlistLocation path just to be on the safe side, like this-

PlistLocation="/Users/$loggedInUser/Library/Preferences/com.apple.dock.plist"

Note that I also removed the space you had between the variable name and the path. That might also cause you an issue.

johnnasset
Contributor

Hmm, made the suggest changes:

#!/bin/sh

## get logged in user

loggedInUser=$( ls -l /dev/console | awk '{print $3}' )
PlistLocation="/Users/$loggedInUser/Library/Preferences/com.apple.dock.plist"


if [[ $(expr ${loggedInUser} / ${loggedInUser} 2>/dev/null) == "1" ]]; then
echo "The user is a student. Skipping"
else
echo "The user is a teacher"
 /usr/local/bin/dockutil --add 'https://xxx.sharepoint.com/PLC/' --label 'PLC Workspace' '${PlistLocation}'
fi

Get the following in the logs:

Executing Policy PLC Webclip... Downloading https://xxx.xxx.org/CasperShare/Scripts/PLC_Webclip.sh... Running script PLC_Webclip.sh... Script exit code: 1 Script result: The user is a teacher ${PlistLocation} does not seem to be a home directory or a dock plist

nessts
Valued Contributor II

well yeah, if you are going to use a variable, you cannot wrap it in single quotes, you have to change that to double quotes " instead of ' in the dockutil line.

mm2270
Legendary Contributor III

The error sounds to me like its coming from dockutil and not the script. The path to the plist should be correct, as long as your user accounts are not stored on some other partition. And assuming the target user has logged in at least once there should definitely be a dock.plist file in that location.

What version of dockutil is this you're trying it with? I'm still using 1.1.4 and am seeing no issue in doing the same operation.
I see in the dockutil help that you can also just specify the path to a home directory and let it figure out the rest. Maybe give that a shot?

loggedInUser=$( ls -l /dev/console | awk '{print $3}' )
HomeLocation="/Users/$loggedInUser/"
*<snip>. . . . . .</snip>*
/usr/local/bin/dockutil --add 'https://hsd1.sharepoint.com/PLC/' --label 'PLC Workspace' '${HomeLocation}'

Edit: @nessts is actually correct as well. Wasn't really paying close attention to your quotes. Normally if using a direct path in a dockutil script the single quotes are OK, but if using a variable, double quote it. That's more likely the problem here.