Patch Management Now...for Office...with the API...kinda


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!


# 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

declare -a office_apps=(

declare -a patch_uri=(

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
    if [[ $version =~ $re ]]; then
        echo "${office_apps[i]}" version $version found
        if [[ $(bc <<< "$version < ${current:0:${versionLength}}") -eq 1 ]]; then
            echo Out of date...
            echo Updating...
            jamf policy -id $id
            echo "${office_apps[i]}" is current
exit 0

Contributor III

I'm intrigued by this.

We're still running Office 2011 and I'm in the process of setting things up for 2016 which includes how we'll implement updates. What are the advantages and disadvantages of doing this as opposed to using a smart group and the same policies? From my point of view it seems like there would be more control with a smart group if that control was needed. Am I missing something(always quite possible)?


I always found that with smart groups I have many groups to update and policies to update. This policy can be run over and over with only updating the policies. You could scope it to everyone. If you don't have Office or are missing just one application (or all but one) it will only attempt the actual app found.

This script doesn't do anything if there is no version number returned e.g. "not found" from spotlight.

We don't cache or push these updates - could probably cache... - since they are so big and can take a while. This is leading us to having many copies of out-of-date Office apps. With this one "Run Office Updates" button a user can get fully updated when they need it.

You could create a smart group and prod them if that group is too far behind or someone is in it too long. For us it was mostly about a user being able to initiate updates on their own when they want to without IT having to update a dozen locations. This just requires updating the individual app "Updater" policies.