Home > Casper, Mac administration, Mac OS X, Scripting > Providing OS X Upgrades via Casper’s Self Service

Providing OS X Upgrades via Casper’s Self Service

To help the folks in my shop keep their Macs updated to the latest version of OS X, I’ve been providing a Self Service-driven OS upgrade option via Casper for the past couple of years. For a high-level overview, here’s how the process looks for El Capitan from my folks’ perspective.

1. Launch Casper’s Self Service application.

Screen Shot 2015 11 11 at 1 30 21 PM


2. Locate the El Capitan Upgrade option

Screen Shot 2015 11 23 at 9 02 19 AM


3. Click on the Install OS X button.

Screen Shot 2015 11 23 at 9 02 20 AM


4. In the next window that pops up, they’re given important information about the OS upgrade and need to click again on the Install OS X button.

Screen Shot 2015 11 23 at 9 02 31 AM


If their Mac does not have sufficient free space available available on their boot drive, they receive a warning message and the upgrade process stops at this point.

Screen Shot 2015 08 24 at 2 11 12 PM

If their Mac’s boot drive has sufficient free space available, they receive a message that OS X 10.11.x is downloading and preparing for installation. Once all preparations are complete, their Mac will automatically reboot to begin the installation process.

Screen Shot 2015 08 24 at 2 35 40 PM


5. Once the Mac reboots, the OS upgrade process runs. Once completed, the Mac reboots.

Screen Shot 2015 11 24 at 2 53 53 PM


6. Following the reboot, an automated post-upgrade process runs. This process will update the Mac with all available Apple updates along with applying my shop’s preferred settings for the new version of OS X.

Note: This process may involve several reboots, depending on what Apple updates are needed. Once the post-upgrade process completes, the Mac will reboot again.

Screen Shot 2015 11 24 at 3 00 18 PM


7. Following the reboot, the Mac will boot to the login window. At this point, the OS upgrade process has been completed and it is OK to log in and begin working again.

Screen Shot 2015 11 24 at 3 02 39 PM


To see how I’ve set up this workflow using Casper and other tools, please see below the jump.

The OS X upgrade method that I’m using leverages createOSXinstallPkg, which is a tool that allows you to create an installer package from Apple’s OS X installers. The resulting installer package can be used in the following ways:

  • Installing OS X on an empty partition
  • Upgrading existing OS X installations to a newer version of the OS X

You can use createOSXinstallPkg to build an OS X installer which installs a stock copy of that version of OS X. However, you can also use createOSXinstallPkg to add your own packages to a createOSXinstallPkg-built OS X installer. This is important from my point of view because this ability allows me to add a package which can run various tasks during the first time the Mac boots following the OS upgrade’s completion, including the previously-mentioned automated Apple software update check and application of my shop’s preferred settings.

This kind of installer package is known as a firstboot installer package, and the tool that I’m using to build my firstboot package is First Boot Package Install Generator.app.

Once you have both createOSXinstallPkg and First Boot Package Install Generator.app available, here’s how you can create an OS X installer package that includes a firstboot package.


Preparing installers for use with First Boot Package Install Generator.app

1. Set up a folder to hold your installers.

Note: createOSXinstallPkg has an upper limit of 350 MBs of available space for added packages, though this can vary per OS X version. This is sufficient space for basic configuration, payload-free or bootstrapping packages, but it’s not a good idea to add Microsoft Office or similar large installers to this installer.

2. Create numbered directories inside that folder, with 00 being the first and proceeding on to as many as you need. For numbers less than 10, make sure to label the directory with a leading zero (For example, 06).

Screen Shot 2015 11 23 at 10 44 49 AM

3. Add one installer package to each numbered directory. The number of the directory indicates the install order, with 00 being the first.

Note: If installing more than 100 packages, be aware that this was beyond the scope of my testing. I recommend adding another leading zero where appropriate.

4. Once finished adding installers to the numbered directories, use First Boot Package Install Generator.app to generate a first boot installer package.

Creating the firstboot package using First Boot Package Install Generator.app

1. If needed, download the latest version of the First Boot Package Install Generator.app installer and install the application on your Mac.

Screen Shot 2015 11 23 at 10 43 27 AM


2. Once downloaded and installed, double-click on the First Boot Package Install Generator application. You’ll be prompted to select the directory that contains the installers you want to have installed at first boot.

Screen Shot 2015 11 23 at 10 47 32 AM


3. Once you’ve selected the folder with your installers, you’ll be prompted to name the installer package. By default, the name filled in will be First Boot Package Install, but this name can be changed as desired.

Screen Shot 2015 11 23 at 10 48 04 AM


