Suspicious Package 4.0 Update

I recently posted about some Suspicious Package Power User Features, which was a follow-up to my MacDevOps YVR presentation “The Encyclopedia of Packages.”

As a follow-up to that follow-up, Suspicious Package was updated to version 4.0 today. (Yesterday? Time zones are strange.) The update to brings compatibility with macOS Monterey and some really nice refinements to these power user features.

First and foremost, Suspicious Package will now show the kind of package, or “package format” in the Package Info tab. This makes me very happy, not just because the FAQ references my presentation. As the FAQ correctly states, most users of packages or even the Suspicious Package application will not care much about the differences between the package formats, but for system administrators, this can determine the difference between a functional deployment or a broken workflow.

The previously ‘secret’ option to show the PackageInfo xml file is now also exposed in the preferences window, next to the option to show the Distribution XML.

It is now also easier to search for the contents of a particular component in a distribution package.

You can download the latest version of Suspicious Package and get the update notes here.

Many thanks to Randy Saldinger of Mothers Ruin Software for providing this amazing tool and further refining it!

Randy was also recently a guest on the MacAdmins Podcast. You check it out if you have not yet listened to that episode.

Installomator v0.7b1 – Prerelease

We have posted a new version of Installomator. This one brings with it major changes in how we assemble the actual script. Since this is such a big change, we decided to do a beta release first.

The changes in detail:

  • script is now assembled from fragments. This helps avoid merging conflicts on git and allows the core team to work on the script logic while also accepting new labels. See the “Assemble Script ReadMe” for details.
  • Change in finding installed apps. We now look in /Applications and /Applications/Utilities first. If not found there, we use spotligt to find it. (We discovered a problem when a user has Parallels Windows installed with Microsoft Edge in it. Then Installomator wanted to update the app all the time, becaus spotligt found that Windows version of the app that Parallels created.)
  • Added bunch of new labels
  • Improved buildCaseStatement.sh a lot. It is a great start when figuring out how to create a new label for an app, or a piece of software.
  • Mosyle changed their app name from Business to Self-Service

Why the changes?

Since the Installomator.sh script has grown to over 3000 lines, its management on git has become very unwieldy. The single file with all the logic and the data required to download and install the applications creates constant merge conflicts which add to the workload of the repo admins, especially when part of the team is working on the logic of the script while we still get PRs to add labels.

Because of that we have split the main script into multiple files which are easier to manage. Having multiple files results in less merge conflicts.

What changes when I use the script?

Nothing. When you just use the Installomator.sh, you still copy its contents from the Installomator.sh script at the root of the repository into your management service (don’t forget to change the DEBUG value). Or you install the script to the clients using the installer pkg from the Releases.

The changes will only affect you when you want to build your own application labels, modify existing labels or other wise modify the script.

How do I build my own labels now?

This is where you need to learn about the new system. To reduce merge conflicts, we have broken the big Installomator.sh script into smaller pieces. There is a utility script that can assemble the script from the pieces and even run it right away fro testing. You can get the details in the “Assemble script ReadMe”

We hope that these changes will make it easier for the Installomator team and other contributors to keep growing and improving the script.

Suspicious Package Power User Features

As many MacAdmins, I work a lot with installer packages. You can say I wrote the book about it. When you get an installer package from some vendor website, you will want to inspect it before you install it anywhere, let alone deploy it to dozens, hundreds, or even thousands of Macs in your fleet.

You can use the pkgutil tool to do this in the command line, but there are package inspector tools with a graphical interface that are very useful and popular.

One of these tools is Suspicious Package from Mothers Ruin Software. It displays all of the content and resources of a pkg file in a very nice user interface. Many people love Suspicious Package from Mothers Ruin Software. I have always had reservations about Suspicious Package, though, because I thought there were a few missing features.

Update (August 2021): The app has gotten a new major update (4.0) which makes these “power user features” even more accessible!

