Jamf Helper for first ten logins on user

Macuser1810
New Contributor III

Hi All,

Does anyone know if there is a way to show a JAMF helper window depending on the amount of times a user has logged into the laptop. Basically I want JAMF helper to pop up for the first ten times a user logs in and display a message

Would i be able to do this using maybe a check in policy, like the first ten check ins it displays the message?

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

@Macuser1810 Here's basic code to get you started. I don't know what you were displaying in the message, so the jamfHelper part of this is left very generic. You can update it with your own code. But the rest should be ok to use as is. Test it out and see if it does what you want.

Script example:

#!/bin/zsh

## Path to jamfHelper executable
JAMF_HELPER="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"

## This is our starting counter value. This gets placed into the plist file on first run under any account
START_VALUE="1"

## Maximum number of times the message should be displayed before stopping
MAX_VALUE="10"

## Get the current logged in user
LOGGED_IN_USER=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");' | sed '/^$/d')

## Set the path to the counter file for the current user
COUNTER_FILE="/Users/$LOGGED_IN_USER/Library/Preferences/com.company.messagecounter.plist"

## Create the initial counter plist file if it's not already present, and set the current count value to 1, or
## if the counter file exists, grab the value from it
if [ ! -e "$COUNTER_FILE" ]; then
    /usr/bin/defaults write "$COUNTER_FILE" displayCount -int "$START_VALUE"
    CURRENT_VALUE="$START_VALUE"
else
    CURRENT_VALUE=$(/usr/bin/defaults read "$COUNTER_FILE" displayCount)
fi

if [ "$CURRENT_VALUE" -lt "$MAX_VALUE" ]; then
    ## Display the jamfHelper message here.
    ## Message gets pushed to the background so it doesn't hang up the script.
    ## Replace placeholder text strings below or use your own jamfHelper message code
    "$JAMF_HELPER" 
        -windowType utility 
        -title "Title" 
        -heading "Heading" 
        -description "Description" 
        -button1 "OK" 
        -defaultButton 1 &

    ## Update the count and replace the value in the plist
    NEW_VALUE=$((CURRENT_VALUE+1))
    /usr/bin/defaults write "$COUNTER_FILE" displayCount -int "$NEW_VALUE"
else
    echo "The counter value is ${CURRENT_VALUE}, so we are no longer displaying the message"
fi

I trust you're ok with putting this into a policy and setting it to the login trigger and ongoing frequency, which would be the other half of this.
One thing to test out is to make sure it actually runs at login. If your Macs connect to Wi-Fi like most, there's a possibility that the network connection isn't active at login time and the policy may not actually run. There are some workarounds to that, such as deploying this as an offline policy for example.

View solution in original post

9 REPLIES 9

mm2270
Legendary Contributor III

This shouldn't be hard to do. You'd have to have the script write out a value, starting at 1, into a local file or plist that can store the 'count' of how many times the jamfHelper window has appeared. Each time the script runs, before it pops up any message, have it read back the value from the file/plist and check it. If it is lower than 10, display the message. If it's 10, then stop displaying the message.
If you want to ensure that any user that logs into the Mac will get the equal amount of 10 prompts then stop scenario, you could write the value into the user's directory somewhere, like in the ~/Library/Preferences/ or ~/Library/Application Support/ folder for example. So each user would have their own local file that keeps track of how many times it has run.
You would attach this script to a policy using the login trigger, and probably set to Ongoing for the frequency.

If you need an example of how this could work, post back and I'll post a framework up here.

Macuser1810
New Contributor III

@mm2270 Thanks for the reply. That sounds like a simpler way than ive seen on the forums before. I would really appreciate an example, just so I can see the framework on how this takes place

mm2270
Legendary Contributor III

@Macuser1810 Here's basic code to get you started. I don't know what you were displaying in the message, so the jamfHelper part of this is left very generic. You can update it with your own code. But the rest should be ok to use as is. Test it out and see if it does what you want.

Script example:

#!/bin/zsh

## Path to jamfHelper executable
JAMF_HELPER="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"

## This is our starting counter value. This gets placed into the plist file on first run under any account
START_VALUE="1"

## Maximum number of times the message should be displayed before stopping
MAX_VALUE="10"

## Get the current logged in user
LOGGED_IN_USER=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");' | sed '/^$/d')

## Set the path to the counter file for the current user
COUNTER_FILE="/Users/$LOGGED_IN_USER/Library/Preferences/com.company.messagecounter.plist"

## Create the initial counter plist file if it's not already present, and set the current count value to 1, or
## if the counter file exists, grab the value from it
if [ ! -e "$COUNTER_FILE" ]; then
    /usr/bin/defaults write "$COUNTER_FILE" displayCount -int "$START_VALUE"
    CURRENT_VALUE="$START_VALUE"