4. Once you’ve entered a name for the installer package, you’ll be prompted for a package identifier. By default, the name filled in will be com.github.first_boot, but this name should be changed to be something unique.

Screen Shot 2015 11 23 at 10 48 24 AM


5. Once you’ve entered an identifier for the installer package, you’ll be prompted for a version number. By default, the value filled in will be 1.0, but this value can be changed as needed.

Screen Shot 2015 11 23 at 10 48 33 AM


6. You will be prompted to choose if you want to have all available Apple software updates applied before your packages are installed. Choose Yes or No as appropriate.

Screen Shot 2015 11 23 at 10 48 38 AM


7. Once the package name, package identifier, package version and software update choice have been set, First Boot Package Install Generator.app will prompt for an administrator’s username and password.

Screen Shot 2015 11 23 at 10 49 01 AM


8. Once the admin username and password are provided, First Boot Package Install Generator.app will create the installer package and prompt you when it’s finished.

Screen Shot 2015 11 23 at 10 49 34 AM


9. Click OK at the prompt and a new Finder window will open and display the newly-created first boot installer package.

Screen Shot 2015 11 23 at 10 49 57 AM


10. Once the new package has been displayed, First Boot Package Install Generator.app will automatically exit. The package is now ready for use.

Screen Shot 2015 11 23 at 10 50 10 AM


Building an OS X installer using createOSXinstallPkg

1. If needed, download the latest version of createOSXinstallPkg

2. Consult the createOSXinstallPkg documentation on how to create a new installer package that installs OS X El Capitan and includes a first boot package.

As an example of how I’m doing it, I’m running the following commands:

A. Open Terminal and navigate to the createOSXinstallPkg application directory

cd /path/to/createOSXinstallPkg

B. Create an El Capitan installer with the following options:

  • Include one installer package named El Capitan First Boot Package Install.pkg
  • Set the El Capitan installer package’s name to be El Capitan 10.11.1 Installer.pkg
sudo ./createOSXinstallPkg --source /path/to/Applications/Install\ OS\ X\ El\ Capitan.app --pkg /path/to/El\ Capitan\ First\ Boot\ Package\ Install.pkg --output /path/to/El\ Capitan\ 10.11.1\ Installer.pkg

Here’s what the output of the example process above looks like:

3. Once you have your OS X installer built, the next steps are to upload the createOSXinstallPkg-built OS X installer package to Casper and build your policies.

Installing OS X via Casper and Self Service


On Casper’s end, I have three policies that work together to run the OS upgrade process in Self Service. The first two policies have manual triggers:


cache-elcapitan-installer goes with a policy named Cache El Capitan Installer which caches the createOSXInstallPkg-built El Capitan installer on the Mac in question.

Screen Shot 2015 11 23 at 8 01 03 AM

Screen Shot 2015 11 23 at 8 01 06 AM


run-elcapitan-installer goes with a policy named Install El Capitan Installer that installs the cached createOSXInstallPkg-built El Capitan installer

Screen Shot 2015 11 23 at 8 03 39 AM

Screen Shot 2015 11 23 at 8 02 28 AM


The third policy is named El Capitan Upgrade, which runs a script and is the only policy of the three which is visible in Self Service.

Screen Shot 2015 11 23 at 8 08 06 AM

Screen Shot 2015 11 23 at 8 07 39 AM

Screen Shot 2015 11 23 at 8 08 00 AM

The script is available at the following location:


This script’s Parameter 4 and Parameter 5 correspond to the two following values:

  • $4 – The amount of free space you want to require on the boot drive before the OS upgrade can proceed.
  • $5 – the version number of the OS that is being upgraded to. For example, 10.11.

The reason I wrote a script to manage the OS upgrade process, as opposed to just installing the OS X installer package, is that I wanted to accomplish several things, but still ensure my users only had to deal with clicking the Install OS X button in Self Service.


  • Make sure the Mac has enough free space available for an OS upgrade, plus a little extra for insurance.
  • Make sure that encrypted Macs were able to stop at the OS login window (to ensure that the post-upgrade processes I included would run normally.)
  • Do everything possible to make sure that the OS installer could be run successfully.

Goal 1

I’ve set a minimum amount of free space available on the Mac being upgraded, which on my Casper server is configured to be 40 GBs (this is defined by the $4 parameter for the script.) This allows for the 8.8 GBs of free space needed as a bare minimum for OS X El Capitan’s system requirements, the 6 GBs of space taken up by the createOSXinstallPkg-built OS X installer package, then a generous safety margin.

To enforce this, the script checks the Mac being upgraded for the actual amount of free space available and compares it against the value which I’ve set as the minimum amount of free space available. The part of the script that handles this is linked below:


