Posted on 07-07-2015 04:11 PM
Hi All
I'm working on the best way to update XProtect and Gatekeeper whilst keeping auto updates unticked as we don't want those joyous notifications.
The plan is to temporarilly enable ConfigDataInstall:
defaults write /Library/Preferences/com.apple.SoftwareUpdate ConfigDataInstall -bool True
And softwareupdate schedule:
softwareupdate --schedule on
Then run
softwareupdate --background-critical
then turn it all off again after the installation has completed
I'd like the option to download these updates from Apple's catalog rather than our own SUS as it's not accessible externally.
Does anyone know of a way i can add Apple's catalogurl to the softwareupdate --background-critical command or another way i can get it to download from Apple and temporarilly ignore our SUS (which is set via a Config profile)
Cheers,
Andy
Posted on 07-07-2015 08:04 PM
The solution that comes to mind is shown below. Please bear in mind that the solution is for a SUS hosted via JAMF NetBoot/SUS or reposado, and may not be applicable on a SUS hosted via the OS X Server app:
softwareupdate --background-critical
.Posted on 07-08-2015 08:19 AM
Thanks for the info @dwandro92
That won't work for our current set up as Our SUS is running on OS X server, i do plan to set up Reposado but it won't be in the near future.
Posted on 07-08-2015 04:01 PM
Is your SUS configured to auto download updates with manual enablement?
Posted on 07-09-2015 02:28 PM
@dwandro92 We're using Manual download and manual enable
Posted on 07-09-2015 04:22 PM
I created a script for use on an Apple SUS:
#!/bin/bash
# Use newline for field seperator
IFS=$'
'
# Function for writing to the log file
writeLog() {
# Get timestamp for logging purposes
timeStamp=`date "+%m/%d/%Y %H:%M:%S"`
# Set output message text to timestamp and message. Omit timestamp if message is blank
[ -n "$1" ] && outMsg="$timeStamp - $1" || outMsg=""
# Output message to log and shell
echo -e "$outMsg" | tee -a "$logFile"
}
# Set path to log file
logFile="/var/log/SWU_Sync.log"
# Set alias for software update sync
swuSync="/Applications/Server.app/Contents/ServerRoot/usr/sbin/swupd_syncd"
# Set path to Software Update home directory
swuDir="/Library/Server/Software Update/Data/html"
# Output information
writeLog "Running software update sync..."
# Run software update sync
"$swuSync" -sync
# Get a list of all catalogs
appleCatalogs=(`ls "${swuDir}/content/catalogs/others" | grep -E '.apple$'`)
# If Apple catalogs were found
if [ ${#appleCatalogs[@]} -ne 0 ]; then
# For each catalog that was found
for appleCatalog in ${appleCatalogs[@]}; do
# Output infromation
writeLog "Searching for Gatekeeper and XProtect updates in ${appleCatalog}..."
# Get a list of all XProtect and Gatekeeper packages from Apple's catalogs
applePkgs=(`grep -E -i 'XProtect|Gatekeeper' "$swuDir/content/catalogs/others/$appleCatalog" | grep '.pkg' | sed -e 's/.*/content/content/g' -e 's/</.*//g'`)
# If packages were found
if [ ${#applePkgs[@]} -ne 0 ]; then
# Set local catalog filename
localCatalog=`echo "$appleCatalog" | awk -F '.apple' '{ print $1 }'`
# For each package that was found
for applePkg in ${applePkgs[@]}; do
# Get ID for update
updateID=`echo "$applePkg" | awk -F '/' '{ print $5 }'`
# Set package to update package
pkgPath="$swuDir/$applePkg"
# If the package doesn't exist (hasn't been downloaded)
if [ ! -e "$pkgPath" ]; then
# Output information
writeLog "Downloading update $updateID..."
# Download the update
"$swuSync" -mirror $updateID
fi
# Check if update is enabled
enabledCheck=`grep "$updateID" "$swuDir/content/catalogs/others/$localCatalog"`
# If update is not enabled
if [ -z "$enabledCheck" ]; then
# Output information
writeLog "Enabling update $updateID..."
# Enable the update
"$swuSync" -enable $updateID 2>&1
fi
done
fi
done
fi
# Exit script
exit 0
Please keep in mind that I don't actually use Apple SUS in my environment, and have therefore only verified this script's functionality on a test server that doesn't serve any clients.
Posted on 07-13-2015 10:37 AM
Hi @dwandro92 that is awesome thank you!
Running through the script i think maybe i didn't describe what we wanted to acheive properly, my script Fu is
not that strong so i may have read it wrong! but it looks like it's all based on the SUS, the change we want to make is on the Mac end of things.
We are able to download the XProtect and Gatekeeper updates to our SUS and manually enable them, and we can install these updates on a Mac by temporarily enabling Automatically check for updates, ConfigDataInstall and running the command "softwareupdate --background-critical"
(without the auto updates on and ConfigDataInstall enabled Xprotect + Gatekeeper updates do not get installed info here
This works great for users inside the network with access to our SUS
We have Automatically check for updates turned off as we don't want users to get Software update notifications.
What i'm looking for is a simple way to temporarilly overide the setting that points each Mac to our SUS and have them get these updates from Apple. We set our SUS CatalogURL using a Configuration Profile.
If there is a command that i could add to softwareupdate --background-critical that would be perfect, i'll keep looking :)!
Thanks again for your help
Posted on 07-13-2015 10:47 AM
If you have a profile that points your client machines to your internal SUS then you will most likely need to have that profile removed as that's going to dictate the SUS the client points to.
Is there any particular reason you are against the notifications? Seems like a lot of trouble just to avoid notifications.
Posted on 07-13-2015 11:44 AM
Hi @bpavlov
Thanks for the info,
We'd like to keep notifications off as our users do not have rights to install any Apple updates and the notifications will cause confusion and more than likely additional service desk tickets.
Posted on 07-13-2015 11:50 AM
Then perhaps you would be more comfortable with the user using Self Service to have the updates installed. It doesn't require admin rights as any Self Service item runs as root.
A policy scoped to all computers that would simply use the Software Update payload (or you could additionally have it run a script calling softwareupdate) may do the trick. I'm actually starting to test this out myself so I can provide more technical details once I'm done.
Posted on 07-13-2015 12:20 PM
The script above would be setup as a scheduled task that runs on the SUS to download and enable Gatekeeper and XProtect updates, so that you don't have to manually download them and enable them yourself. In other words, you would still have to download and enable other updates on your SUS as usual, but these types of updates would be handled in an automated fashion. By doing this, you wouldn't have to point the clients to the Apple catalogs at all, which would simplify the client-side automation quite a bit.
On the client-side, you could then enable the settings you stated above and install updates programatically as follows (not tested):
#!/bin/bash
# Turn on automatic updates
softwareupdate --schedule on
# Enable configuration updates
defaults write /Library/Preferences/com.apple.SoftwareUpdate ConfigDataInstall -bool TRUE
# Disable critical updates
defaults write /Library/Preferences/com.apple.SoftwareUpdate CriticalUpdateInstall -bool FALSE
# Install updates
softwareupdate --background-critical
# Disable automatic updates
softwareupdate --schedule off
If your reason for using the Apple catalogs is that the systems are off the network and do not have access to the SUS, you would need to do the following:
If using a config profile to manage your SUS catalog URL, remove the profile. You can use
profiles -R -p <Config Profile UUID>
to do this in a script.
Set the Apple Catalog URL using the code proposed at the bottom of this comment.
Install updates using the code proposed at the top of this comment.
Re-apply your SUS settings by re-installing your config profile via profiles -I -F - <Config Profile Contents>
or by using defaults write "/Library/Preferences/com.apple.SoftwareUpdate.plist" CatalogURL <SUS URL>
Code for setting Apple Catalog URL:
#!/bin/bash
# Set path to config file
configFile="/Library/Preferences/com.apple.SoftwareUpdate.plist"
# Get OS version
osVersion=`defaults read /System/Library/CoreServices/SystemVersion ProductVersion | awk -F "." '{ print $1"."$2 }'`
# Get OS minor version
osMinorVersion=`defaults read /System/Library/CoreServices/SystemVersion ProductVersion | awk -F "." '{ print $2 }'`
# Examine OS version
case $osMinorVersion in
# Set catalog name for OS X Lion
7) catalogName="index-lion-snowleopard-leopard";;
# Set catalog name for OS X Mt. Lion
8) catalogName="index-mountainlion-lion-snowleopard-leopard";;
# Set catalog name for OS X Mavericks
9) catalogName="index-10.9-mountainlion-lion-snowleopard-leopard";;
# Set catalog name for OS X Yosemite
10) catalogName="index-10.10-10.9-mountainlion-lion-snowleopard-leopard";;
# Set catalog name for OS X El Capitain
11) catalogName="index-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard";;
# Do not set a catalog name for any other version of OS X
*) echo "Unable to determine catalog path for ${osVersion}.";;
esac
# If catalog name is set
if [ -n "$catalogName" ]; then
# Set full catalog URL
catalogURL="http://swscan.apple.com/content/catalogs/others/${catalogName}.merged-1.sucatalog"
# Write full path to catalog URL
defaults write "$configFile" CatalogURL "$catalogURL"
# Output catalog URL
echo "Software Update Catalog was set to $catalogURL..."
fi
Please let me know if you have any questions.
Posted on 07-13-2015 03:38 PM
Thanks for your suggestion @bpavlov , it would be beneficial to add updates to self service to supplement our updates schedule, though at the moment it would require more time than is available to configure, test and document, that's in the "to do when we're bored" list!
and thank you @dwandro92 , i think your solution could do what we need, thanks for sharing the script also, very handy, I'm looking forward to testing it out tomorrow!