The missing features were in connection with distinguishing “normal” or “component” packages (which have a single payload) from “distribution” or “meta” packages (which don’t have a payload of their own, but contain one or more component packages).

I have explained the differences in a bit more detail in my MacDevOps YVR presentation “The Encyclopedia of Packages” where I (once again, ignorantly) stated that you can’t really tell them apart in the UI of Suspicious Package.

After that presentation, Mat X, one of the organizers of the conference got me in touch with the developer of Suspicious Package, Randy Saldinger, who graciously and patiently demonstrated that I was wrong.

In my defense, you really cannot tell normal packages from distribution packages in the default configuration of Suspicious Package, but if I had bothered to read the manual and/or explore the Preferences window, I would have found this option:

This will show the Distribution xml file at the top of the list of the ‘All Scripts’ pane for distribution packages. When you see no Distribution file there, the package is a component package.

The second checkmark in that preference window is also very useful. With “Component package and bundle info” enabled you can see which component contains the selected file in the info pane:

You can also search in the “All Files” tab with command-F and use the component package ID as a search criteria.

All of this is already well enough to remove the reservations I have had on Suspicious Package. But Randy shared another preference with me which puts it over the top. It is not exposed in the UI (yet) but when you run:

% defaults write com.mothersruin.SuspiciousPackage ShowRawPackageInfo -bool YES

in Terminal and re-launch Suspicious Package, you will see the raw PackageInfo xml in the “All Scripts” tab. Together with showing the Distribution xml, this allows you to inspect all the raw metadata that can be inside a pkg file.

I have also learned that you can use the search functionality in the “Help” menu of Suspicious Package which will link directly to the online documentation. Not many apps leverage this functionality, so we often forget to check for it. Kudos to Suspicious Package for using this.

Many thanks to Randy for all his work and help and for providing an excellent tool! I am very much looking forward to the next version.

Installomator v0.6

We have posted an update for Installomator, which brings it to v0.6.

The changes are as follows:

  • several new and updated labels, for a total of 302
  • versionKey variable can be used to choose which Info.plist key to get the version from
  • an appCustomVersion() {} function can now be used in a label
  • with INSTALL=force, the script will not be using updateTool, but will reinstall instead
  • added quit and quit_kill options to NOTIFY
  • updated buildCaseStatement.sh
  • updated buildInstallomatorPkg.sh to use notarytool (requires Xcode 13)
  • several minor fixes

There have been some other organizational changes as well. We have moved the repo to its own team on GitHub: Installomator/Installomator. This should reflect that I am no longer the sole, or even the main contributor. Many thanks to Søren Theilgaard, Isaac Ordonez, and Adam Codega for helping maintain this!

And many thanks to everyone else who contributed!

Installomator Updated: v0.5

It has been a while, mainly because I was busy with other things, but there finally is a new release version of Installomator!

The reason work has progressed—quite significantly—even though I was distracted is that Søren Theilgaard and Isaac Ordonez have joined the project as conributors. All of the work from 0.4 to 0.5 was from one of them. We ahve some great plans to move this tool forward, as well.

Many of these new app labels have been provided from others, either through GitHub issues, pull requests, or through comments in the #installomator channel on MacAdmins Slack. Thanks to all who contributed.

