Handling macOS Software Updates with Jamf Pro

Jamf Pro has not handled software updates successfully on all Mac hardware since Apple introduced the T2 processor with the iMac Pro back in December 2017. It’s been requested that they address this issue in a feature request, but it’s gone completely unacknowledged (Edit: As of November 11, 2019, the feature request is now marked as Under Review).

The problem with the software update process on Macs with T2 processors is that sometimes there is a bridgeOS update (the OS on the T2 processor) which requires a shutdown instead of a restart. The Mac will read the shutdown and automatically power back on to apply the bridgeOS update. However, not all software updates have a bridegeOS update which would mean a shutdown in those situations would actually leave the computer powered down. Unfortunately, Jamf Pro does not know how to handle this situation. Apple did introduce the --restart option for softwareupdate but that also comes with its own problems in that it hasn’t worked reliably in all scenarios. Since the solution to this isn’t particularly difficult to work around, I created a script to address this workflow in our environment.

Before continuing, I’d like to mention that we do leverage macOS’s ability to do automatic updates. This has one benefit of doing automated authenticated restarts which is important on Macs with FileVault enabled. However, we’ve found in our environment that after a month only 60% of computers running macOS 10.14 are up to date on the latest version. It’s a bit of a black box as to how macOS determines when to do automatic updates. Needless to say, the rate of updates is unacceptable.

This script is meant to be used with Jamf Pro and makes use of Jamf Helper. The idea behind this script is that it alerts the user that there are required OS updates that need to be installed. Rather than forcing updates to take place through the command line using “softwareupdate”, the user is encouraged to use the macOS GUI to update. When I say macOS GUI, I’m referring to the Software Update mechanism that Apple refers consumers to: https://support.apple.com/en-us/HT201541

In recent OS versions, Apple has done a poor job of testing command line-based workflows of updates and failed to account for scenarios where an end-user may or may not be logged in. The update process through the GUI has not suffered from these kind of issues. The script will allow end users to postpone/defer updates X amount of times and then will give them one last change to postpone. We run this script using the Once A Day policy frequency which means the user will get this once a day so long as it checks in.

This script should work rather reliably going back to 10.12 and maybe further, but at
this point the real testing has only been done on 10.14. Please note, that this script does NOT cache updates in advance. Sometimes Apple releases updates that get superseded in a short time frame. This can result in downloaded updates that are in the /Library/Updates path that cannot be removed in 10.14+ due to System Integrity Protection.

This script does make use of Jamf Pro Script Parameters:
Parameter 4: Optional. Number of postponements allowed. Default: 3
Parameter 5: Optional. Number of seconds dialog should remain up. Default: 900 seconds
Parameter 6: Optional. Contact email, number, or department name used in messaging. Default: IT

Here is the expected workflow with this script:

  1. If no user is logged in, the script will install updates through the command line and
    shutdown/restart as required.
  2. If a user is logged in and there are updates that require a restart, the user will get
    prompted to update or to postpone.
  3. If a user is logged in and there are no updates that require a restart, the updates will get installed in the background (unless either Safari or iTunes are running.)

There are a few exit codes in this script that may indicate points of failure:
11: No power source detected while doing CLI update.
12: Software Update failed.
13: FV encryption is still in progress.
14: Incorrect deferral type used.

Below are some screenshots for what you will see on macOS Mojave. However the text is aware of at least 10.8 and higher where the instructions to get to Software Update might differ.

This is the initial message you will see when prompted to update:

Update1.png

When you click Continue, you will be taken to Apple’s Software Update:

Update3.pngUpdate4.png

This is the final message you will get when you’ve postponed the maximum number times:

Update2.png

Note: “Please make selection in HH:MM:SS” is not text I can modify. It serves as a countdown for the end user to know how much time they have before they are forced to update.

And lastly when the forced update is taking place, a headsup display window pops up:

Update5.png

The script is easy to modify if you don’t like the verbiage or if you want to use it for inspiration on other workflows. The script can be found here on my Github page.

15 thoughts on “Handling macOS Software Updates with Jamf Pro

  1. Excellent work and well thought out, I can’t find anything i wanted to change. This is a good light touch management approach to macOS updates.

    Like

  2. nice script but I’ve come across an interesting edge case in my first test. In testing on a 10.14.5 machine there was an iTunes restart update available. installed this and restarted. next time it ran 10.14.6 update was available but the defer count hadn’t gone down. Tried this using interactive install and forced install. I’m not sure of a way round this as the interactive install can always be cancelled by the user thus avoiding any way to clear the counter in the script. In the automated method it could be set to clear the deferral count.

    Like

    1. The latest version of my script should account for this. I previously did not reset the deferral counter prior to restarting under the rationale that somehow a user could game the restart process to avoid the update. But that seems very unlikely.

      Like

  3. Hi, I’m evaluating this script but it just does not seem to run on my Jamf. it errors with no information. Do I need to amend it in anyway? I inserted parameters in 4&5.

    Like

    1. What’s the output you get in the policy log? Is this happening with every computer or just one? Can you try modifying the first line in the script to `#!/bin/bash -x` to see what is getting executed?

      Like

    1. I was doing some testing in Catalina with this script a week or two ago. Testing was mostly just around the changes in the text output which has changed slightly in Catalina versus previous versions of macOS. It seemed at least in my brief testing that the script seems to handle these changes fine. Did you have problems running this script in Catalina?

      Like

    2. Just wanted to let you know that I did some more testing today on Catalina. I made some updates to the script with some other bug fixes. I can confirm that it works in Catalina.

      Like

  4. Great work! Would you mind sharing your Software Update settings as well? Do you use a configuration profile in conjunction with this script? Specifically, I’m interested if you are setting or disabling ‘Download new updates when available’. Thanks!

    Like

  5. Thanks for making this available. I’ve just been reviewing this to see if it could work in our environment.
    Please correct me if I’m wrong but it would appear that if the prompt occurs when a user isn’t at their machine, or they simply ignore it, there is a 15 minute timeout (default). During which time the jamf policy process is blocked waiting for the script to finish running. That doesn’t seem ideal as it could prevent other important actions from being completed.

    Like

    1. This is a fair point and one I thought of when making the script. In our environment we actually do not use the default value of 15 minutes to time out. We have it set to 90 minutes. At least in our experience, it does not seem to have stopped jamf from running other policies. I believe that jamf will get into a state where it will simply launch another jamf process when it’s supposed to check in again (even if there’s already a jamf process running). You can test this out yourself of course and let me know what your experience is.

      And naturally, if you don’t particularly like the logic for this part of the script, you can change the default time out value so that it’s less than your jamf check-in period. Alternatively, you can make your own modifications to the script as well to fit your company’s needs.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s