So, with 9.93 it dawned on me we can pull details about patches directly from the JSS with the API.
This script will check what versions of Office apps using Spotlight to check the metadata, then checks the JSS for the latest patch from the Patch Management section, then it will compare the versions. If you're below the latest version it will attempt to find a policy with the naming convention "Microsoft [APP] 2016 Updater" (you have to build that policy and attach the update installer, you will have to update this policy to get it to run the updated patch) and once it knows that policy ID, it will call the jamf binary to run the update.
This could also be modified to run for any other application, create user pop-ups with something like cocoa dialogue or something else.
My original idea was to put this one script in Self Service so users could install these large updates on their own, when they have time. Notice, it does not check if the applications are running - in our tests, you can install the update while the application is running...ymmv.
Hope this is handy!
#!/bin/bash
# Check Office versions installed with "current" version on JSS Patches
#
# Requirements:
# • JSS 9.93 or later & patch reporting enabled for Office apps
# • Policy named "Microsoft 'Application' 2016 Updater" for each app to update
# • Applications must be in Spotlight index for local version lookup
# JSS Variables
APIUSER='apiusername'
APIPASS='apipassword'
JSSURL='jss.your.domain.com:8443/JSSResource'
patchLINT='string(//software_title/versions/software_version)'
policyLINT='//policy/general/id/text()'
declare -a office_apps=(
'/Applications/Microsoft Excel.app'
'/Applications/Microsoft Word.app'
'/Applications/Microsoft PowerPoint.app'
'/Applications/Microsoft Outlook.app'
'/Applications/Microsoft OneNote.app'
)
declare -a patch_uri=(
'Microsoft%20Excel%202016'
'Microsoft%20Word%202016'
'Microsoft%20PowerPoint%202016'
'Microsoft%20Outlook%202016'
'Microsoft%202016OneNote%202016')
getAppVersion() {
version=$(mdls -name kMDItemVersion "${office_apps[i]}" | cut -d " -f2)
}
getJSSPatch() {
current=$(curl -s -u $APIUSER:$APIPASS
https://$JSSURL/patches/name/${patch_uri[i]} |
xmllint --xpath "${patchLINT}" -)
}
getPolicyID() {
id=$(curl -s -u $APIUSER:$APIPASS
https://$JSSURL/policies/name/${patch_uri[i]}%20Updater |
xmllint --xpath "${policyLINT}" - )
}
for ((i=0;i<${#office_apps[@]};++i)); do
getAppVersion
re='^[0-9]+([.][0-9]+)?$'
if [[ $version =~ $re ]]; then
echo "${office_apps[i]}" version $version found
getJSSPatch
versionLength=${#version}
if [[ $(bc <<< "$version < ${current:0:${versionLength}}") -eq 1 ]]; then
echo Out of date...
echo Updating...
getPolicyID
jamf policy -id $id
else
echo "${office_apps[i]}" is current
fi
fi
done
exit 0