What’s new in v0.5:

  • Major update and now with help from @Theile and @Isaac
  • Added additional BLOCKING_PROCESS_ACTION handlings
  • Added additional NOTIFY=all. Usuful if used in Self Service, as the user will be notified before download, before install as well as when it is done.
  • Added variable LOGO for icons in dialogs, use LOGO=appstore (or jamf or mosyleb or mosylem or addigy). It’s also possible to set it to a direct path to a specific icon. Default is appstore.
  • Added variable INSTALL that can be set to INSTALL=force if software needs to be installed even though latest version is already installed (it will be a reinstall).
  • Version control now included. The variable appNewVersion in a label can be used to tell what the latest version from the web is. If this is not given, version checking is done after download.
  • For a label that only installs a pkg without an app in it, a variable packageID can be used for version checking.
  • Labels now sorted alphabetically, except for the Microsoft ones (that are at the end of the list). A bunch of new labels added, and lots of them have either been changed or improved (with appNewVersion og packageID).
  • If an app is asked to be closed down, it will now be opened again after the update.
  • If your MDM cannot call a script with parameters, the label can be set in the top of the script.
  • If your MDM is not Jamf Pro, and you need the script to be installed locally on your managed machines, then take a look at Theiles fork. This fork can be called from the MDM using a small script.
  • Script buildCaseStatement.sh to help with creating labels have been improved.
  • Fixed a bug in a variable name that prevented updateTool to be used
  • added type variable for value "updateronly" if the label should only run an updater tool.

And if you are counting, there are now more than 260 application labels in Installomator. However, that number is a bit inflated, because several vendors have multiple downloads for Intel and Apple Silicon apps.

Get the script and find the instructions on the GitHub repo.

If you have any feedback or questions, please join us in the #installomator channel on MacAdmins Slack.

Thanks again to all those who contributed!

(Installomator Icon credit: Mischa van der Bent)

Get Password from Keychain in Shell Scripts

MacAdmin scripts often require passwords, mostly for interactions with APIs.

It is easiest to store the password in clear text, but that is obviously a terrible solution from a security perspective. You can pass the password as an argument to your script, but that is inconvenient and may still appear in clear text in the ps output or the shell history.

You can obfuscate the password with base64, but that is easily reversible. You can even try to encrypt the password, but since the script needs to be able to decrypt the password, you are just adding a layer of complexity to the problem.

macOS has a keychain, where the user can store passwords and allow applications and processes to retrieve them. We can have our script retrieve a password from a local keychain.

There are limitations to this approach:

  • the password item has to be created in the keychain
  • the user has to approve access to the password at least once
  • the keychain has to be unlocked when item is created and when the script runs—this usually requires the user to be logged in
  • the user and other scripts can find and read the password in the Keychain Access application or with the security tool

Because of these limitations, this approach is not useful for scripts that run without any user interaction, e.g. from a management system. Since the user can go and inspect the key in the Keychain Access is also not well suited for critical passwords and keys.

However, it is quite useful for workflow scripts that you run interactively on your Mac. This approach has the added benefit, that you do not have to remember to remove or anonymize any keys or passwords when you upload a script to GitHub or a similar service.

Note: Mischa used this in his ‘OnAirScanner’ script.

Update: I didn’t remember this, but Graham Pugh has written about this before.

How to Store a Password in the Keychain

Since adding the password to your keychain is a one-time task, you can create the password manually.

Open the Keychain Access application and choose “New Password Item…” from the Menu. Then enter the Keychain Item Name, Account Name and the password into the fields. The “Keychain Item Name” is what we are going to use later to retrieve the password, so watch that you are typing everything correctly.

You can also add the password from the command line with the security command.

> security add-generic-password -s 'CLI Test'  -a 'armin' -w 'password123' 

This will create an item in the Keychain with the name CLI Test and the account name armin and the horribly poor password password123.

How to Retrieve the Password in the Script

To retrieve a password from the keychain in a script, use the security command.

> security find-generic-password -w -s 'CLI Test' -a 'armin'

This will search for an item in the keychain with a name of CLI Test and an account name of armin. When it finds an item that matches the name and account it will print the password.

The first time you run this command, the system will prompt to allow access to this password. Enter your keychain password and click the ‘Always Allow’ button to approve the access.

This will grant the /usr/bin/security binary access to this password. You can see this in the Keychain Access application in the ‘Access Control’ tab for the item.

When you create the item with the security add-generic-password binary, you can add the -T /usr/bin/security option to immediately grant the security binary access.

Whether you grant access through the UI or with the command, keep in mind that a every other script that uses the security binary will also gain access to this password.