If a Mac does not have the specified amount of free space, a message appears to let them know that they need to have X amount of space to install the OS using Self Service and they have an amount of free space which is less than X. The part of the script that handles this is linked below:


Screen Shot 2015 08 24 at 2 11 12 PM

If they do have sufficient space available, a note is made in the log and and the script proceeds. The part of the script that handles this is linked below:



Goal 2

To help make sure that both encrypted and not-encrypted Macs will stop at the OS login window for the running of the post-upgrade process, the script will check to see if the Mac is encrypted or isn’t. If it is, a setting is added to /Library/Preferences/com.apple.loginwindow.plist to disable FileVault 2’s automatic login. The part of the script that handles this is linked below:


As part of my post-upgrade process, I have a script that re-enables FileVault 2’s automatic login.


Goal 3

Once the script has gotten past the check for free space and the encryption check, a message appears to let the user know that the installer is downloading and that the Mac will automatically restart to begin the OS upgrade process. 

Screen Shot 2015 08 24 at 2 35 40 PM

The parts of the script that handles these functions are linked below:




At that point, it downloads and caches the installer using the cache-elcapitan-installer policy. This is to ensure that all the parts of the OS installer downloaded properly before proceeding with the installation process. The part of the script that handles this is linked below:



Once the cache-elcapitan-installer policy has completed, the run-elcapitan-installer policy runs and installs the cached installer. If the cached installer isn’t found, the policy fails but otherwise won’t cause problems. The part of the script that handles this is linked below:



Once the run-elcapitan-installer policy completes, then the script triggers a restart. The part of the script that handles this is linked below:



Once the Mac reboots, it will automatically proceed to upgrade the OS using the createOSXinstallPkg-built OS X installer.

Screen Shot 2015 11 24 at 2 53 53 PM

Once the upgrade completes, the firstboot package’s process will be triggered and run the post-upgrade process.

Screen Shot 2015 11 24 at 3 00 18 PM

  1. November 23, 2015 at 7:55 pm

    Very nice post! Personally, i like putting a payload-free pkg in my First Boot Package, calling a policy with a custom trigger from the postinstall-script, to take care of post-upgrade tasks. This way i don’t have to keep rebuilding the First Boot Package and the createOSXinstallPkg when there is a change, instead i can adjust it directly in the policy. One can also get around the 350MB limitation with this if that’s a problem for anyone.

  2. Randy
    December 1, 2015 at 10:27 pm

    This is great, Rich! Thank you so much. How would you go about adding your 10.11 first_boot.sh and LaunchDaemon into the equation here? It doesn’t appear to work when packaging as a .pkg through Composer and adding a DMG to folder 00 doesn’t seem to do it either. Thoughts?

  3. Thijs
    December 9, 2015 at 9:15 am

    Very Nice Rich! Thanks a lot!

  4. Jason
    December 10, 2015 at 7:32 pm

    I like that the self service script checks for available space and exists if there isn’t enough.

    Have you considered adding one that checks for either battery percentage or if the laptop is plugged into AC? Or do you find that check isn’t necessary?

  5. Thijs
    January 20, 2016 at 2:08 pm

    To make this build, run it on a 10.10 Yosemite machine! otherwise it will fail at reboot “/OS X Install Data is not a directory”

  6. pg
    February 5, 2016 at 7:10 pm

    Thanks, Rich!

  7. Jason
    March 29, 2016 at 12:52 pm

    Thanks for documenting this process. It’s been working well for us.

    One improvement I am interested is concerning how Self Service appears front and center after the upgrade is complete. And for a brief time, it still displays the “El Capitan Upgrade” until a recon and a refresh of Self Service takes place. Is it possible to close the Self Service application by way of the self_service_elcapitan_os_install.sh script and before the reboot is issued on line 47?

    • Mack
      March 30, 2016 at 11:34 pm

      I believe the “shutdown -r now” command was causing the script to terminate abruptly. Changed to “shutdown -r +1” and it seems to give the script and policy ample time to complete. After the upgrade the “El Capitan Upgrade” entry is removed from self-service. It also lets the “El Capitan Upgrade” policy exit properly and the policy logs are recorded.

  8. Lenny
    September 27, 2016 at 3:46 pm

    Hey rich! Very nice. Thank you!

    Is it possible to add authrestart to the restart process, so the user does not have to put in their password just after the first boot (before installation) when they clicked install in self service?

  9. October 13, 2016 at 6:05 pm

    I am getting this error with the upgrade to 10.12.
    Installation failed. The installer reported: installer: Error – This version of macOS 10.12 cannot be installed on this computer.
    Blessing in-place OS upgrade directory…
    Mounting install DMGs…
    Creating Reboot Script…
    It reboots to the OS that is already on there.

  1. No trackbacks yet.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: