Posted on 04-17-2018 08:39 AM
Anyone has a reboot script that Allows deferral and uses Jamf Helper?. Would like to attach it to an apple updates policy. After the policy runs, it should prompt the user to restart the machine. The user should be allowed to postpone that reboot at least once before it reboots on its own. I have seen some that uses CocoaDialog. We cant/wont use Cocoadialog here at our company.
Posted on 04-17-2018 08:49 AM
I have the rudiments of one that does it with AppleScript. It was designed around our company’s previous energy policy. While I wouldn’t use it as is, I can post it later to help with formulation of what you want to do.
Basically it was triggered at 6 pm and would check if the user was working. If not it would shutdown the computer. If so, it would give a preprescribed message from our energy management folks offering to shutdown or defer. I then had a cron script (that’s how old this is) recall it every two hours offering the same choices. It did that every two hours between 6 pm and 6 am.
Again, I wouldn’t use it as is (we don’t even use it anymore) but it might give you food for thought. I’ll post after lunch.
Posted on 04-17-2018 08:53 AM
@blackholemac , thanks Im actually brand new to scripting. I need to find a way to get what I posted to work.
Posted on 04-17-2018 09:22 AM
Here is one that I use. It checks if the computer has rebooted in the last 4 days. If not a jamfHelper gives them the option of to restart Immediately, 2 mins, 5 mins or 1 hour. The user then gets another jamf helper as a 1 min warning to restart. It is setup on a once a day recurring checkin policy but only executes if the last reboot was at least 4 days ago. The number of days can be edited by editing this line if [ $diffDays -ge 4 ];then to your desired number of days. It also checks for a custom logo we populate on our computers. If not present it will use a built in icon. Test, test, and test again before using in a production environment.
#!/bin/bash
#######################################################################################
#
# Copyright (c) 2016, JAMF Software, LLC. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the JAMF Software, LLC nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#######################################################################################
#
#######################################################################################
#
# This script will check the last reboot date of the computer. If it has been
# more than 3 days the user is presented a popup with the option to reboot now,
# or delay for 2 minutes, 5 minutes, or 1 hour. 1 minute from the planned reboot
# another popup is presented with a 1 minute countdown.
#
# Modified by Mike Donovan March 1, 2018
#######################################################################################
# jss.jhp.delay.sh
# ©2016 brock walters jamf
#
#
# the information in the jamfhelper pop-up window can be modified by changing the following below:
#
# -title
# -heading
# -description
# -icon (eg, a .b64 encoded .png or .icns file in the script or a reference to a graphics file)
# -button1 (limited characters in field)
# -button2 (limited characters in field)
# -showDelayOptions (in seconds)
#
# for other jamfHelper options see:
#
# /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -help
#
# the case statement takes input from the jamfHelper button exit code variable "$result"
#
# some command or a series of commands separated by pipes or newlines or other functions
# containing lists of commands could be added to the script & called by replacing "$cmdstr"
# & "$pthstr" with the function names.
###########################################################################################
#
# Modified for KISD by Mike Donovan March 8, 2018
#
#
###########################################################################################
cleanUp(){
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# CREATE FIRST BOOT SCRIPT
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
/bin/mkdir /usr/local/jamfps
/bin/echo "#!/bin/bash
## First Run Script to remove the installer.
## Clean up files
/bin/rm -f /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
/bin/rm -f /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
/bin/rm -f /Library/Scripts/rebootwarning.sh
launchctl remove org.yourorgname.rebootdelay
launchctl remove org.yourorgname.rebootdelaywarning
/bin/sleep 2
## Update Device Inventory
/usr/local/jamf/bin/jamf recon
## Remove LaunchDaemon
/bin/rm -f /Library/LaunchDaemons/com.jamfps.cleanupDelayedRestart.plist
## Remove Script
/bin/rm -fdr /usr/local/jamfps
exit 0" > /usr/local/jamfps/cleanupDelayedRestart.sh
/usr/sbin/chown root:admin /usr/local/jamfps/cleanupDelayedRestart.sh
/bin/chmod 755 /usr/local/jamfps/cleanupDelayedRestart.sh
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# LAUNCH DAEMON
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
cat << EOF > /Library/LaunchDaemons/com.jamfps.cleanupDelayedRestart.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jamfps.cleanupDelayedRestart</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/usr/local/jamfps/cleanupDelayedRestart.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
##Set the permission on the file just made.
/usr/sbin/chown root:wheel /Library/LaunchDaemons/com.jamfps.cleanupDelayedRestart.plist
/bin/chmod 644 /Library/LaunchDaemons/com.jamfps.cleanupDelayedRestart.plist
}
lastBootRaw=$(sysctl kern.boottime | awk -F'[= |,]' '{print $6}')
lastBootFormat=$(date -jf "%s" "$lastBootRaw" +"%m-%d-%Y")
today=$(date +%s)
#today=$(date -v+4d +%s) ###########For Testing #############################################
diffDays=$(( (today - lastBootRaw) / 86400 ))
#echo $diffDays
if [ $diffDays -ge 4 ];then
#echo "4 days or more Running Reboot script"
file=$(find /Library/Application Support/JAMF/bin/KISDColorseal.png)
if [ ! -z "$file" ]
then
useIcon=/Library/Application Support/JAMF/bin/KISDColorseal.png
#echo "found"
else
useIcon=/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertCautionIcon.icns
#echo "not found"
fi
else
#echo "3 days or less Exiting"
exit 0
fi
jamfhelper()
{
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper
-windowType utility
-title "KISD Mac Systems Admin"
-heading "It's time to reboot"
-description "This computer has not restarted since $lastBootFormat. Restart now or choose a delay option."
-icon "$useIcon"
-iconSize 110
-button1 "Delay"
-button2 "Restart Now"
-showDelayOptions "120, 300, 3600" # 2 minutes, 5 minutes, 1 hour
}
# variables
result=$(jamfhelper)
delayint=$(echo "$result" | /usr/bin/sed 's/.$//')
warndelayint=$(expr $delayint - 60)
#echo $delayint
#echo $warndelayint
defercal=$(($(/bin/date +%s) + delayint))
hour=$(/bin/date -j -f "%s" "$defercal" "+%H")
minute=$(/bin/date -j -f "%s" "$defercal" "+%M")
#echo $hour
#echo $minute
warndefercal=$(($(/bin/date +%s) + warndelayint))
warnhour=$(/bin/date -j -f "%s" "$warndefercal" "+%H")
warnminute=$(/bin/date -j -f "%s" "$warndefercal" "+%M")
#echo $warnhour
#echo $warnminute
# write launch daemon populated with variables from jamfHelper output
delay()
{
/bin/cat <<EOF > /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.yourorgname.rebootdelay</string>
<key>ProgramArguments</key>
<array>
<string>reboot</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>$hour</integer>
<key>Minute</key>
<integer>$minute</integer>
</dict>
</dict>
</plist>
EOF
}
warndelay()
{
/bin/cat <<EOF > /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.yourorgname.rebootdelaywarning</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>/Library/Scripts/rebootwarning.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>$warnhour</integer>
<key>Minute</key>
<integer>$warnminute</integer>
</dict>
</dict>
</plist>
EOF
}
warnScript()
{
/bin/cat <<EOF > /Library/Scripts/rebootwarning.sh
#!/bin/bash
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper
-windowType utility
-title "KISD Systems Admin"
-heading "It's time to reboot"
-description "This computer is set to reboot in 1 minute."
-timeout 60
-countdown
-lockHUD
-icon "$useIcon"
-iconSize 110
-button1 "Ok"
EOF
}
finalPrep()
{
# unload launchd
#launchctl unload /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
#launchctl unload /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
# set ownership on delay launch daemon
chown root:wheel /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
chmod 644 /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
# set ownership on delaywarning launch daemon
chown root:wheel /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
chmod 644 /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
#load launchd
launchctl load /Library/LaunchDaemons/org.yourorgname.rebootdelay.plist
launchctl load /Library/LaunchDaemons/org.yourorgname.rebootdelaywarning.plist
}
# select action based on user input
case "$result" in
*1 ) delay
warndelay
warnScript
finalPrep
cleanUp
;;
*2 ) reboot
echo "Reboot Called"
;;
esac
exit 0
Posted on 08-27-2021 09:03 PM
Do you have an updated script for Catalina, bigsur. was trying to get this working,
Posted on 11-21-2022 09:29 AM
How can i edit this script to change the final reboot warning timer for 1 minute to 15 minutes ?
Seems like you can't just edit a line when using these jamf helper scripts.
Any help would be appreciated
Posted on 04-17-2018 09:42 AM
by default I like @m.donovan 's script better as I never really liked mine, but it got the job done. I don't use mine anymore because I was able to persuade our energy management czar that full shutdowns as opposed to sleep don't really save power. That being said, I keep it just in case I can't win that argument. If it helps great, if nothing else, I have @m.donovan 's script to use if I'm ever forced to consider a shutdown script again.
#!/bin/sh
#######################DEFINE VARIABLES AND READ-IN PARAMETERS############################
minutesN=5
# Number of minutes to count down before shutdown
shutdownAction="shutdown -h now"
# Change to "shutdown -r now" to reboot
# Change to "shutdown -h now" to shut down
notificationMessage="ATTENTION!!!! ATTENTION!!!! ATTENTION!!!!
In an effort to conserve energy during evenings and weekends, this Mac is scheduled to shut down in five minutes.
Please save all open documents and close any open applications prior to a shut down."
# This message will appear in the initial dialog box following the initial warning dialog.
shutdownButtonText="Shut Down NOW!"
# This variable should contain either "Shut Down" or "Restart"
# depending on the value of $shutdownAction. This string will appear
# in the dialog and will determine the name of the button that causes
# $shutdownAction to be executed.
shutdownTitle="LSC Automated Shutdown"
# You can customize this to your organization as you see fit.
postponeButtonText="Postpone for 2 Hours"
# Basically this button could say anything as it causes the script to exit 0 when pushed.
openbusinessHour="6"
closebusinessHour="18"
# You would use military time by hour here, for example 6 = 6 a.m., 18 = 6 p.m.
###################################SCRIPT CONTENTS########################################
rm -f /var/log/newshutdowndebug*
# exit 0 if this script accidentally runs during declared business hours
current_hour=`/bin/date +%H`
if [ $current_hour -gt $openbusinessHour -a $current_hour -lt $closebusinessHour ]; then
exit 0
fi
# If no user is logged in at the console, shut down immediately
consoleUser=`/usr/bin/w | grep console | awk '{print $1}'`
if test "$consoleUser" == ""; then
$shutdownAction
fi
function timedShutdown {
button=`/usr/bin/osascript << EOT
try
with timeout of 400 seconds
tell application "Finder"
activate
set question to display dialog "$notificationMessage" with title "$shutdownTitle" buttons {"$postponeButtonText", "$shutdownButtonText"} default button 1 giving up after 300
set answer to button returned of question
return answer
end tell
end timeout
on error
return "error"
end try
EOT`
if test "$button" == "$postponeButtonText"; then
exit 0
elif test "$button" == "$shutdownButtonText"; then
$shutdownAction
elif test "$button" == "error"; then
exit 0
else
$shutdownAction
exit 0
fi
}
timedShutdown
Posted on 04-17-2018 10:13 AM
Hey @mdonovan , I would need your script to run every day with our apple updates policy. Would I be able to configure this to do that? i know you mentioned we can change the days from 4 to anything else.
Posted on 04-17-2018 10:27 AM
I tested @mdonovan script in terminal. It doesn't seem to be working for me. Am I testing it incorrectly?
Posted on 04-17-2018 10:50 AM
Tested both of these and cant get any of them to run. Nothing happens at all.
Posted on 04-17-2018 11:28 AM
When you test this be sure to change these lines as shown. The # comments out the line starting with it. This simulates a reboot older than 4 days. Otherwise the computers actual last reboot date is used. Also you will need to run it as root so if running from the desktop of your test machine I use terminal and enter sudo bash /path/to/file.sh
#today=$(date +%s)
today=$(date -v+4d +%s) ###########For Testing #############################################
Posted on 04-18-2018 09:05 AM
@m.donovan. If i want this to execute immediately after running a policy, would i change the days from 4 to 0?
Posted on 04-18-2018 09:23 AM
The 4 is used in the difference variable to decide the allowed number of days to go without a reboot. If you use the today=$(date +%s) line as is and set the diffDays comparison to 0 then it should execute every time this script is run. So if used in a policy that is on a once per day trigger the user should be prompted to restart once everyday. However, I don't think this going to happen at the same time everyday. You may get users that are prompted to restart at 3pm Monday and again at 7AM on Tuesday. You should really do some testing to see how this will impact your users.
Posted on 04-18-2018 10:18 AM
@mdonovan , what im needing is starting to become a lot more difficult. I need a script that restarts computers after apple updates. All apple updates do not require a reboot. So I need a script to only execute when an apple updates requires a restart. I would need the script to execute every time the apple updates script has run.
Posted on 04-18-2018 10:35 AM
@kadams Maybe I missed it, but how are the Apple updates you're referring to being installed? Do you have a separate script that's installing those updates, and, are they first being cached from a Jamf policy, and then installed, or are you installing them using a softwareupdate
command?
So you know, you can get the restart flag from a package using the installer
command. For example:
/usr/sbin/installer -query RestartAction -pkg /path/to/Package.pkg
The above will return a few different string possibilities, including
None (Means no reboot required)
RecommendRestart
RequireLogout
RequireRestart (Most common one for pkgs that require a restart, like most security updates, etc)
RequireShutdown
Using the above, if you are caching these installers, then installing them in a script, you should be able to query for the restart action on each pkg and if any require or recommend restart, set a variable that would then initiate your reboot after the script completes the installs successfully.
Conversely, if none of the updates to be installed require or recommend a reboot, logout or other action, then don't do anything after they are all installed.
Hopefully that makes some sense.
Posted on 04-18-2018 02:06 PM
@mm2270 We have this script thrown in a policy sudo sh -c "softwareupdate -ia".
Posted on 09-02-2018 06:49 PM
@m.donovan I've been playing with your script and really like the way it works. However have found that users can just ignore the initial dialog box, move it out of the way at the bottom of the screen and continue on for days. Is there a way to make it time out and just restart if no options are selected?
Posted on 05-06-2019 10:13 AM
I know this is a little old but this is the script I am using for applying forced updates. It will automatically time out after 5 minutes and choose to delay the update if the user ignores the window. You can also choose your deferral amounts by changing a $maxdeferrals number to whatever you would like. It does delay one hour each deferment though which can be changed with a few edits. Once the counter expires or they select restart now, then the update command executes. Hope this helps.
#!/bin/bash
#set deferral counter to zero
deferral=0
#set max amount of deferments a users can make
maxdeferrals=3
choice="2"
#edit title and msg that you want displayed in the pop up window
TITLE="Restart required"
MSG="Software Updates are ready to be installed on your Mac that require a restart.
You can choose to restart now, or delay this restart by 1 hour by choosing the option below:"
#Launches pop up
while [ "$choice" -ne "0" ]
do
#You can choose which icon you would like to appear in the pop up here
ICON="/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdate.icns"
choice=$(/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "$TITLE" -description "$MSG" -icon "$ICON" -button1 "Restart Now" -button2 "Delay 1h" -defaultButton 2 -lockHUD -timeout 300)
#adds one to the deferral counter
if [ "$choice" -eq "2" ];
then ((deferral+=1))
fi
if [ "$choice" -ne "0" ] && [ "$deferral" -lt "$maxdeferrals" ];
then sleep 3600
else ((choice = "0"))
fi
done
softwareupdate -ia --restart
Posted on 01-15-2020 11:08 AM
@jkupidura, I am testing with your script, thanks. What I am looking to do is give the user an option to defer for 2 hours each time with a maximum of 12 deferrals (24 hours) and then the update will force run. New to scripting too. So what I need to do is:
I don't understand the "It does delay one hour each deferment though which can be changed with a few edits." What gets delayed one hour? I thought when you click on the number 2 button it will defer for whatever your value is in the "sleep"?
Appreciate any help.
Posted on 04-25-2020 10:59 PM
@JeyT did you test the script with 24 hours deferral? i also wondering to test that
Posted on 04-28-2020 01:01 PM
@Rohirtds14 I have not. Waiting on the release of the new deferral feature in 10.21. Hope that fixes this. Thanks
Posted on 02-21-2023 01:34 PM
i tried @m_donovan script posted on 2018-04-17. My Jamf logs shows the following.
Script result: find: /Library/Application: No such file or directory
find: Support/JAMF/bin/KISDColorseal.png: No such file or directory /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 157: /Library/Application: No such file or directory /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 158: -windowType: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 159: -title: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 160: -heading: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 161: -description: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 162: -icon: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 163: -iconSize: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 164: -button1: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 165: -button2: command not found /Library/Application Support/JAMF/tmp/
Jamf Helper Reboot Script with Deferral: line 166: -showDelayOptions: command not found expr: syntax error
I'm not too familiar scripts and the command's syntax. Any insight on the error message would be greatly appreciated.