For very sensitive passwords, you can just click ‘Allow’ rather than ‘Always Allow.’ Then the script will prompt interactively for access every time. This is more secure, but also requires more user interaction.

Once you have tested that you can retrieve the password in the interactive shell, and you have granted access to the security binary, you can use command substitution in the script to get the password:

cli_password=$(security find-generic-password -w -s 'CLI Test' -a 'armin')

This command might fail for different reasons. The keychain could be locked, or the password cannot be found. (Because it was either changed, deleted or hasn’t been created yet.) You want to catch that error and exit the script when that happens:

pw_name="CLI Test"
pw_account="armin"

if ! cli_password=$(security find-generic-password -w -s "$pw_name" -a "$pw_account"); then
  echo "could not get password, error $?"
  exit 1
fi

echo "the password is $cli_password"

Twenty Years of Mac OS X

Mac OS X 10.0 was released March 24, 2001. Twenty years ago today.

The PowerBook, iMac, iPod, iPhone, iPad, and Apple Watch are obviously big steps along the way from Apple as a ‘beleagured,’ minor computer maker with an uncertain future to the $2 trillion tera-corp they are today. It is easy to focus on the hardware. But Mac OS X was at least as important.

Back then, it was essential that Apple move forward from ‘classic’ Mac OS. Protected memory, multi-user setups, and support for multiple applications running safely side-by-side were the main advantages of Mac OS X over Mac OS 9. But Mac OS X also brought with it the Unix core (and shell), a new display technology, and the Cocoa frameworks.

The transition was rough for the existing Mac users. The early versions were not as complete and stable as one would have hoped. The processing requirements of early Mac OS X pushed existing Mac hardware to their limits. Many application vendors dragged their feet adopting Mac OS X and the new technologies and features available.

But Mac OS X made the Mac interesting for a whole new group of people. It was the only platform at then time that they had Microsoft and Adobe productivity app as well as the Unix shell and tools available. This was a huge bonus for web designers and developers, but also for scientists.

Apple built some of the best laptops of the time. It might seem strange now, but having a portable, battery-powered Unix workstation, which also ran Word, Excel, Photoshop, and could edit videos, was un-imaginable just a few years before.

Then, Apple stripped down Mac OS X, so it could run on on a phone. Up until then, portable devices had very basic and minimal operating systems. They were also locked down and installing additional software was complicated and often expensive.

The early versions of iPhone OS were also basic and minimal compared to Mac OS X, but they held the promise of extension and growth. The iPhone had potential and Apple delivered on that promise with every system update. They treated the iPhone as a computer, rather than a gadget. It took a few years, but with the iPhone, people went from having one computer, to two computers: one in your pocket and one on your desk or in your bag.

Today, Apple has a range of operating systems from the watch on your wrist to the large screen in your living room, all going back to Mac OS X 10.0 twenty years ago. macOS is just one element in this ecology of devices. We don’t just have one computer, we have many. A spectrum of computers, most of them wireless and battery-powered, each with different strengths. These computers might all be from Apple, or from a variety of vendors.

macOS is part of this spectrum. In the past years, Apple has changed the name and just last year the major version number of their operating system for laptops and desktops.

Sometimes it seems that Apple has lost sight of what makes Macs an important tool. With Apple silicon for Macs, it seems that Apple is re-focusing on the Mac and seeing how they can improve macOS, while also improving the eco-system as a whole.

“macOS 11” holds a promise for continued and even re-newed growth. Like the first “Mac OS X” twenty years ago, and the first iPhone OS, there is potential.

I am looking forward to the next twenty years!

EraseInstall application retired

It makes me very sad that the EraseInstall application has been retired.

We built this tool three years ago, mostly because we wanted to learn how to build an app like this on macOS. We think it worked out well. We learned a lot, and are glad the application was useful to some.

Since then, all the people involved in the EraseInstall Project have moved on to other jobs or other responsibilities. Unfortunately, this leaves us with no time or resources to maintain or improve EraseInstall.

