Skip to main content

Since Jamf hasn't implemented a few of the feature requests out there that would make this better, I have resorted to making a script and using Jamf helper. I stole a lot of it from https://www.jamf.com/jamf-nation/discussions/5404/jamfhelper-software-update-trigger. My goal is to incorporate the new softwareupdate -i -a -R feature as defined by Der Flounder (https://derflounder.wordpress.com/2018/03/29/new-automated-restart-option-added-to-10-13-4s-softwareupdate-command-line-tool/) in a work flow that works well and is less intensive for my users.



The biggest catch I've had so far is recording the success or failure of the reboot process because the reboot is triggered by the script thus the policy never completes and the logs are never submitted to Jamf. Below is what I have written, it will be in a policy that is scoped to a smart group of folks that have updates pending, any suggestions on functionality or workflow is appreciated.



Edit 4/25/2019: A new GitHub has been made for this project. it incorporates tons of bug fixes and feature additions discussed in the below posts. It is, as of now, an active project. Folks here continue to add great suggestions and bug finds to what has been built, so please review the code and use a pinch of salt when deploying in your environments. The git can be found here: https://github.com/taboc741/MacScripts/blob/master/A-Kinder-macOS-Update

@shawnis43 Unrelated to the unnecessary restart issue is a new one I've added to the list. The countdown timer function of the script is not working on my Mojave Macs. It simply displays the total amount of time for the counter doesn't animate. The button on the pop-up window is also shaded poorly and is hard to read in both regular and dark mode. Plenty more to troubleshoot now.


@cstout , Thanks for the heads up! I think I figured out why it was restarting when not necessary, though my scripting knowledge is very weak so I'm not 100% on it. In the if statement of the "warning user" section, I changed the "!=" to "==" and that seems to do the trick. In my testing the Mac did not restart for the Safari update. I look forward to seeing any updates you or anyone else comes up with for Mojave!!


..


Just tried the script on Mojave 10.14.2 update, and it starts well up, but then just reboot at once without any prompt ? So the update is working, but not so user friendly if just rebooting without any notice



@shawnis43 can you try and put up the script that is working for you, so it does not reboot without prompting first on updates


Script works very nicely. Just trying to understand ... what is the purpose of:



#!/bin/sh
ShutDownRequired=`echo $updates | grep shutdown | grep -v '*' | cut -d , -f 1`

Ditto to what @mlitton said. Awesome script, but the shutdown is a bit weird. Maybe have a button that gives the option to reboot or shutdown?


Here is one that I've worked on:



#!/bin/bash

log="/Library/Logs/YourCorp/SoftwareUpdate.log"
scriptName=$(basename "$0")
osVersion=$(sw_vers -productVersion)
osMinorVersion=$(echo "$osVersion" | awk -F. '{print $2}')
[[ "$osMinorVersion" -le 12 ]] && icon="/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdate.icns"
[[ "$osMinorVersion" -ge 13 ]] && icon="/System/Library/CoreServices/Install Command Line Developer Tools.app/Contents/Resources/SoftwareUpdate.icns"

/bin/mkdir -p /Library/Logs/YourCorp

function writelog () {
DATE=$(date +%Y-%m-%d %H:%M:%S)
/bin/echo "${1}"
/bin/echo "$DATE" " $1" >> "$log"
}

function finish () {
writelog "======== Finished $scriptName ========"
exit "$1"
}

function trigger_updates () {
# Run softwareupdate and clean up the output so we only see what is necessary.
/usr/sbin/softwareupdate --install $1 |
grep --line-buffered -v -E 'Software Update Tool|Copyright|Finding|Downloaded|Done.|You have installed one|Please restart immediately.|^$' |
while read -r LINE; do writelog "$LINE"; done
sleep 5
}

function initiate_restart () {
writelog "Initiating restart now..."
kill "$jamfHelperPID" > /dev/null 2>&1 && wait $! > /dev/null
/usr/local/bin/jamf reboot -background -immediately
finish 0
}

