Posted on 09-09-2016 04:23 AM
Greetings, all! I'm fine tuning a JAMF Helper script that I have in place to upgrade with an OS X installer using simple caching. Between the caching and the actual installation of the OS X installer, I want to use a JAMF Helper window to notify the end user of the process, allowing them to opt-in and opt-out.
I am noticing that the notification (running at recurring check-in, once per day) is capable of running when no one is logged onto the computer. This displays the JAMF Helper window at the login screen and eventually just times out. Here is what I would like to accomplish, with your help:
Echo that a timeout has been reached using "243 - The window timed-out with no buttons on the screen."
Before the JAMF Helper command runs, check to see if the logged in user (loggedInUser=$(stat -f%Su /dev/console)) is actually logged onto the computer.
#!/bin/bash
/usr/bin/curl -s -o /tmp/elcapitan_icon.png http://assets.materialup.com/uploads/ec819071-7140-4c6d-89ac-81b712642fcb/512x512bb-85.png
loggedInUser=$(stat -f%Su /dev/console)
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="Your <Organization>-issued computer is not currently running the latest OS X version. To perform the OS X El Capitan update, select 'UPDATE' below and the upgrade will begin to run. Once complete, your computer will restart immediately. If you are unable to perform this update at the moment, please select 'Cancel.'
*Please save all working documents before selecting 'UPDATE.'
If you require assistance, please contact the Helpdesk by phone at <PhoneNumber> or by email at <EmailAddress>."
button1="UPDATE"
button2="Cancel"
icon="/tmp/elcapitan_icon.png"
title="Update Available: Install OS X El Capitan"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="10"
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2")
if [ "$userChoice" == "0" ]; then
echo "$loggedInUser clicked UPDATE; now running OS X El Capitan Installer via JSS policy ID 547."
jamf policy -id 547
elif [ "$userChoice" == "2" ]; then
echo "$loggedInUser clicked Cancel; now exiting."
exit 0
elif [ "$userChoice" == "243" ]; then
echo "Timeout was reached; now exiting."
exit 0
fi
Solved! Go to Solution.
Posted on 09-09-2016 07:30 AM
Thanks, @mm2270! This did the trick :)
#!/bin/bash
/usr/bin/curl -s -o /tmp/elcapitan_icon.png http://assets.materialup.com/uploads/ec819071-7140-4c6d-89ac-81b712642fcb/512x512bb-85.png
## Collect current logged in user
loggedInUser=$(stat -f%Su /dev/console)
## Collect the UID of $loggedInUser, or rather, who owns console
loggedInPID=$(id -u "$loggedInUser")
## Define JAMF Helper variables
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="Your <Organization>-issued computer is not currently running the latest OS X version. To perform the OS X El Capitan update, select 'UPDATE' below and the upgrade will begin to run. Once complete, your computer will restart immediately. If you are unable to perform this update at the moment, please select 'Cancel.'
*Please save all working documents before selecting 'UPDATE.'
If you require assistance, please contact the Helpdesk by phone at <PhoneNumber> or by email at <EmailAddress>."
button1="UPDATE"
button2="Cancel"
icon="/tmp/elcapitan_icon.png"
title="Update Available: Install OS X El Capitan"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="5"
## Collect a count of processes that match ScreenSaverEngine
ScreenSaverCheck=$(ps axc | grep "ScreenSaverEngine" | awk 'END {print NR}')
if [[ "$loggedInPID" != 0 ]] && [[ "$ScreenSaverCheck" == 0 ]]; then
## ScreenSaverEngine.app and/or loginwindow.app is/are not active; run JAMF Helper
echo "The computer is not at the login window nor is the screen saver active."
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2" 2>&1)
else
## ScreenSaverEngine.app and/or loginwindow.app is/are active; exit script
echo "The computer is at the login window and/or has the screen saver active."
exit 0
fi
## JAMF Helper functions for opt-in and opt-out options
if [ "$userChoice" == "0" ]; then
echo "$loggedInUser clicked UPDATE; now running OS X El Capitan Installer via JSS policy ID 547."
jamf policy -id 547
elif [ "$userChoice" == "2" ]; then
echo "$loggedInUser clicked Cancel or timeout was reached; now exiting."
exit 0
fi
Posted on 09-09-2016 04:34 AM
How I do it is the have a policy that caches the installer on all machines, and just have it run once per computer on check-in.
Then, I have another policy that runs the cached installer, but I allow deferral under the User Interaction tab in JSS for the policy. I then put messages using the built in message fields on the policy, explaining the implications of allowing the policy to run vs. selecting a deferral time.
Then, before I activate this policy, I send an email a few days in advance explaining the upgrade process, the implications, and why it is necessary. This allows the majority of users who would have concerns to contact me ahead of time and discuss the upgrade.
I attached an example image as well:
Posted on 09-09-2016 04:57 AM
@McLeanSchool That's a great workflow but I need to stay within this custom JAMF Helper script as it allows for further customization. Any others able to assist?
Posted on 09-09-2016 05:16 AM
Ah, I see. Sorry, I don't know any fixes for the timeout issue.
Posted on 09-09-2016 06:08 AM
I effectively want this to run if loginwindow.app is not running or if it’s locked or if ScreenSaverEngine.app is running. Is this still possible to accomplish within this JAMF Helper script?
Posted on 09-09-2016 06:39 AM
@sepiemoini So, if you're already getting the logged in user with stat -f%Su /dev/console
, you can check who owns the console and if its "root" then the Mac is at the login window (username & password fields)
if [ "$loggedInUser" == "root" ]; then
exit 0
fi
As for screensaver being active, I think you can just run a ps axc
or similar to see if that process is running. Since the ScreenSaverEngine should never be running when someone is using the Mac, that should be a good indication if the screen saver is up.
screenSaverProc=$(ps axc | grep ScreenSaverEngine)
The above should yield no results when the Mac is in use, or one or more results if the screensaver is on.
I'm not certain how to determine if the Mac is locked but the ScreenSaver isn't active, since I think that's a unique state that's different from the others. I'd have to research that. I have a feeling there's a way, but not certain on how.
Posted on 09-09-2016 06:52 AM
@mm2270 Great minds think alike! I think we're on a similar track. How does the below script look to you?
#!/bin/bash
/usr/bin/curl -s -o /tmp/elcapitan_icon.png http://assets.materialup.com/uploads/ec819071-7140-4c6d-89ac-81b712642fcb/512x512bb-85.png
loggedInUser=$(stat -f%Su /dev/console)
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="Your <Organization>-issued computer is not currently running the latest OS X version. To perform the OS X El Capitan update, select 'UPDATE' below and the upgrade will begin to run. Once complete, your computer will restart immediately. If you are unable to perform this update at the moment, please select 'Cancel.'
*Please save all working documents before selecting 'UPDATE.'
If you require assistance, please contact the Helpdesk by phone at <PhoneNumber> or by email at <EmailAddress>."
button1="UPDATE"
button2="Cancel"
icon="/tmp/elcapitan_icon.png"
title="Update Available: Install OS X El Capitan"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="5"
loginwindow="/System/Library/CoreServices/loginwindow.app"
loginwindowCheck="/bin/ps -e | grep '$loginwindow' | grep -vc grep"
ScreenSaver="/System/Library/Frameworks/ScreenSaver.framework/Versions/A/Resources/"
ScreenSaverCheck="/bin/ps -e | grep '$ScreenSaver' | grep -vc grep"
if [[ "$loginwindowCheck"=="0" || "$ScreenSaverCheck"=="0" ]]; then
echo "The computer is not at the login window nor is the screen saver active."
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2" 2>&1)
elif [[ "$loginwindowCheck"=="1" || "$ScreenSaverCheck"=="1" ]]; then
echo "The computer is at the login window and/or has the screen saver active."
exit 0
fi
#userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2" 2>&1)
if [ "$userChoice" == "0" ]; then
echo "$loggedInUser clicked UPDATE; now running OS X El Capitan Installer via JSS policy ID 547."
jamf policy -id 547
elif [ "$userChoice" == "2" ]; then
echo "$loggedInUser clicked Cancel or timeout was reached; now exiting."
exit 0
fi
Posted on 09-09-2016 07:11 AM
Its not exactly how I would do it, but if it works, then it works.
For example, I tend to use ps axc | grep <something>
which avoids needing to a grep -v
later to exclude grep itself from the results. This avoids an extra process (pipe).
Second, I would probably just check to see who owns console, since you already need to get that up front. As I mentioned, when the loginwindow is up, console gets owned by root. I doubt very much any actual user account would be called "root" outside of the actual root account, but if you really wanted to be sure, you could get the UID of the logged in account. Only root would have a UID of 0.
loggedInUser=$(stat -f%Su /dev/console)
## Get the UID of the logged in account, or rather, who owns console
loggedInPID=$(id -u "$loggedInUser")
## Get a count of processes that match ScreenSaverEngine
ScreenSaverCheck=$(ps axc | grep "ScreenSaverEngine" | awk 'END {print NR}')
if [[ "$loggedInPID" != 0 ]] && [[ "$ScreenSaverCheck" == 0 ]]; then
## Someone is logged in and the screen saver isn't running. Continue
<do your stuff here>
else
## Either the screen saver is running, or no-one is logged in, so exit
exit 0
fi
But I'm just showing an alternate way to do it. There's no right or wrong, just different approaches, so by all means, if you like what you have and its working as you expect, then use it.
Posted on 09-09-2016 07:15 AM
I'm liking this script. Perhaps add in a check to make sure device is plugged in to power before the update runs using the following command?
pmset -g ps
Posted on 09-09-2016 07:30 AM
Thanks, @mm2270! This did the trick :)
#!/bin/bash
/usr/bin/curl -s -o /tmp/elcapitan_icon.png http://assets.materialup.com/uploads/ec819071-7140-4c6d-89ac-81b712642fcb/512x512bb-85.png
## Collect current logged in user
loggedInUser=$(stat -f%Su /dev/console)
## Collect the UID of $loggedInUser, or rather, who owns console
loggedInPID=$(id -u "$loggedInUser")
## Define JAMF Helper variables
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="Your <Organization>-issued computer is not currently running the latest OS X version. To perform the OS X El Capitan update, select 'UPDATE' below and the upgrade will begin to run. Once complete, your computer will restart immediately. If you are unable to perform this update at the moment, please select 'Cancel.'
*Please save all working documents before selecting 'UPDATE.'
If you require assistance, please contact the Helpdesk by phone at <PhoneNumber> or by email at <EmailAddress>."
button1="UPDATE"
button2="Cancel"
icon="/tmp/elcapitan_icon.png"
title="Update Available: Install OS X El Capitan"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="5"
## Collect a count of processes that match ScreenSaverEngine
ScreenSaverCheck=$(ps axc | grep "ScreenSaverEngine" | awk 'END {print NR}')
if [[ "$loggedInPID" != 0 ]] && [[ "$ScreenSaverCheck" == 0 ]]; then
## ScreenSaverEngine.app and/or loginwindow.app is/are not active; run JAMF Helper
echo "The computer is not at the login window nor is the screen saver active."
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2" 2>&1)
else
## ScreenSaverEngine.app and/or loginwindow.app is/are active; exit script
echo "The computer is at the login window and/or has the screen saver active."
exit 0
fi
## JAMF Helper functions for opt-in and opt-out options
if [ "$userChoice" == "0" ]; then
echo "$loggedInUser clicked UPDATE; now running OS X El Capitan Installer via JSS policy ID 547."
jamf policy -id 547
elif [ "$userChoice" == "2" ]; then
echo "$loggedInUser clicked Cancel or timeout was reached; now exiting."
exit 0
fi
Posted on 02-27-2018 02:12 PM
Hi all,
I ran across this and was trying to figure out a similar workflow, but instead of checking to see if no user is logged in, I was hoping to check to see if the user is logged in but at a locked screen.
Posted on 05-25-2021 01:57 PM
Does 243 still work? Its nice to see when it times out vs clicks cancel
elif [ "$userChoice" == "243" ]; then
echo "Timeout was reached; now exiting."
exit 0