The repository and the application will remain available in its current state. There will be no more updates. If someone feels they can take up the project and continue it, please do!

If you are looking for a similar solution, we recommend Graham Pugh’s eraseinstall script.

Thank you, all, again!

Team EraseInstall: Mischa van der Bent, Arnold Nefkens, and Armin Briegel

Platform Support in macOS Installer Packages (pkg)

Mac users and admins find themselves in yet another major platform transistion. For the duration of the transition, developers and admins will have to deal with and support software and hardware for the Intel and Apple silicon Macs. With Universal applications and Rosetta 2, Apple is providing very efficient tools to dramatically reduce the friction and problems involved.

This post was inspired by comments from Josh Wisenbaker on MacAdmins Slack and Twitter. Thank you!

For most end user level tasks, these tools will provide seamless experience. Universal applications will run on either platform natively and Rosetta 2 will translate applications compiled for the legacy platform (Intel) so they can run on the new Apple silicon chips. There are only a few situations where these tools don’t work: virtualization solutions and Kernel extensions.

In most cases this tools will “just work.” But for MacAdmins there is one major issue that may throw a wrench in your well-oiled deployment workflows. Rosetta is not pre-installed on a fresh macOS installation.

We can only speculate why Apple chooses to deliver Rosetta this way. In “normal” unmanaged installations, this is not a big deal. The first time a user installs or launches a solution that requires Rosetta, they will be prompted to for installation and upon approval, the system will download and install Rosetta.

As a MacAdmin, however, you want your deployments to be uninterrupted by such dialogs. Not only are they confusing to end users, but the user might cancel out of them which will result in your workflow failing partially.

There are two solutions. The first is to install Rosetta as early as possible in the deployment process. Apple provides a new option for the softwareupdate command to initiate the installation. Graham Gilbert and Rich Trouton have already published scripts around this. Have this script run early in your deployment workflow on Apple silicon and subsequent apps and tools that require Rosetta should be fine.

The other solution is to avoid requiring Rosetta and thus the prompt for Rosetta.

I mentioned earlier that we can only speculate as to why Apple has made Rosetta 2 an optional installation. One possible explanation is, that Apple believes Rosetta will not be a necessary installation for very long. An extra dialog and installation will make users and developers more aware of software that “needs an update” and motivate developers to provide Universal applications faster.

When a user opens an application that requires Rosetta for the first time, before Rosetta is installed, the system prompts to install. The same thing can happen with an installer package. The system might prompt to install Rosetta before a certain package is installed. However, not all packages trigger the dialog. I was curious what is required in the package to trigger or to avoid the prompt.

Aside from legacy formats, there are two types of packages. The first are “plain” packages, which are also called component packages. These packages have a payload and can have pre- and postinstall scripts, but other than that, there is little metadata you can add to influence the installation workflow.

This is where “distribution packages” come in. Distribution packages do not have a payload or installation scripts of their own, but contain one or more component packages. In addition, distribution packages can contain metadata that influences the installation workflow, such as customization of the Installer.app interface, system version checks, prompting the user to quit running applications before an installation and software requirements and a few more.

Note: learn more about the detailed differences between component and distribution packages in my book: “Packaging for Apple Administrators

You can build a distribution package from a component package with the productbuild command:

> productbuild --package component.pkg distribution.pkg

Since most of the extra features of distribution packages are only effective when the installation package is launched manually in the Installer application, MacAdmins usually just build component pkgs.

The confusing part here is that both component pkgs and distribution pkgs have the same file extension. They are hard to distinguish even from the command line. To tell them apart, you can expand a pkg with the pkgutil command and look at the files in the expanded folder. Component pkgs have (among other files) a PackageInfo file and distribution pkgs have a Distribution file:

# component pkg
> pkgutil --expand component.pkg expanded_component_pkg
> ls expanded_component_pkg
Bom
Payload
Scripts
PackageInfo