writelog " "
writelog "======== Starting $scriptName ========"
writelog "Determining available Software Updates for macOS $osVersion..."

# Check for updates and determine if a restart is required for any
updates=$(/usr/sbin/softwareupdate -l)
updatesNoRestart=$(echo "$updates" | /usr/bin/grep -v restart | /usr/bin/grep -B1 recommended | /usr/bin/grep -v recommended | /usr/bin/awk '{print $2}' | /usr/bin/awk '{printf "%s ", $0}')
updatesRestart=$(echo "$updates" | grep -i restart | grep -v '*' | cut -d , -f 1)
updateCount=$(echo "$updates" | grep -i -c recommended)

# If there are no system updates, quit
if [[ "$updateCount" -eq 0 ]]; then
writelog "No updates at this time; exiting."
finish 0
fi

# If we get to this point and beyond, there are updates, let's download them.
writelog "Downloading $updateCount update(s)..."
/usr/sbin/softwareupdate --download --recommended | grep --line-buffered Downloaded | while read -r LINE; do writelog "$LINE"; done

# Don't waste the user's time - install any updates that do not require a restart first.
if [[ -n "$updatesNoRestart" ]]; then
writelog "Installing updates that DO NOT require a restart..."
trigger_updates "$updatesNoRestart"
fi

