Building MacBooks with Jamf Setup Manager

In the last of this series of posts about Jamf Setup Manager, I discuss how we use it to provision MacBooks. This is our primary use case for JSM. Read the first post to learn more about our decision to use it as our preferred tool for provisioning Macs.

Design Goals

When considering how to replace our DEPNotify-based process for provisioning MacBooks, we had the following goals for our new process:

  • It should perform all tasks in the DEPNotify process. (This did not mean that tasks should be performed in the same way, or in the same order. Simply that at the end, the same software should be installed.)
  • It should work either on-premise or remotely, driven by technicians or end-users. The existing process only worked on-premise.
  • It should work on Ethernet or Wi-Fi. Ethernet provides some efficiencies, like Auto Advance, and a more stable network connection, but Wi-Fi should work too, especially remotely.
  • Because an end-user may run this new process remotely, the process should run faster than the existing one.
  • It must eliminate the need for a help desk technician to log in as an admin account during the process for the process to work remotely with end-users.
  • End-users should not be created with temporary passwords. In our DEPNotify process, a user account was created with a temporary password. Only later did the user sync their password with our directory using the Kerberos SSO Extension.
  • As we are in the process of converting our user accounts to standard users (non-admin), creating accounts with standard permissions needed to be supported.

Before we could design a new process, we mapped out the existing process and noted any dependencies. That way we could determine where the order of operations was fixed, and where it was flexible.

In the end, we succeeded on most of the goals. My only area of dissatisfaction is that I wish a remote user going through this process could log in and start working sooner.

Bootstrapping

Because anyone can run this process, we do not require DFU mode restores of IPSW files to kick it off.

To bootstrap this provisioning process, we boot up straight out of the box if it’s shipped from Apple, or we use Erase All Contents and Settings/MDM wipe command, if it’s an existing Mac in our fleet.

Enrollment

Once again, we want to take advantage of Automated Device Enrollment and Auto Advance, so these MacBooks are in Apple Business Manager and are assigned to our production Jamf Pro Cloud instance.

In Jamf Pro, the MacBooks are scoped to a PreStage Enrollment called MacBooks – Jamf Setup Manager. It has the following characteristics:

  • The MDM profile is mandatory and cannot be removed.
  • Activation Lock is disabled.
  • Auto Advance is enabled.
  • Software Update to a recent macOS version is required for enrollment. (We operate a two-week delay in requiring new macOS versions for acceptance testing.)
  • All panels in Setup Assistant are disabled except for Touch ID.
  • A managed local administrator account is created. (This will be deleted later after a Jamf Management Framework LAPS account is created.)
  • A configuration profile named Jamf Setup Manager – MacBooks is assigned.
  • An enrollment package containing branded images is assigned.

Smart Group

Computers enrolled in the above PreStage are added to a smart group called Enrolled by MacBooks – Jamf Setup Manager.

Provisioning

A Jamf Pro policy is triggered by the enrollmentComplete trigger. It is scoped to the above smart group. The first payload is a short script. This script:

  1. Queries the Jamf API for the computer’s asset tag
  2. Programmatically builds the userEntry dictionary for Jamf Setup Manager to collect and validate the asset tag. It uses the retrieved asset tag as the default value.
  3. Stores the userEntry dictionary in /Library/Preferences/com.jamf.setupmanager.plist1
  4. Waits for the Jamf Setup Manager configuration profile to be installed.
  5. Waits for Setup Assistant to exit.

This script a) maintains a feature we had in our existing process; and b) works around a shortcoming of Jamf Pro: $ASSET_TAG is not available as a variable in computer configuration profiles.2 (It is available in mobile device configuration profiles.) We use a custom asset tag as the basis of our asset tracking and computer naming. A unique five-digit number is tagged to each of our computers. We store this number in the Asset Tag field in the Jamf inventory record. It’s semi-permanent, in that the value is retained when a computer is wiped and re-enrolled. By recalling the value and making it default in Jamf Setup Manager’s user entry form, we get to validate it against the physical asset or enter it if it’s missing.

The second payload in this policy installs Jamf Setup Manager.

Jamf Setup Manager

