Posted on 09-02-2016 03:09 PM
JAMF Nation folks! I am in need of some advice on how to restart a computer within a if-else/else-if loop of a JAMF Helper script. The script's purpose is to perform software and security updates and then reboot the computer if the user decides to opt in. If not, an echo command is sent and they'll be prompted again the following day. The opt-in and opt-out portions work great and the updates are applied. The only issue here is with the actual restarting of the computer.
if [ "$userChoice" == "0" ]; then
echo "User clicked UPDATE; now downloading and installing all available updates."
softwareupdate --install --all
osascript -e 'tell application "System Events" to restart'
elif [ "$userChoice" == "2" ]; then
echo "User clicked Cancel or timeout was reached; now exiting."
exit 0
fi
The problematic line is osascript -e 'tell application "System Events" to restart'. An error is generated as well within the JSS logs. Here's the error that is received.
36:43: execution error: An error of type -10810 has occurred. (-10810)
The error here pertains to access rights and not being able to run with elevated permissions--i.e. sudo. Is there a work-around to get this to restart?
Solved! Go to Solution.
Posted on 09-02-2016 05:43 PM
This did the trick!
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
Posted on 09-03-2016 04:04 AM
@hcodfrie As requested, here you go!
#!/bin/bash
# Grab icon image from specified URL and place into /tmp
/usr/bin/curl -s -o /tmp/lock_icon.png http://core0.staticworld.net/images/article/2014/11/security-and-privacy-icon-100529575-large.png
loggedInUser=$(stat -f%Su /dev/console)
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="There is a critical security update avaialble for your <CompanyName>-issued computer. To perform the update, select 'UPDATE' below and the security update will begin to run. Once complete, you will be prompted to 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/lock_icon.png"
title="Critical: Apple Security Update Available"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="900"
# JAMF Helper window as it appears for targeted computers
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2")
# If user selects "UPDATE"
if [ "$userChoice" == "0" ]; then
echo "User clicked UPDATE; now downloading and installing all available updates."
# Install ALL available software and security updates
softwareupdate --install --all
# Present user with 60 second countdown to restart computer; user may opt out of restart
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
# If user selects "Cancel"
elif [ "$userChoice" == "2" ]; then
echo "User clicked Cancel or timeout was reached; now exiting."
exit 0
fi
Here's the policy that the above script is being used in. Pretty basic stuff here; once per day at recurring check-in with a smart computer group and an inventory update at the end.
This is the smart computer group that I am using. Right now, I am in testing so it's scoped to the "it-15434" computer. When I am ready to go live in production, I will remove this line. You'll also noticed the other nested computer group being used. The "OS X Yosemite 10.10.5, El Capitan 10.11.6" is pretty self-explanatory but I've used it elsewhere so thought of just using it again here instead of specifying the same criteria again.
And lastly, here's the restart window. Hope this helps :)
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
Posted on 09-02-2016 05:43 PM
This did the trick!
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
Posted on 09-02-2016 08:50 PM
You're using osascript, which is essentially running an AppleScript command inside your shell script. I suggest instead using the shutdown command directly within your shell script:
shutdown -r now
Posted on 09-02-2016 11:27 PM
Hi @sepiemoini interested in the rest of that script since i was working to do the same yesterday :)
Posted on 09-03-2016 04:04 AM
@hcodfrie As requested, here you go!
#!/bin/bash
# Grab icon image from specified URL and place into /tmp
/usr/bin/curl -s -o /tmp/lock_icon.png http://core0.staticworld.net/images/article/2014/11/security-and-privacy-icon-100529575-large.png
loggedInUser=$(stat -f%Su /dev/console)
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
windowType="hud"
description="There is a critical security update avaialble for your <CompanyName>-issued computer. To perform the update, select 'UPDATE' below and the security update will begin to run. Once complete, you will be prompted to 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/lock_icon.png"
title="Critical: Apple Security Update Available"
alignDescription="left"
alignHeading="center"
defaultButton="2"
timeout="900"
# JAMF Helper window as it appears for targeted computers
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2")
# If user selects "UPDATE"
if [ "$userChoice" == "0" ]; then
echo "User clicked UPDATE; now downloading and installing all available updates."
# Install ALL available software and security updates
softwareupdate --install --all
# Present user with 60 second countdown to restart computer; user may opt out of restart
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
# If user selects "Cancel"
elif [ "$userChoice" == "2" ]; then
echo "User clicked Cancel or timeout was reached; now exiting."
exit 0
fi
Here's the policy that the above script is being used in. Pretty basic stuff here; once per day at recurring check-in with a smart computer group and an inventory update at the end.
This is the smart computer group that I am using. Right now, I am in testing so it's scoped to the "it-15434" computer. When I am ready to go live in production, I will remove this line. You'll also noticed the other nested computer group being used. The "OS X Yosemite 10.10.5, El Capitan 10.11.6" is pretty self-explanatory but I've used it elsewhere so thought of just using it again here instead of specifying the same criteria again.
And lastly, here's the restart window. Hope this helps :)
osascript -e 'tell app "loginwindow" to «event aevtrrst»'
Posted on 09-03-2016 07:37 AM
@sepiemoini Any particular reason for curling down that icon, when it exists on any recent OS X system by default? Its in the following path:
/System/Library/CoreServices/loginwindow.app/Contents/Resources/FileVault_logo.tiff
Its possible in some versions of OS X its not a .tiff. but a .png format or other, but in general that path should work.
Its also in the following path as well, although its an icns format, and somehow looks slightly different than the tiff version.
/System/Library/PreferencePanes/Security.prefPane/Contents/Resources/FileVault.icns
You should be able to use either one of those as a path to the icon with jamfHelper.
Posted on 09-03-2016 08:44 AM
@mm2270 Greetings! Using .icns files isn't ideal as the best file format, in my experience, has been using .png files. Since users will need network connectivity to check-in and run the script/software updates, I didn't see the harm in using ones online. I guess I could package an icon bundle and deploy those; that'd be pretty cool, eh?
Posted on 09-04-2016 09:28 PM
Thanks
Posted on 09-06-2016 07:17 AM
@talkingmoose I've used the "reboot" command for something similar. Is there an advantage of using "shutdown -r now" over it that you're aware of?
Posted on 09-06-2016 07:47 AM
@sepiemoini Thanks for posting your script. I do have a question about your policy though.
Does the inventory update actually serve a purpose? From what I can tell your script is going to run and then either reboot or not reboot. If it doesn't reboot, the inventory would be unchanged. If it does reboot, doesn't it reboot before gathering the inventory?
If I'm wrong on this, feel free to say. I worked on something similar once and the inventory aspect just didn't seem to work that way for me so I have my systems all currently set to update inventory each time they start up. If I'm right, I guess it doesn't hurt anything functionally but am curious if it really works for you.
Posted on 09-06-2016 07:58 AM
@jhuls Our environment is not terribly large and the added inventory traffic does not contribute to a significant load on our server or network. I typically configure this payload so that dynamic group memberships are updated following the completion of certain actions. Does that answer your question?
Posted on 09-06-2016 08:04 AM
@sepiemoini Not really. Hopefully long story short I'm interested in knowing how the Update Inventory portion of the policy would completely run if the script that runs before it has told the computer to restart. I can see where in some cases it might still collect the inventory before it shuts down on the restart but it doesn't seem like it would be reliable in some cases. Like I said I had some trouble with it in the past for a script that did a restart.
Posted on 09-06-2016 08:32 AM
@jhuls Upon deeper investigation, it in fact, is not doing much for reasons that you raised. A separated "Update Inventory" policy which runs once per day is kicking in after the software update policy runs. I'll keep this in mind for future policies instead of relying on muscle memory. Thanks for the suggestion/input!
Posted on 09-06-2016 08:53 AM
@mm2270 @jhuls On a related note with another JAMF Helper script, is it possible to run a sudo command within this script? Say if I wanted to run a JSS policy based on the user's input?
#!/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 <CompanyName>-issued computer is not currently running the latest OS X version. To perform the update, select 'UPDATE' below and the security update will begin to run. Once complete, you will be prompted to 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"
cancelButton="2"
timeout="300"
userChoice=$("$jamfHelper" -windowType "$windowType" -lockHUD -title "$title" -timeout "$timeout" -defaultButton "$defaultButton" -cancelButton "$cancelButton" -icon "$icon" -description "$description" -alignDescription "$alignDescription" -alignHeading "$alignHeading" -button1 "$button1" -button2 "$button2")
if [ "$userChoice" == "0" ]; then
echo "User clicked UPDATE; now running OS X El Capitan Installer via JSS policy ID 547."
sudo jamf policy -id 547
elif [ "$userChoice" == "2" ]; then
echo "User clicked Cancel or timeout was reached; now exiting."
exit 0
fi
The problematic line being this one:
sudo jamf policy -id 547
Posted on 09-06-2016 09:10 AM
Ahhh worth noting that when I created a test JSS policy, I am all set -- please ignore the above post :)
Posted on 09-06-2016 09:03 PM
@jhuls, both commands will restart the Mac. Using the osascript command, you will get the dialog prompting to press a button to complete the restart. That may or may not be what you want.
I mentioned using the "shutdown" command because it just reduces complexity in your script. You started in bash but dipped into AppleScript (another scripting language) by calling the osascript command. My advice for anyone creating scripts is to do as much in one language as possible and only call another scripting language when necessary.
The less complex your code, the easier it is to read and troubleshoot.
Posted on 10-13-2016 04:37 AM
@sepiemoini
The script works great, is it possible to add an option of two deferrals of 1-4 hours each before a forced restart.
Many thanks
Posted on 10-13-2016 07:58 AM
Instead of deferrals for restart, we use the deferrals option for installing updates. If interested, read on.
Deferrals is not working correctly in policies but we manage to work around the bug by setting the policy frequency to ongoing and scoping to a smart group that have pending updates. See discussion here regarding the deferral bug...
Link
If you are running JSS 9.96, you will have to work around another bug. The Software Update count does not show the proper number of updates available. The workaround is shown in forum link below...
Link
Once updates are installed and system reboot, another policy is needed to remove the system form the smart group. To do so we have an ongoing policy that runs on login to update inventory, scoped to the same smart group that have pending updates.
Summary of our Install Apple Critical Updates policy.
Posted on 12-17-2018 11:08 AM
@dmhlanga008 I need the exact same thing. I need a deferral option for users. I need a force restart after a set amount of time as well..
Posted on 12-17-2018 11:36 AM
Ditto here, we are currently making a script of this exact process
Posted on 02-20-2020 07:46 AM
@sepiemoini Love the script. We have recently had some push back from our more vocal associates on not wanting to have their updates forced upon them. This script does exactly what we needed. A gentle "Nudge" so to say update your darn MAC... Also utilizing it in combo with a second script to kick off in place upgraded. Instead of using the policy id I am using custom triggers. But anyway, just wanted to say thanks.