# If the script moves past this point, a restart is required.
if [[ -n "$updatesRestart" ]]; then
writelog "A restart is required for remaining updates."
# If no user is logged in, just update and restart. Check the user now as some time has past since the script began.
loggedInUser=$(/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 + "
");')
if [[ "$loggedInUser" == "root" ]] || [[ -z "$loggedInUser" ]]; then
writelog "No user logged in."
writelog "Installing updates that DO require a restart..."
trigger_updates "--recommended"
initiate_restart
fi

# Past this point means a user is logged in.
writelog "Warning user $loggedInUser of impending restart."
result=$("/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType utility -title "Software Update Required" -heading "Required Mac OS update" -alignHeading justified -description 'A required OS update is available for your Mac. This will require a reboot AFTER the update has been installed. Please start the update now and you will be prompted again to reboot after the update has completed.' -alignDescription left -icon "$icon" -button1 'Start Update' -timeout 14400 -countdown -lockHUD)
if [[ "$result" =~ ^0|239$ ]]; then
writelog "Timer expired, user clicked begin, or user force-quit the prompt."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -lockHUD -heading 'Software Update Required' -description 'We are now updating your Mac System software. These updates should not take longer than 30 to 45 minutes depending on how many updates your Mac needs. If you see this screen for more than 45 minutes please call Service Desk. Your machine may reboot or shutdown. Please do not manually turn off this computer. This message will go away when updates are complete.' -icon "$icon" > /dev/null 2>&1 &
jamfHelperPID=$(echo $!)
writelog "Installing updates that DO require a restart..."
trigger_updates "--recommended"
initiate_restart
else
writelog "jamfHelper failed to prompt the user; exiting."
finish 1
fi
else
writelog "No updates that require a restart available; exiting."
finish 0
fi

@ryan.ball That script is awesome! Only problem I'm having is that the user isn't warned in between "starting" the update and the computer restarting. Are you experiencing the same thing?


@willsmithcc So are you saying between the jamfHelper dialog and the initiate_restart function? So if the updates take 10 minutes to install, and during that 10 minute window a user logs in, and then the Mac just restarts when the updates are done I guess is what might be happening.



You'd need to check one more time for a logged in user after the trigger_updates "--recommended" part again if you are trying to avoid that.



I never used this in production. Moved on to a version where the user is notified 3 times using yo.app before forcing the install.


@willsmithcc I did not test this in this script, but I took care of that issue in my own version and copied it over for you.



#!/bin/bash

# Posted here: https://www.jamf.com/jamf-nation/discussions/28280/a-nicer-software-update-tool

log="/Library/Logs/YourCorp/SoftwareUpdate.log"
scriptName=$(basename "$0")
osVersion=$(sw_vers -productVersion)
osMinorVersion=$(echo "$osVersion" | awk -F. '{print $2}')
[[ "$osMinorVersion" -le 12 ]] && icon="/System/Library/CoreServices/Software Update.app/Contents/Resources/SoftwareUpdate.icns"
[[ "$osMinorVersion" -ge 13 ]] && icon="/System/Library/CoreServices/Install Command Line Developer Tools.app/Contents/Resources/SoftwareUpdate.icns"

/bin/mkdir -p /Library/Logs/YourCorp

function writelog () {
DATE=$(date +%Y-%m-%d %H:%M:%S)
/bin/echo "${1}"
/bin/echo "$DATE" " $1" >> "$log"
}

function finish () {
writelog "======== Finished $scriptName ========"
exit "$1"
}

function trigger_updates () {
# Run softwareupdate and clean up the output so we only see what is necessary.
/usr/sbin/softwareupdate --install $1 |
grep --line-buffered -v -E 'Software Update Tool|Copyright|Finding|Downloaded|Done.|You have installed one|Please restart immediately.|^$' |
while read -r LINE; do writelog "$LINE"; done
sleep 5
}

function initiate_restart () {
writelog "Initiating restart now..."
kill "$jamfHelperPID" > /dev/null 2>&1 && wait $! > /dev/null
/usr/local/bin/jamf reboot -background -immediately
finish 0
}

writelog " "
writelog "======== Starting $scriptName ========"
writelog "Determining available Software Updates for macOS $osVersion..."

# Check for updates and determine if a restart is required for any
updates=$(/usr/sbin/softwareupdate -l)
updatesNoRestart=$(echo "$updates" | /usr/bin/grep -v restart | /usr/bin/grep -B1 recommended | /usr/bin/grep -v recommended | /usr/bin/awk '{print $2}' | /usr/bin/awk '{printf "%s ", $0}')
updatesRestart=$(echo "$updates" | grep -i restart | grep -v '*' | cut -d , -f 1)
updateCount=$(echo "$updates" | grep -i -c recommended)

# If there are no system updates, quit
if [[ "$updateCount" -eq 0 ]]; then
writelog "No updates at this time; exiting."
finish 0
fi

# If we get to this point and beyond, there are updates, let's download them.
writelog "Downloading $updateCount update(s)..."
/usr/sbin/softwareupdate --download --recommended | grep --line-buffered Downloaded | while read -r LINE; do writelog "$LINE"; done

# Don't waste the user's time - install any updates that do not require a restart first.
if [[ -n "$updatesNoRestart" ]]; then
writelog "Installing updates that DO NOT require a restart..."
trigger_updates "$updatesNoRestart"
fi

# If the script moves past this point, a restart is required.
if [[ -n "$updatesRestart" ]]; then
writelog "A restart is required for remaining updates."
# If no user is logged in, just update and restart. Check the user now as some time has past since the script began.
loggedInUser=$(/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 + "
");')
if [[ "$loggedInUser" == "root" ]] || [[ -z "$loggedInUser" ]]; then
writelog "No user logged in."
writelog "Installing updates that DO require a restart..."
trigger_updates "--recommended"
loggedInUser=$(/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 + "
");')
if [[ ! "$loggedInUser" == "root" ]] && [[ -n "$loggedInUser" ]]; then
writelog "$loggedInUser has logged in since we started to install updates, alerting them of pending restart."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -lockHUD -title 'Software Update In Progress' -alignHeading center -alignDescription natural -description 'Unfortunately you logged in while software updates were being installed. This Mac will restart in 60 seconds.

If you have any questions please call the Help Desk.' -icon "$icon" -iconSize 100 -timeout "60"
initiate_restart
else
# Still nobody is logged in, restart
initiate_restart
fi
fi

# Past this point means a user is logged in.
writelog "Warning user $loggedInUser of impending restart."
result=$("/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType utility -title "Software Update Required" -heading "Required Mac OS update" -alignHeading justified -description 'A required OS update is available for your Mac. This will require a reboot AFTER the update has been installed. Please start the update now and you will be prompted again to reboot after the update has completed.' -alignDescription left -icon "$icon" -button1 'Start Update' -timeout 14400 -countdown -lockHUD)
if [[ "$result" =~ ^0|239$ ]]; then
writelog "Timer expired, user clicked begin, or user force-quit the prompt."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -lockHUD -heading 'Software Update Required' -description 'We are now updating your Mac System software. These updates should not take longer than 30 to 45 minutes depending on how many updates your Mac needs. If you see this screen for more than 45 minutes please call Service Desk. Your machine may reboot or shutdown. Please do not manually turn off this computer. This message will go away when updates are complete.' -icon "$icon" > /dev/null 2>&1 &
jamfHelperPID=$(echo $!)
writelog "Installing updates that DO require a restart..."
trigger_updates "--recommended"
initiate_restart
else
writelog "jamfHelper failed to prompt the user; exiting."
finish 1
fi
else
writelog "No updates that require a restart available; exiting."
finish 0
fi

@mlitton and @rkovelman The point of testing for the shutdown state was that last year Apple introduced a new update reboot state that Jamf has (had) not incorporated into their built-in reboot options.



My goal is to incorporate the new softwareupdate -i -a -R feature as defined by Der Flounder (https://derflounder.wordpress.com/2018/03/29/new-automated-restart-option-added-to-10-13-4s-softwareupdate-command-line-tool/


After talking with Apple support the expected flag for updates requiring the strange reboot model is "shutdown", thus I tried to capture and contain the future state. Note: I have not seen it be used yet, but this is Apple we're talking about. They do what they want when they want.



@cstout and @shawnis43 , I think figured out why we would get the random reboots, it was a race condition in the if statement. Turns out the test of a null variable does not compute and can cause sh to process the code after the null evaluation strangely. I discovered this while trying to get a deferral process working. (The users eventually got the better of my management who was happy with the simpler solution). I am working on sanitizing the scripts and moving to a github since paste-bin doesn't really do multi-file solutions well. I'll post back when I get that done.



To add more color, essentially I am taking



#!/bin/sh
updates=`softwareupdate -l`
updatesNoRestart=`echo $updates | grep recommended | grep -v restart`
restartRequired=`echo $updates | grep restart | grep -v '*' | cut -d , -f 1`
shutDownRequired=`echo $updates | grep shutdown | grep -v '*' | cut -d , -f 1`


and turned it into



#!/bin/sh
updates=`softwareupdate -l`
updatesNoRestart=`echo $updates | grep recommended | grep -v restart`
[[ -z $updatesNoRestart ]] && updatesNoRestart="none"
restartRequired=`echo $updates | grep restart | grep -v '*' | cut -d , -f 1`
[[ -z $restartRequired ]] && restartRequired="none"
shutDownRequired=`echo $updates | grep shutdown | grep -v '*' | cut -d , -f 1`
[[ -z $shutDownRequired ]] && shutDownRequired="none"


Now the test statements always have a real variable to test against and the race condition of a "real test that works" versus "a test that will fail and cause weird problems" has been prevented.


......And the Git up is up. Please visit the taboc741 github to see my hastily propped up GIT. The new set of files should allow for deferrals and, as mentioned previously, this update contains the "unary operator" error I was seeing earlier.



Please feel to comment there on my shoddy instructions and/or provide suggestions for making them more clear.


Question, I would love to utilize this but with our environment we have to hold back on Safari because of internal applications. Is there a way to just update the OS security update?


@TheDecline Not as the script exists today. Someone better at parsing the string passed back from softwareupdate into $updates could in theory turn that into an array and build a foreach loop to apply the updates 1 at a time excluding ones that containing the words Safari. The catch here is I think Safari updates are often bundled with Apple's security updates so I'm not sure how well it will work in practice.




Hey guys,
First of all this is awesome. I'm so pleased people are looking at other ways to update machines. I'm running a fleet of 150+ macs and Jamf don't seem to have an awesome for updating them all (patch management certainly doesn't work!)



I've just jumped onto your github @Taboc741 - pulled the files down, updated the paths etc. Everything seems to be working, however the script doesn't seem to know that I don't have any updates pending. It goes ahead and tries to "update" the machine... and then restarts it!
I can't see any reason why the script doesn't stop when it sees there are no updates to do. Any ideas?



Packaged up the file with composer and installed it before running the script. - everything works as expected from what I can see.
FWIW I ran the script from self service because I believe most of my users will do that.



#!/bin/sh
## SoftwareUpdate4.sh
## Created by Chris on 5/31/18. Last edited by Chris 2/8/2019
##### Special thanks to mm2270, cstout, nvandam from JamfNation for helping me with some testing and code suggestions to problems I couldn't solve on my own.#####

######### Create settings for logging and create log file #########
## Path to Log file. Map your Own Log Path. Do not use /tmp as it is emptied on boot.
LogPath=/Library/Logs/SPX
##Verify LogPath exists
if [ ! -d "$LogPath" ]; then
mkdir $LogPath
fi
## Set log file and console to recieve output of commands
Log_File="$LogPath/SoftwareUpdateScript.log"
function sendToLog ()
{

echo "$(date +"%Y-%b-%d %T") : $1" | tee -a "$Log_File"

}
## begin log file
sendToLog "Script Started"
######### Set variables for the script ############
icon=/Library/Application Support/SPX/AppleSoftwareUpdate.png
## Determine OS version
OSVersion=`sw_vers -productVersion`
## Get the currently logged in user, if any.
LoggedInUser=`who | grep console | awk '{print $1}'`
## Check for updates that require a restart and ones that do not.
updates=`softwareupdate -l`
updatesNoRestart=`echo $updates | grep recommended | grep -v restart`
[[ -z $updatesNoRestart ]] && updatesNoRestart="none"
restartRequired=`echo $updates | grep restart | grep -v '*' | cut -d , -f 1`
[[ -z $restartRequired ]] && restartRequired="none"
shutDownRequired=`echo $updates | grep shutdown | grep -v '*' | cut -d , -f 1`
[[ -z $shutDownRequired ]] && shutDownRequired="none"

################ End Variable Set ################
sendToLog "OS version is $OSVersion"
sendToLog "Logged in user is $LoggedInUser"

## If there are no system updates, quit
if [[ $updatesNoRestart = "none" && $restartRequired = "none" && $shutdownRequired = "none" ]]; then
sendToLog "No updates at this time, updating Jamf inventory"
jamf policy -trigger recon
sendToLog "Inventory update complete, script exit."
exit 0
fi
######### If we get to this point and beyond, there are updates. #########
sendToLog "Updates found."
## Download all updates before trying to install them to make a smoother user experiance.
title='Software Update Required'
heading='Software updates'
description='Downloading the required Software updates. This prompt will change when it is time to install them. It is safe to continue using the mac while this happens.'
button1="Ok"
##prompt the user
"/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType hud -title "$title" -heading "$heading" -alignHeading justified -description "$description" -alignDescription left -icon "$icon" -button1 "$button1" -lockHUD > /dev/null 2>&1 &
softwareupdate --download --all --force --no-scan
killall jamfHelper
##Map some variables to pretty up the command to prompt the user
title='Software Update Required'
heading='Required Software update'
description='The Apple Updates are ready to install. Please press start.'
button1="Start Updates"
##prompt the user
prompt=`"/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType hud -title "$title" -heading "$heading" -alignHeading justified -description "$description" -alignDescription left -icon "$icon" -button1 "$button1" -timeout 14400 -countdown -lockHUD`
sendToLog "prompt equaled $prompt. 0=start 1=failed to prompt 2=canceled 239=exited"
sendToLog `softwareupdate --install -all --force` && sendToLog "Updates Applied"
if [[ $restartRequired = "none" && $shutdownRequired = "none" ]]; then
sendToLog "no reboot required, exiting"
sendToLog "Script exit"
exit 0
fi
######### If we get to this point a reboot is required #########

if [[ $restartRequired != "none" || $shutDownRequired != "none" ]]; then
##Map some variables to pretty up the command to prompt the user
title='Software Update Required'
heading='Required Software update'
description='A reboot is required to apply the OS updates to your Mac. Please close all open applications before restarting your mac.'
button1="Reboot"
prompt=`"/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType hud -title "$title" -heading "$heading" -alignHeading justified -description "$description" -alignDescription left -icon "$icon" -button1 "$button1" -timeout 21600 -countdown -lockHUD`
sendToLog "prompt equaled $prompt."
sendToLog "placing reboot message"
##Map some variables to pretty up the command to prompt the user
title='Software Update Required'
heading='Required Mac OS update'
description='We are now updating your Mac System software. These updates should not take longer than 20 to 30 minutes depending on how many updates your Mac needs. If you see this screen for more than 30 minutes please call Sparx IT. Your machine may reboot or shutdown if required. Please do not manually turn off this computer. This message will go away when updates are complete.'
button1="Reboot"
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType hud -lockHUD -heading "$heading" -description "$description" -icon "$icon" > /dev/null 2>&1 &
fi
if [[ $shutDownRequired != "none" ]]; then
sendToLog "Starting softwareupdate --install --all --restart --force --no-scan"
sendToLog `softwareupdate --install --all --restart --force --no-scan` & exit 0
else
sendToLog "starting reboot"
## using the Jamf restart process because it increases the odds of Jamf receiveing the logs back from the completed policy.
jamf reboot -minutes 1 -background -startTimerImmediately & sendToLog "Script exit"
exit 0
fi


Forgot to add:


Thank you @Taboc741 !



Out of curiosity, is there a reason the LaunchAgent is running at a particular time rather than just letting Jamf call it when necessary (ie. software updates >0 type thing)?


@samuelbrown I should probably add 'sendToLog "$updates" ' arourd line 31 or so. That would output the string to the log that the following 6 lines is trying to parse to determine if there is an update pending to install. If you add that and then post the resulting log I could figure out how my logic is broken and resulting in the script trying to install updates that aren't pending.



@jwojda The defer process was built to run independent of Jamf. That way I am not waiting on machines to submit inventory, which we run weekly to help with DB maintenance, for a machine to fall into a smart group to then be pestered about installing their updates. You could certainly swap up the process, having Jamf trigger the defer script rather than the launch agent.


@samuelbrown @Taboc741 The test machine I ran it on had the opposite problem, we had an update available, the only option I had was to install it. After the script claimed to download the update, install, and then reboot only to find the update never installed.


@jwojda I have had that happen once in my testing. I tried running the script a second time from the terminal window so I can see all the stdout context...and then the update installed, and I have not been able to reproduce the issue. I added the --force to the softwwareupdates command just incase though. Someone on slack suggested using the softwareupdates restart process every time which might work for you. In my testing I had issues with some macs trying to re-install the updates a second time and taking a really long time about it in the reboot portion of the script.


I've been testing with the code posted on github today. In this instance I have a VM running 10.13.4 that has updates available:



softwareupdate -l



Software Update Tool



Finding available software
Software Update found the following new or updated software:
macOS High Sierra 10.13.6 Update-
macOS High Sierra 10.13.6 Update ( ), 2407932K [recommended] [restart]
iTunesX-12.8.2
iTunes (12.8.2), 273564K [recommended]



You can see I have two updates available, one of which requires a reboot.



After the series of helper prompts the system reboots and you would expect it to finish install of the updates on reboot however it does not.



The SoftwareUpdateScript.log file contains:



2019-Feb-18 14:15:08 : Script Started
2019-Feb-18 14:15:32 : OS version is 10.13.4
2019-Feb-18 14:15:32 : Logged in user is lmeinecke
2019-Feb-18 14:15:32 : Updates found.
2019-Feb-18 14:16:13 : prompt equaled 0. 0=start 1=failed to prompt 2=canceled 239=exited
2019-Feb-18 14:16:54 : Software
2019-Feb-18 14:16:54 : Updates Applied
2019-Feb-18 14:17:08 : prompt equaled 0.
2019-Feb-18 14:17:08 : placing reboot message
2019-Feb-18 14:17:08 : starting reboot
2019-Feb-18 14:17:08 : Script exit



JamF log:



Script result: 2019-Feb-18 14:49:17 : Script Started
2019-Feb-18 14:49:57 : OS version is 10.13.4
2019-Feb-18 14:49:57 : Logged in user is lmeinecke
2019-Feb-18 14:49:57 : Updates found.
Software Update Tool



Finding available software



Downloaded iTunes
Downloaded macOS High Sierra 10.13.6 Update
Done.
/Library/Application Support/JAMF/tmp/SoftwareUpdate4.sh: line 67: 1119 Terminated: 15 "/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" -windowType hud -title "$title" -heading "$heading" -alignHeading justified -description "$description" -alignDescription left -icon "$icon" -button1 "$button1" -lockHUD > /dev/null 2>&1
2019-Feb-18 14:51:02 : prompt equaled 0. 0=start 1=failed to prompt 2=canceled 239=exited
2019-Feb-18 14:51:43 : Software
2019-Feb-18 14:51:43 : Updates Applied
2019-Feb-18 14:52:34 : prompt equaled 0.
2019-Feb-18 14:52:34 : placing reboot message
2019-Feb-18 14:52:34 : starting reboot
2019-Feb-18 14:52:34 : Script exit



Another observation was when I was playing around with the defer prompts. I've pressed that twice on this host so it is down to 3. It seems to persist but perhaps that is in design seeing the updates aren't really installing. At first I expected that to go back to 5 on the next execution. I see mentions of a Deferrals plist file in the AppleUpdateDefer1.sh script but didn't see that on the file system. Where would this be located?


I've been chatting with @Taboc741 on Slack. It looks like the deferral count is possibly stored in a SIP area but you can see the count with read or modify using "sudo defaults write com.YourOrg.SoftwareUpdate.Deferral remainingDeferrals" during testing.



We fixed a line today and the pull request has been approved.


It looks like where I'm at now with testing is the deferral script is executing on the host by the launchd. When the user clicks install updates for some reason it is not properly triggering the JamF policy that runs the softwareupdate script. I know JamF is good because if I manually run the "jamf policy -trigger AppleUpdateScript" it works. Something in the deferral script is still off. Trying to debug and get in contact with the OP.


So, The Git is just updated with new instructions to resolve the issues with LaunchAgents not having sufficient rights from standard users to trigger Jamf policies. This is what I get for testing with friends and family that all have admin rights in my own org.


10.14.4 requires --restart in order to process an actual shut down as noted below (from softwareupdate's output).



To install these updates, your computer must shut down. Your computer will automatically start up to finish installation.
Installation will not complete successfully if you choose to restart your computer instead of shutting down.
Please call halt(8) or select Shut Down from the Apple menu. To automate the shutdown process with softwareupdate(8), use --restart.


With that said, the current variable (ShutDownRequired) for grep'ing "shutdown" doesn't work.



I'm trying to figure out what to change the variable to so that end logic can perform this action:



if [ "$ShutDownRequired" != "" ]; then
echo `date`" : Shut Down Required. Executing halt."
/sbin/halt
else


The difficult part for me is finding the right way to use the text from the softwareupdate output above and use it after the fact. The output above only appears after running softwareupdate --install --recommended and I have no idea how to use that command's output for use in another variable.



Paging @mm2270...would you be willing to help me out on this puzzle?


Reply