Posted 2021 August 23
Because Apple’s major OS release schedule does not align with the academic calendar at my University (and most others), I hold off deploying the newest major version of macOS until at least January but more commonly May. So when I started reading things that suggested that
softwareupdate wasn’t working for triggering updates, I wasn’t seeing it because I was still running Catalina. When I read that the biggest problems were fixed in macOS 11.3, I thought I was in the clear since I didn’t start deploying Big Sur in earnest until 11.4. Well, it seems that things are a little more complicated than that. The information I needed to finish my deployments was in bits and pieces all over the place, and I had to learn some things through experimentation. This article is meant to gather some of this disparate information in one place to make things easier for your Big Sur (and likely Monterey) deployments.
Note that this article will focus on how to deploy Big Sur updates on shared use computers, such as computer labs or libraries. If you are deploying single user computers, there may be some resources here that are useful, but your best strategy is likely to have the user update their Mac using Software Update in the GUI as God Apple intended, supplementing with tooling that reminds the user to do so (such as Nudge) as necessary.
Software Update at the Login Screen
The first roadblock I encountered was that
softwareupdate didn’t work with no user logged in, which had been the desired state for running Software Update in the past for my labs. My scale is such that I could login in to every single computer using an admin account and do this manually, but clearly that doesn’t work for larger deployments, nor does it make it possible to quickly deploy macOS updates that have a security payload. The first piece of wisdom I picked up was that deploying the full installer could be done without requiring a logged in user and would correctly update the system, albeit with a bandwidth penalty (13 GB per station as opposed to 3–4 GB). So the first step was to reliably download the latest installer for Big Sur.
Fetching Full Installers
There are many ways to fetch a full macOS installer these days. Which one you use will probably depend on your desired workflow. Armin Briegel describes many of these options in detail in a blog post from November 2020. The ones that apply to Big Sur and shared Macs are:
- Greg Neagle’s
- Armin Briegel’s
fetch-installer-pkgPython script (which leverages code from Greg’s tool)
Armin references InstallAssistant in that post. For those of you who use a management platform that requires packages for deployment (e.g., Jamf Pro), grabbing the full ~13 Gb installer already in pkg form is a great option since it is hard to make a package that big yourself. Armin suggests using SUS Inspector to find the link, but Ryan (nom de plume Mr. Macintosh) does a good job of maintaining a list of the links to the versions that are (still) live. When you run this installer package, it puts the Install macOS Big Sur.app in
/Applications. You can then use a shell command or script to trigger
startosinstall, since you know where the installer app is located.
If you like GUI tools, there are two other options that leverage Greg’s
installinstallmacos under the hood to get you the latest full macOS installer as an app:
- Armin Briegel’s Download Full Installer, a Swift/Swift UI wrapper for the aforementioned fetch-installer-pkg, and
- MDS from Twocanoes Software, which has a Download macOS Installer tool (MDS can use the dmg it creates in its workflows).
As an aside, Apple Silicon Mac computers have another option that operates similar to iOS/iPadOS devices. If you are willing to wipe the Mac, you can download the latest IPSW from Apple and use Apple Configurator 2 from another Mac to apply the new system. Once again, Greg Neagle has a command line tool,
getmacosipsws, and Ryan/Mr. Macintosh maintains a convenient list of links to help you download the IPSW file you need from Apple.
Triggering the Full Installer
Once you have your full installer, you need to deliver it to your target systems using your management system. (This could even be Apple Remote Desktop, in this instance.) Once the installer is there, you can invoke the
startosinstall command from within the bundle to trigger the install. Since I am using Jamf Pro, my solution was to create a policy that installed InstallAssistant.pkg, scoped to all the Mac computers that I wanted to update (all of them, in this case). I then created a Smart Group of all computers that had the Install macOS Big Sur.app in
/Applications, which is what the state should be when InstallAssistant is done. Finally, I created a policy scoped to this Smart Group that triggers
startosinstall. I tested this updating my shared Macs from 10.5.1 to 10.5.2 and it worked whether or not a user was logged in.
M1 Volume Owners
“But what about Apple Silicon Mac computers? Don’t they need a volume owner to enter their password in the GUI?” Yes, this was something that was difficult to work around, but I did find a solution by finding some tips in the MacAdmins Slack. The first tip was from @Pico in the #applesilicon channel (which was also confirmed in a separate suggestion in #general by Apple’s Mike Lynn): you can confirm which users are volume owners by using the command
diskutil apfs listUsers /, which will give you output that looks something like this:
Cryptographic users for disk3s3s1 (3 found) | +-- 2457711A-523C-4604-B75A-F48A571D5XXX | Type: MDM Bootstrap Token External Key | Volume Owner: Yes | +-- 4AC779B9-A1ED-49EB-B51B-9E5A6AFD0XXX | Type: Local Open Directory User | Volume Owner: Yes | +-- 942F530E-5544-4D46-A1A1-994CB35E6XXX Type: Local Open Directory User Volume Owner: Yes
As you can see, this only lists the generated user ID (GUID) for each user, not their actual usernames. You can determine the short username in one of two ways:
- In an admin account, use the command
sudo fdesetup list, which will output the shortname and the GUID for each Local Open Directory User—use this information for comparison;
- Take the GUID for the Local Open Directory User you want to investigate and add it to the end of the command
dscl . -search /Users GeneratedUID, which will return the short username and the GUID you entered.
Because all my Lab computers are configured in the same way, I found that the two local accounts I create on each system (one admin account via Jamf Pro, one standard user via Setup Assistant) are both volume owners. So I could use either of them on the Apple Silicon Mac computers.
Triggers for Intel and Apple Silicon
As I suggested before, I used the
startosinstall command to trigger the installation of the macOS Installer. For Intel computers, this was fairly simple:
/Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/startosinstall --agreetolicense --nointeraction
(you may need to scroll sideways to see the full command).
But Apple Silicon Mac computers require authorization by a volume owner. This was where the second tip I picked up from the MacAdmins Slack came in. Sterling Anderson provided a workflow in the #workspaceone channel that included piping the password for a volume owner into the
startosinstall command. He was referring to an erase and install workflow, but the concept applies equally well to just running the installer:
echo password | /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/startosinstall --agreetolicense --nointeraction --user volumeowner --stdinpass
(substitute the desired values for password and volumeowner).
Of course, this involves placing a password in my management system in plain text. Because volume owners can be standard users, you don’t have to store the keys to the kingdom in this command. In my case, that standard local user is my emergency local user when network accounts aren’t working (or the person forgot their password and we don’t have time to reset/fetch it), so the password is an open secret; you can only do limited damage with it. If I were really concerned, it might be interesting to experiment with creating a disposable standard account to use for this process.
I ended up setting up two separate Jamf Pro policies, one scoped to Intel machines and one to Apple Silicon machines, using Smart Groups based on architecture. Since the commands were one-liners, I used the Files and Processes > Execute Command payload. (You could certainly trim it to a single policy by writing a script with logic based on the architecture. This approach may work better with your management platform or skillset.) Because the macOS Installer is deleted once a successful installation occurs, you don’t have to worry about tidying up. In fact, this allowed me to set the Execution Frequency of this Jamf Pro policy to Ongoing, since it would drop out of the Smart Group (and thus out of scope) once the macOS install was done. When the next update to macOS comes out, I just have to push out the new macOS Installer app to my shared computers and they will be brought back in scope, causing the policy to run automatically. Profit!
Caveats and Misc. Findings
I did not test moving from 11.4 to 11.5.2 directly. There have been reports that you might have trouble doing that on Apple Silicon Mac computers in one step (there is a useful thread in the #applesilicon channel of the MacAdmins Slack if you experience this).
Since all my Apple Silicon Mac deployments were new computers, if something failed badly, I could just use the IPSW file and Apple Configurator 2 to bring me back to a good state. Because I setup computers afresh using MDS, it was sometimes simpler to just “revive” my M1 Mac instead of doing a full restore (which takes longer), since I would have MDS just erase and install the OS regardless. Reviving brings Recovery up to the current version of the OS (or whichever IPSW you are using), so any of the “you need to be at 11.x for this to work” can be hopped over. This became quite useful for me.
Finally, after I posted this, Graham Pugh reminded me that his
erase-install tool could also be used in situations where you just wanted to install the macOS Installer and not erase the system. It incorporates Greg’s
installinstallmacos (and Armin’s pkg variant) and has lots of options (well-documented in the wiki) that could do all of the things I mentioned in this post (including just downloading the macOS Installer and triggering the update from Jamf Pro). There is only one exception: installing macOS as an update on Apple Silicon with no user logged in. Graham tells me that it would not be hard to add that option, since most of the logic is already there, so I’m certain Graham would be open to a pull request on his project in this regard.
I hope having this all in one place has been helpful for readers. Let me know if there are things that could use clarifying or updating for future readers.
Updated 2021-08-24 to add information on
 MDS does have the ability to create workflows that don’t install macOS, so one could do a full restore and the only difference from an Apple Silicon Mac from the factory would be the absence of Keynote, Pages, Numbers, and GarageBand. I did play with adding a workflow that setup my stations this way, but couldn’t quite get it functioning in the time frame I needed. Hence, I opted for the workflow I knew that worked, even if it was less efficient. A project for another day…. [Return to main text]