Jamf Setup Manager is configured as follows:

  • Icon is a company logo, installed locally during enrollment.
  • The title and message convey that this is a standard Mac install.
  • Background is the default branded wallpaper.
  • Accent color is our corporate color.
  • Runs at loginwindow
  • Final action is to shut down, and the final countdown is 30 seconds.
  • As indicated above, the user entry only prompts for an asset tag. The validation rule ensures the value is an integer between 10000 and 99999.
  • The computer name template is based on the asset tag and uses the appropriate substitution variable.
  • Help is configured with a message directing folks to call our Help Desk if they have problems or questions.
  • Enrollment Actions (source material linked where possible):
    • Power management – Jamf policy – A script that runs pmset commands.
    • Default Time Zone and City – Jamf policy – With Auto Advance, the time zone step in Setup Assistant is bypassed, so we run a script instead. This policy’s scoping is such that it only runs on-premise. (Remote users set their own time zone.)
    • Time Server – Jamf policy – Sets our on-premise time server. (On the Internet, we resolve this DNS name to time.apple.com.)
    • Defines YubiKeys and keyboards – Jamf policy – an existing policy to define YubiKeys and keyboards and suppress Keyboard Setup Assistant as all our Mac users have YubiKeys for multi-factor authentication.
    • swiftDialog – Jamf policy – We build interactive user dialogs (including one immediately after the first login) with this tool.
    • Rosetta 2 – Jamf policy – A script to ensure that Rosetta installs before a user attempts to install any Self Service that requires it.
    • Check Point Identity Agent – Jamf policy – A custom script that installs this agent. CPIA authenticates users to our on-premise firewalls.
    • Google Chrome – Jamf policy – Reusing an existing Installomator-based policy to install this browser.
    • Zoom – Jamf policy – Reusing an existing Installomator-based policy to install our standard video conferencing platform.
    • Here the process waits for user data entry. It’s not strictly required, but I want to set the computer name before the security agents installed next report the name to their cloud services.
    • Wait for /Library/Managed Preferences/com.crowdstrike.falcon.plist – Wait for this file to exist as proof that the CrowdStrike Falcon configuration profile has been installed.
    • Cisco Secure Client – Jamf policy – VPN, Umbrella (DNS only), and DART modules are installed.
    • CrowdStrike Falcon N-2 – Jamf policy
    • Jamf Connect – Jamf policy – Normally, installing Jamf Connect at the login window will restart the loginwindow process. However, I am creating a false “Setup Assistant” process to prevent this.3
    • “Prepare for first user” – Jamf policy – Makes changes to the user template, then creates a launch daemon and script that guides users through their first time logging in.

After Jamf Setup Manager shuts down the Mac, it can be restarted when the end user is ready to log in.

First Login with Jamf Connect

Jamf Connect handles the first login. It authenticates the user against our IdP, creates an account with standard user privileges, and enables FileVault. After they log in, the user is prompted to set up Touch ID.

First User Launch Daemon

The First User Launch Daemon has likely launched before the user logs in. The script it runs has the following order of operations:

  1. Turns off the recurring Jamf policy check-in
  2. Waits for the Dock process (signaling that a user has logged in)
  3. Waits for the Setup Assistant process to end
  4. Deletes the PreStage enrollment user
  5. Opens a small swiftDialog window to show the progress of initial setup steps
  6. Checks for connectivity to Jamf Pro
  7. Sets up a default set of Dock icons including Google Chrome, Zoom, and Self Service
  8. Assigns the Mac in Jamf Pro to the logged-in user
  9. Waits for the enrollment configuration for the Netskope web security client
  10. Installs the Netskope web security client
  11. Sets the picture for the Jamf LAPS account
  12. Prompts the user to enter their password so that the Jamf LAPS account is added to FileVault. (Users are allowed to opt-out.)
  13. Tells the user that the setup is complete and closes swiftDialog
  14. Takes an inventory of the Mac
  15. Runs a Jamf policy check-in
    • This will install missing miscellaneous items such as Ivanti EM (for inventory only), our patching scripts, Particulars, our policy banner, etc. Apple’s stock apps are uninstalled here.
  16. Turns on the recurring Jamf policy check-in
  17. Deletes this launch daemon and script

The user now has a fully-baked Mac and can go to work. For further customization, they can install additional apps using Self Service.

Why These Tools Meet Our Goals

It’s important to call out why the process I’ve described meets the goals we started with.

  • Jamf Setup Manager can run a variety of actions. Perhaps the most important for converting from DEPNotify is running Jamf Pro policies. The heart of many DEPNotify scripts is an array of policies run in a loop.
  • Jamf Setup Manager executes enrollment actions before the user entry is submitted, speeding up the operation vs tools that have to wait for data entry before starting their actions.
  • Jamf Setup Manager runs before the first login so temporary technician accounts are unnecessary.
  • Jamf Connect creates either standard or admin local accounts based on authenticated credentials. This eliminates temporary passwords set by technicians or scripts.
  • Some tasks have to wait until a user is assigned, notably installing Netskope. We choose to assign the user in custom code after the first user logs in. That custom code also lets us silently install some components after we told the user that the computer was ready. (We originally had kept some more policies out of JSM to install later, but users are too fast and we moved Rosetta and Identity Agent in JSM.)

Afterword

In this series, I’ve tried to explore Jamf Setup Manager, how it can be used in different scenarios, and to push what can be done with it. JSM has streamlined our provisioning processes and helped us meet the goals I set out above. The recent release of version 1.2 will enable more workflows in more organizations. It’s a good time to switch to Jamf Setup Manager!


  1. Normally, Jamf Setup Manager is entirely configured by a configuration profile, the results of which are stored locally in /Library/Managed Preferences/com.jamf.setupmanager.plist. Jamf Setup Manager uses the UserDefaults API to read the configuration. While managed preferences have precedence, that API will look in /Library/Preferences as well. ↩︎
  2. I’d be delighted to remove this workaround if the variable was made available. ↩︎
  3. I’d be equally happy to remove this hack. See https://ideas.jamf.com/ideas/ID-I-432 and https://github.com/jamf/Setup-Manager/issues/56 for requests regarding a silent install of Jamf Connect. ↩︎

2 responses to “Building MacBooks with Jamf Setup Manager”

  1. thanks for the write-up. Wondering what you do about enabling location services?

    Like

    1. We took a look at Location Services after I saw your comment. Ultimately, the security team decided we would not enable Location Services by default without a business reason. Users can enable it when they are promoted to admin, or call our help desk for assistance.

      Like

Leave a reply to Gareth Cancel reply