# distribution pkg
> pkgutil --expand distribution.pkg expanded_distribution_pkg
> ls expanded_distribution_pkg
component.pkg
Distribution

For distribution pkgs, the Distribution file is an XML file which contains the configuration data for the package. One tag in this XML is the options tag which can have a hostArchitectures attribute. According to [Apple’s documentation on this tag](A comma-separated list of supported architecture codes), the hostArchitectures are a “comma-separated list of supported architecture codes.”

Apple documentation is a bit aged, so it gives i386, x86_64, and ppc as possible values. However, when you read the productbuild man page on macOS Big Sur you will see that arm64 is a new valid value. We will also find these extremely helpful note:

NOTE: On Apple Silicon, the macOS Installer will evaluate the product’s distribution under Rosetta 2 unless the arch key includes the arm64 architecture specifier. Some distribution properties may be evaluated differently between Rosetta 2 and native execution, such as the predicate specified by the sysctl-requirements key. If the distribution is evaluated under Rosetta 2, any package scripts inside of product will be executed with Rosetta 2 at install time.

When a distribution pkg has this attribute and it contains a value of arm64 then the installation process on an Apple silicon Mac will not check if Rosetta is installed. When arm64 is missing from the hostArchitectures, or the attribute or tag are missing entirely, the installation process on an Apple silicon Mac will asume the pkg requires Rosetta and prompt to install when necessary.

There is more good news in the next note in the man page:

NOTE: Starting on macOS 11.0 (Big Sur), productbuild will automatically specify support for both arm64 and x86_64 unless a custom value for arch is provided.

When you use productbuild to create a distribution pkg on Big Sur (Intel and Apple silicon) both arm64 and x86_64 will be added to the configuration by default.

But, when you use productbuild on Catalina or earlier, the attribute will be lacking, when means that when someone installs that pkg on an Apple silicon Mac, it will assume it requires Rosetta and prompt for installation.

Adding both architectures by default is a useful default. But can we set the value explicitly when we build the distribution pkg? And can we do so on Catalina?

Yes, you can, of course. There are even two solutions. First, instead of letting productbuild generate the Distribution xml, you can build and provide a complete Distribution xml file with the --distribution option. That will give you full, fine-grained control over all the options.

The second solution is a bit easier. You can create a requirements.plist property plist file in the form:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>arch</key>
        <array>
                <string>x86_64</string>
                <string>arm64</string>
        </array>
</dict>
</plist>

Then you can provide this property list file to the productbuild command with the --product option.

> productbuild --package component.pkg --product requirements.plist distribution.pkg

This way, productbuild still generates the Distribution xml and merges in your choices from the requirements.plst. There are other options you can add which are documented in the productbuild man page.

Both of these approaches will work on Catalina as well. This way you can explicitly tell the installer system which architectures your packages will run with and not leave anything to chance.

In Whitebox Packages you can configure the hostArchitectures attribute under the “advanced options” for a distribution package.

As far as I can tell, when you install a component pkg, no checks for Rosetta are performed. Nevertheless, this is not something I would rely on. For packages that are crucial to the deployment workflow, I would recommend going the extra step and creating a distribution pkg from the component pkg with the proper flags set. This way you can ensure proper behavior.

Of course, if your package installer contains any form of Intel-only, not-universal binary, you should not abuse this just to skip the annoying Rosetta dialog, as it might lead to problems later. But, when the software you are installing is universal, you sould use this to tell the system which platforms your package supports.

Deploying the Big Sur Installer Application

When you want to provide automated workflows to upgrade to or erase-install macOS Big Sur, you can use the startosinstall tool. You can find this tool inside the “Install macOS Big Sur” application at:

/Applications/Install macOS Big Sur.app/Contents/Resources/startosinstall

Note: Apple calls the “Install macOS *” application “InstallAssistant.” I find this a useful shorthand and will use it.

Before you can use startosinstall, you need to somehow deploy the InstallAssitant on the client system. And since the “Install macOS Big Sur” application is huge (>12GB) it poses its own set of challenges.

