Posted on 04-27-2018 07:57 AM
Hello everyone, I have this script im testing that @mm2270 posted. The script checks for apple updates and if the machine requires a reboot. I would like to know if there is a way to get a reboot script to only execute after the first script has said it requires a reboot? My personal machine is up to date at the moment. When I run the script, it says that no reboot is requires at this time. I have another script that prompts the user to reboot the machine and has a deferral option. I would like the second script to only run when the first script has said the computer needs a reboot.
Posted on 04-27-2018 08:06 AM
Maybe @mm2270 can answer your question, but how to help and know which script you're talking about since he posted a lot :-)
Posted on 04-27-2018 09:23 AM
Yes, please post a link to the script you're referring to. Unfortunately, some of the older scripts I've posted may not be working anymore and I don't always have time to go back to look over them for a refresh. But if you post the script or preferably a link to it, I'll be able to tell you if it can be modified to do what you're asking.
Posted on 04-27-2018 10:13 AM
Here is the script that I have taken from your post @mm2270
EAScript="Yes"
LogScript="Yes"
Reboot_Needed_Log="/Library/Application Support/Reboot_Updates_Needed"
function get_Reboot_Updates ()
{
i=0
while read folder; do
if [[ -e "/Library/Updates/${folder}" ]]; then
while read distFile; do
if [[ $(grep -i restart "$distFile") ]]; then
RestartPkgs+=("${updateIdentifiers[$i]}-${updateVersions[$i]}")
fi
done < <(find "/Library/Updates/${folder}" -name *.dist)
let i=$((i+1))
else
echo "Could not find path /Library/Updates/${folder}"
fi
done < <(printf '%s
' "${productKeys[@]}")
if [[ "${RestartPkgs[@]}" != "" ]]; then echo "Some updates require a reboot"
if [ "$EAScript" ]; then ## prints the reboots needed results in Casper Suite Extension Attribute format echo "<result>$(printf '%s ' "${RestartPkgs[@]}")</result>" fi
if [ "$LogScript" ]; then
echo "Adding details to local file..."
## Sends the reboots needed result into local log file
printf '%s
' "${RestartPkgs[@]}" > "$Reboot_Needed_Log"
exit 0
fi
else
echo "No reboot updates are available at this time..."
if [ "$EAScript" ]; then
echo "<result>None</result>"
fi
if [ "$LogScript" ]; then
echo "Nothing to write to log file"
exit 0
fi
fi
}
function get_Update_Stats ()
{
echo "Getting update stats..."
RecommendedUpdatesData=$(/usr/bin/defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist RecommendedUpdates)
while read identifier; do
updateIdentifiers+=("$identifier")
done < <(awk -F'= ' '/Identifier/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read version; do
updateVersions+=("$version")
done < <(awk -F'= ' '/Display Version/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read Key; do
productKeys+=("$Key")
done < <(awk -F'= ' '/Product Key/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read Name; do
displayNames+=("$Name")
done < <(awk -F'= ' '/Display Name/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
echo "Looking for reboot required updates..."
get_Reboot_Updates
}
check_Downloads_Vs_AvailUpdates ()
{
while read item; do
if [[ $(echo "$downloadedUpdates" | grep "$item") == "" ]]; then
getDownloads="Yes"
fi
done < <(printf '%s
' "$RecommendedUpdateKeys")
if [ "$getDownloads" ]; then
echo "Some available updates are not already downloaded. Downloading all available updates..."
softwareupdate -d -a
get_Update_Stats
else
## Or, if all downloads are accounted for, move to grabbing the values from the plist
echo "All available updates have been downloaded. Skipping to checking the update stats..."
get_Update_Stats
fi
}
if [ -e "/Library/Application Support/Reboot_Updates_Needed" ]; then
rm "/Library/Application Support/Reboot_Updates_Needed"
fi
RecommendedUpdateKeys=$(/usr/bin/defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist RecommendedUpdates | awk -F'= ' '/Product Key/{print $NF}' | sed 's/"//g;s/;//g')
downloadedUpdates=$(find "/Library/Updates" -maxdepth 1 -type d | sed '1d')
echo "Running check for available updates..."
check_Downloads_Vs_AvailUpdates
Posted on 04-27-2018 04:19 PM
Just for the purposes of making sure the script is clear on this thread, I'm reposting the full script below. When posting a script here, highlight it and click the script tag in the small toolbar above the post field. It looks something like >_
so it's readable as a script.
So, this script I wrote doesn't install anything at all. I'm guessing you know that, but I wanted to be sure. It simply checks the available updates and determines if any of them would require a reboot and then prints back an answer on what it found. I'm not sure if your plan was to then install all available updates after running this or not, and then invoking your reboot deferral script if needed, but if so, there is likely an easier way to do this.
Still, if that is your plan, you'll want to add a line or section in the get_Reboot_Updates
function area. Directly underneath these lines
if [[ "${RestartPkgs[@]}" != "" ]]; then
echo "Some updates require a reboot"
you can add a jamf policy call that will run your other script, which you can attach to a policy. That section is for when it found updates, so that's the most logical place to put something that would run another script call.
Another thing you could consider is to merge the scripts together. Take the main program of your reboot deferral script and place it into it's own function within my script. Then in the get_Reboot_Updates
section I call out above, add a line that calls that function. Let's say you name the function show_reboot_deferral
, you would add that to the section, like so
if [[ "${RestartPkgs[@]}" != "" ]]; then
echo "Some updates require a reboot"
## Call the reboot deferral function
show_reboot_deferral
But you of course need to make sure there is a full function within the script that is referenced by that, or it won't work.
Good luck.
#!/bin/bash
## Get available Software Updates and determine which need reboots when installed
##################### Script behavior options (Choose one or both options) #####################
## Set the below variable to Yes to make the script operate as an Extension Attribute
EAScript="Yes"
## Set the below variable to Yes to have the script export the results out to a local log file
LogScript="Yes"
################################################################################################
## Local file where reboot required update names get stored (if option above is enabled)
Reboot_Needed_Log="/Library/Application Support/Reboot_Updates_Needed"
## Gets the names of downloaded updates that require a reboot by scanning for the reboot flag in the dist file
function get_Reboot_Updates ()
{
i=0
while read folder; do
if [[ -e "/Library/Updates/${folder}" ]]; then
while read distFile; do
if [[ $(grep -i restart "$distFile") ]]; then
RestartPkgs+=("${updateIdentifiers[$i]}-${updateVersions[$i]}")
fi
done < <(find "/Library/Updates/${folder}" -name *.dist)
let i=$((i+1))
else
echo "Could not find path /Library/Updates/${folder}"
fi
done < <(printf '%s
' "${productKeys[@]}")
if [[ "${RestartPkgs[@]}" != "" ]]; then
echo "Some updates require a reboot"
if [ "$EAScript" ]; then
## prints the reboots needed results in Casper Suite Extension Attribute format
echo "<result>$(printf '%s
' "${RestartPkgs[@]}")</result>"
fi
if [ "$LogScript" ]; then
echo "Adding details to local file..."
## Sends the reboots needed result into local log file
printf '%s
' "${RestartPkgs[@]}" > "$Reboot_Needed_Log"
exit 0
fi
else
echo "No reboot updates are available at this time..."
if [ "$EAScript" ]; then
echo "<result>None</result>"
fi
if [ "$LogScript" ]; then
echo "Nothing to write to log file"
exit 0
fi
fi
}
## Creates several arrays with values extracted from the SoftwareUpdate plist (to be used later)
function get_Update_Stats ()
{
echo "Getting update stats..."
RecommendedUpdatesData=$(/usr/bin/defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist RecommendedUpdates)
while read identifier; do
updateIdentifiers+=("$identifier")
done < <(awk -F'= ' '/Identifier/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read version; do
updateVersions+=("$version")
done < <(awk -F'= ' '/Display Version/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read Key; do
productKeys+=("$Key")
done < <(awk -F'= ' '/Product Key/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
while read Name; do
displayNames+=("$Name")
done < <(awk -F'= ' '/Display Name/{print $NF}' <<< "$RecommendedUpdatesData" | sed 's/"//g;s/;//g')
echo "Looking for reboot required updates..."
get_Reboot_Updates
}
## Checks the current downloaded updates versus what Software Update's last check saw as being available
check_Downloads_Vs_AvailUpdates ()
{
## While reading over the recommended update IDs, check to see if a matching directory exists in /Library/Updates/
## If any are not found, set a flag to get new downloads
while read item; do
if [[ $(echo "$downloadedUpdates" | grep "$item") == "" ]]; then
getDownloads="Yes"
fi
done < <(printf '%s
' "$RecommendedUpdateKeys")
## If the get downloads flag was set, first download available updates before continuing
if [ "$getDownloads" ]; then
echo "Some available updates are not already downloaded. Downloading all available updates..."
softwareupdate -d -a
get_Update_Stats
else
## Or, if all downloads are accounted for, move to grabbing the values from the plist
echo "All available updates have been downloaded. Skipping to checking the update stats..."
get_Update_Stats
fi
}
## Remove any previous reboot needed log file
if [ -e "/Library/Application Support/Reboot_Updates_Needed" ]; then
rm "/Library/Application Support/Reboot_Updates_Needed"
fi
## Get the last recommended update IDs from the SoftwareUpdate plist
RecommendedUpdateKeys=$(/usr/bin/defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist RecommendedUpdates | awk -F'= ' '/Product Key/{print $NF}' | sed 's/"//g;s/;//g')
## Get a list of directories in /Library/Updates/ to scan through
downloadedUpdates=$(find "/Library/Updates" -maxdepth 1 -type d | sed '1d')
echo "Running check for available updates..."
check_Downloads_Vs_AvailUpdates