else
    CURRENT_VALUE=$(/usr/bin/defaults read "$COUNTER_FILE" displayCount)
fi

if [ "$CURRENT_VALUE" -lt "$MAX_VALUE" ]; then
    ## Display the jamfHelper message here.
    ## Message gets pushed to the background so it doesn't hang up the script.
    ## Replace placeholder text strings below or use your own jamfHelper message code
    "$JAMF_HELPER" 
        -windowType utility 
        -title "Title" 
        -heading "Heading" 
        -description "Description" 
        -button1 "OK" 
        -defaultButton 1 &

    ## Update the count and replace the value in the plist
    NEW_VALUE=$((CURRENT_VALUE+1))
    /usr/bin/defaults write "$COUNTER_FILE" displayCount -int "$NEW_VALUE"
else
    echo "The counter value is ${CURRENT_VALUE}, so we are no longer displaying the message"
fi

I trust you're ok with putting this into a policy and setting it to the login trigger and ongoing frequency, which would be the other half of this.
One thing to test out is to make sure it actually runs at login. If your Macs connect to Wi-Fi like most, there's a possibility that the network connection isn't active at login time and the policy may not actually run. There are some workarounds to that, such as deploying this as an offline policy for example.

Macuser1810
New Contributor III

@mm2270 Thank you for this. just three questions, 1. Is there any harm in running this as a bash script? I know zsh is the new default but zsh is capable of running bash scripts
2. If I run this as an offline policy, does that affect the count for login and policy execution, in terms of knowing when to stop showing it?
3. Does this count the amount of total times? or does it start the count to ten once the policy has been deployed on the machine?

mm2270
Legendary Contributor III

Hey @Macuser1810
So yeah, this should work perfectly fine as a bash script. I just used #!/bin/zsh since, as you said, it's now the default shell. But swapping it out for #!/bin/bash would work fine also, at least for as long as bash is being included in the OS.

As for your second question, I wasn't saying you should definitely run this as an offline policy. It was just that if you did have issues running it as a regular check in policy, then you could consider switching it to offline. The way an offline policy works is that it needs to run at least the first time under it's regular trigger, after which time the jamf binary stores all the elements of that policy that it downloaded locally so it can run again if the Jamf Pro server isn't reachable. But the first time it does need to be able to connect to the Jamf Pro server on it's set trigger(s). To answer your more specific question though, it should all work the same way since it's running a script and checking for the local file that captures the number of times the message was displayed. Being offline shouldn't change any of that.

Lastly, this counts the number of times after first being deployed. It isn't going to go back and look at how many previous logins there were on that machine. It's semi possible to do that, but this script and setup would work best for newly deployed machines. In other words, push it out to newly configured Macs as part of the setup and it should start working right away and will show the number of times you specify in the script for any log-ins.

Hope those answers help.

Macuser1810
New Contributor III

@mm2270 I just tested this and the policy completes but it seems that it doesnt appear at a login after the first time. Any thoughts, there is no errors on the policy.

mm2270
Legendary Contributor III

@Macuser1810 Does the policy log show that it ran? I assume yes, but just want to make sure we aren't running into that scenario discussed where the policy doesn't actually happen if it can't reach the server.

Assuming it does show that it ran, the first thing I would check, assuming you are running this on a Mac you have access to, is if the plist file was created. For example, use this defaults command to see if the file is there and what it's contents are:

defaults read /Users/$(stat -f%Su /dev/console)/Library/Preferences/com.company.messagecounter.plist

If you renamed what the plist file is called, change the last part of the path to match.
Either way, see what the output is. On my system that I ran the tests on, I see this, since I ran it a total of 10 times

{
    displayCount = 10;
}

You should see something, some value show up for displayCount if it ran at all.

If instead you get an error, then there was a problem creating the local plist file. It is possible that since it runs as root when executed from a Jamf policy that maybe the way it's creating the plist file is causing an issue.
I only ran my tests first locally, then in a throwaway policy using a custom trigger. I did not actually test it as an actual policy using a Login trigger, so there may be some issue there. I can drop it into a policy using the login trigger and test it on my own and see though

Macuser1810
New Contributor III

@mm2270 it did run successfully, but now when I go to check if the plist was created I get an error that it does not exist. I have it setup to trigger at login, and ongoing frequency, I also made it available offline

mm2270
Legendary Contributor III

Hmm, so somehow it's not creating the local plist file for the user it seems?
Let me run a couple of tests when I can, probably later, and see if I can spot what the issue is. In my initial tests it worked for me.