Different management systems have different means of deploying software. If you are using Munki (or one of the management systems that has integrated Munki, like SimpleMDM or Workspace One) you can wrap the application in a dmg. Unfortunately, even though “app in a dmg” has been a means of distributing software on macOS for nearly 20 years, most management systems cannot deal with this and expect an installer package (pkg).

You can use pkgbuild to build an installer package from an application, like this:

pkgbuild --component "/Applications/Install macOS Catalina.app" InstallCatalina-10.15.7.pkg

This works for all InstallAssistants up to and including Catalina. With a Big Sur installer application this command will start working, but then fail:

% pkgbuild --component "/Applications/Install macOS Big Sur.app/" InstallBigSur20B29.pkg
pkgbuild: Adding component at /Applications/Install macOS Big Sur.app/
pkgbuild: Inferred install-location of /Applications
pkgbuild: error: Cannot write package to "InstallBigSur20B29.pkg". (The operation couldn’t be completed. File too large)

The reason for this failure is that the Big Sur installer application contains a single file Contents/SharedSupport/SharedSupport.dmg which is larger than 8GB. While a pkg file can be larger than 8GB, there are limitations in the installer package format which preclude individual files in the pkg payload to be larger than that.

When you want to distribute the “Install macOS Big Sur” application to the clients in your fleet, either to upgrade or for an erase-and-install workflow, this limitation introduces some challenges.

You can use Composer with Jamf to create a Jamf dmg style deployment, but that will only work with Jamf Pro. You could further wrap and split the application in different containers, but that will increase the creation and deployment time.

There are a number of solutions. Each with their own advantages and downsides, some supported and recommended by Apple and some… less so. Different management and deployment styles will require different solutions and approaches.

App Deployment with MDM/VPP

When you have your MDM hooked up to Apple Business Manager or Apple School Manager, you can push applications “purchased” in the “Apps and Books” area with MDM commands. This was formerly known as “VPP” (Volume Purchase Program and I will continue to use that name, because “deploy with Apps and Books from Apple Business Manager or Apple School Manager” is just unwieldly and I don’t care what Apple Marketing wants us to call it.

Since the “Install macOS Big Sur” application is available for free on the Mac App Store, you can use VPP to push it to a client from your MDM/management system.

When you do this, the client will not get the full InstallAssistant application, but a ‘stub’ InstallAssistant. This stub is small in size (20-40MB).

The additional resouces required for the actual system upgrade or installation which are GigaBytes worth of data will be loaded when they are needed. It doesn’t matter whether the process is triggered by the user after opeing the application or by using the startosinstall or createinstallmedia tool. Either workflow will trigger the download of the additional resources.

This has the advantage of being a fast initial installation of the InstallAssistant, but then the actual upgrade or re-installation process will take so much longer, because of the large extra download before the actual installation can even begin. For certain deployment workflows, this is an acceptable or maybe even desireable trade-off.

The extra download will use a Caching Server. This approach is recommended and supported by Apple.

Mac App Store and/or System Preferences

For some user-driven deployment styles, having the user download the InstallAssistant themselves can be part of the workflow. This way, the user can control the timing of the large download and make sure they are on a “good” network and the download will not interfere with video conferences or other work.

You can direct then to the Big Sur entry in the Mac App Store with a link. You cannot search for older versions of macOS Installers in the Mac App Store, but Apple has a kbase article with direct links.

You can also use a link that leads a user directly to the Software Update pane in System Preferences and prompts the user to start the download:

# Big Sur
x-apple.systempreferences:com.apple.preferences.softwareupdate?client=bau&installMajorOSBundle=com.apple.InstallAssistant.macOSBigSur

# Catalina
x-apple.systempreferences:com.apple.preferences.softwareupdate?client=bau&installMajorOSBundle=com.apple.InstallAssistant.Catalina

When the InstallAssistant is already installed, this link will open the application. When the Mac is already running a newer version of macOS or doesn’t support the version given, it will display an error.

You can use these links from a script with the open command:

open 'x-apple.systempreferences:com.apple.preferences.softwareupdate?client=bau&installMajorOSBundle=com.apple.InstallAssistant.macOSBigSur'

The downloads initiated this way will use a Caching Server. Linking to the Mac App Store is supported and recommended by Apple. The x-apple.systempreferences links are undocumented.

softwareupdate command

Catalina introduced the --fetch-full-installer option for the softwareupdate command. You can add the --full-installer-version option to get a specific version of the installer, for example 10.15.7.

You can run this command from a managed script on the clients to install the application. The download will use a Caching Server.

This would be a really useful method to automate deployment the InstallAssistant on a client, if it were reliable. However, in my experience and that of many MacAdmins, this command is very fragile and will fail in many circumstances. As of this writing, I have not been able to reliably download a Big Sur InstallAssistant with this command. Most of the time I get

Install failed with error: Update not found 

This approach is often recommended by Apple employees, however it will have to be much more reliable before I will join their recommendation.

Please, use Feedback Assistant, preferably with an AppleSeed for IT account, to communicate your experience with this tool with Apple. If this command were reliable, then it would be my recommended solution for nearly all kinds of deployments.

InstallAssistant pkg

With these solutions so far, we have actually avoided creating an installer package, because we moved the download of the InstallAssistant to the client. A caching server can help with the network load. Nevertheless for some styles of deployments, like schools and universities, using the local management infrastucture (like repositories or distribution points) has great advantages. For this, we need a package installer for the InstallAssistant.

A “magic” download link has been shared frequently in the MacAdmins Slack that downloads an installation package from an Apple URL which installs the Big Sur InstallAssistant.

This pkg from Apple avoids the file size limit for the package payload by not having the big file in the payload and then moving it in the postinstall script. Smart hack.. er… solution!

The URL is a download link from a software update catalog. You can easily find the link for the current version with the SUS Inspector tool.

But it would be really tedious to do this on every update. You, the regular reader, know the “tedious” is a trigger word for me to write a script. In this case it was less writing a script than looting one. Greg Neagle’s installinstallmacos.py had most of the pieces needed to find the InstallAssistant.pkg in the software update catalog and download it. I merely had to put the pieces together somewhat differently.

Nevertheless, I “made” a script that downloads the latest InstallAssistant.pkg for macOS Big Sur. You can then upload this pkg to your management system and distribute it like any other installation package.

It works very much like installinstallmacos.py.

./fetch-installer-pkg.py

When you start the script it will download a lot of data into a content folder in the current working directory, parse through it and determine the Big Sur Installers in the catalog. When it finds more than one installers, it will list them and you can choose one. When it finds only one Installer, it will start downloading that immediately.

You can add the --help option for some extra options (all inherited from installinstallmacos.py.

We will have to wait for the 11.1 release to be sure this actually works as expected, but I am confident we can make it work.

This approach is very likely not supported by Apple. But neither was re-packaging the InstallAssitant from disk in Catalina. This deployment method is likely closer to the supported deployment workflows than some common existing methods.

The download does not use a Caching Server, but since the goal is to obtain a pkg that you can upload to your management server, this is not a big downside.

Big Sur signature verification check

You may have noticed that when you launch the Big Sur InstallAssistant on Big Sur for the first time, it will take a long time to “think” before it actually launches. This is due to a new security feature in Big Sur that verifies the application signature and integrity on first launch. Since this is a “big” application this check takes a while. Unfortunately Big Sur shows no progress bar or other indication. This check occurs when the user double-clicks the app to open it and when you start an upgrade or installation with the startosinstall command.

There does not seem to be a way to skip or bypass this check. You can run startosinstall --usage from a script right after installing the InstallAssistant. This will do nothing really, but force the check to happen. Subsequent launches, either from Finder or with startosinstall will be immediate.