Menu Close

Setup Your Mac (1.14.0): Under-the-hood

An under-the-hood look at SYM 1.14.0 for Jamf Pro Admins prior to production implementation

Setup Your Mac (1.14.0): Under-the-hood
Setup Your Mac (1.14.0): Under-the-hood

Introduction

Apple’s Automated Device Enrollment helps streamline Mobile Device Management (MDM) enrollment and device Supervision during activation, enabling IT to manage enterprise devices with “zero touch.”

Setup Your Mac aims to simplify initial device configuration by leveraging swiftDialog and Jamf Pro Policy Custom Events to allow end-users to self-complete Mac setup post-enrollment.

Setup Your Mac (1.14.0) screencast (01:51; no audio; edited for time)

Jump-start

MacAdmins can jump-start their users’ on-boarding experience with SYM-Helper, a stand-alone macOS app to help MacAdmins more easily deploy Setup Your Mac.

SYM-Helper is a stand-alone macOS app to help MacAdmins more easily deploy Setup Your Mac
SYM-Helper is a stand-alone macOS app to help MacAdmins more easily deploy Setup Your Mac

Under-the-hood

This post presumes you’ve generated a customized Setup-Your-Mac.bash script with the latest version of SYM-Helper as detailed in the SYM-Helper post.

1. Dry-run

Complete the following steps on a virtual machine or non-production physical Mac.

  1. Open the macOS Terminal.
  2. Download the latest production version of Setup Your Mac using the following command. (The script will be saved to your Downloads folder as Setup-Your-Mac-via-Dialog-reference.bash):
curl -o ~/Downloads/Setup-Your-Mac-via-Dialog-reference.bash https://raw.githubusercontent.com/setup-your-mac/Setup-Your-Mac/main/Setup-Your-Mac-via-Dialog.bash
  1. Execute the Setup Your Mac script using the following command:
bash ~/Downloads/Setup-Your-Mac-via-Dialog-reference.bash
  1. Observe the output (i.e., PRE-FLIGHT CHECK: This script must be run as root; exiting.)
touch: /var/log/org.churchofjesuschrist.log: Permission denied
tee: /var/log/org.churchofjesuschrist.log: Permission denied
2024-02-03 04:59:21 - 

###
# Setup Your Mac (1.14.0)
# https://snelson.us/sym
###

tee: /var/log/org.churchofjesuschrist.log: Permission denied
2024-02-03 04:59:21 - PRE-FLIGHT CHECK: Initiating …
tee: /var/log/org.churchofjesuschrist.log: Permission denied
2024-02-03 04:59:21 - PRE-FLIGHT CHECK: This script must be run as root; exiting.
  1. Execute the Setup Your Mac script with elevated privileges via sudo !!:
sudo !!
sudo bash ~/Downloads/Setup-Your-Mac-via-Dialog-reference.bash
Password:
2024-02-03 06:47:07 - 

###
# Setup Your Mac (1.14.0)
# https://snelson.us/sym
###

2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Initiating …
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Setup Assistant is no longer running; proceeding …
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Finder & Dock are running; proceeding …
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Check for Logged-in System Accounts …
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Current Logged-in User: dan
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Current Logged-in User First Name: Dan
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Current Logged-in User ID: 501
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: 'requiredMinimumBuild' has been set to disabled; skipping OS validation.
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: macOS 14.3 (23D56) installed
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Caffeinating this script (PID: 804)
2024-02-03 06:47:07 - QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 452 # # #
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: swiftDialog not found. Installing...
2024-02-03 06:47:07 - PRE-FLIGHT CHECK: Installing swiftDialog...
installer: Package name is 
installer: Upgrading at base path /
installer: The upgrade was successful.
2024-02-03 06:47:14 - PRE-FLIGHT CHECK: swiftDialog version 2.4.0.4750 installed; proceeding...
2024-02-03 06:47:14 - PRE-FLIGHT CHECK: Complete
2024-02-03 06:47:15 - WELCOME DIALOG: brandingBanner is available, using it
2024-02-03 06:47:15 - WELCOME DIALOG: Auto-caching hosted 'liquid-marbling-paint-texture-background-fluid-painting-abstract-texture-intensive-color-mix-wallpaper_1258-101465.jpg' …
2024-02-03 06:47:16.234 defaults[994:7760] 
The domain/default pair of (/Library/Preferences/com.jamfsoftware.jamf, self_service_app_path) does not exist
/..namedfork/rsrc: No such file or directory
2024-02-03 06:47:16 - 

###
# VERBOSE DEBUG MODE | Dialog: v2.4.0.4750 • Setup Your Mac: v1.14.0
###

2024-02-03 06:47:16 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2862 # # #
2024-02-03 06:47:16 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2867 # # #
2024-02-03 06:47:16 - WELCOME DIALOG: Disk Space: 24.8 GB free (56.29% available)
2024-02-03 06:47:16 - WELCOME DIALOG: Starting checkNetworkQualityConfigurations …
2024-02-03 06:47:16 - WELCOME DIALOG: Write 'welcomeJSON' to /var/tmp/welcomeJSONFile.6TQ …
2024-02-03 06:47:16 - WELCOME DIALOG: Display Welcome dialog 'infobox' animation …
2024-02-03 06:47:16 - WELCOME DIALOG: Display 'Welcome' dialog …
2024-02-03 06:47:22 - WELCOME DIALOG: dan clicked Quit at Welcome dialog
2024-02-03 06:47:22 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2687 # # #
2024-02-03 06:47:22 - QUIT SCRIPT: Exiting …
2024-02-03 06:47:22 - QUIT SCRIPT: De-caffeinate …
2024-02-03 06:47:22 - Attempting to terminate the 'caffeinate' process …
2024-02-03 06:47:22 - (Termination message indicates success.)
/Users/dan/Downloads/Setup-Your-Mac-via-Dialog-reference.bash: line 2197:   882 Terminated: 15          caffeinate -dimsu -w $symPID
2024-02-03 06:47:22 - QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled
2024-02-03 06:47:22 - QUIT SCRIPT: Removing /var/tmp/dialogCommandFileWelcome.iIw …
2024-02-03 06:47:22 - QUIT SCRIPT: Removing /var/tmp/welcomeJSONFile.6TQ …
2024-02-03 06:47:22 - QUIT SCRIPT: Removing default dialog file …
2024-02-03 06:47:22 - COMPLETION ACTION: Removing /var/tmp/liquid-marbling-paint-texture-background-fluid-painting-abstract-texture-intensive-color-mix-wallpaper_1258-101465.jpg …
2024-02-03 06:47:22 - COMPLETION ACTION: Removing /var/tmp/overlayicon.icns …
dan@Dans-143-SYM ~ % 2024-02-03 06:47:47 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2405 # # #
/Users/dan/Downloads/Setup-Your-Mac-via-Dialog-reference.bash: line 187:  1038 Terminated: 15          welcomeDialogInfoboxAnimation "$myPID"
2024-02-03 06:47:47 - WELCOME DIALOG: Completed networkQualityTest …
2024-02-03 06:47:47 - WELCOME DIALOG: 480.64 (Mbps)
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration One Estimated Seconds: 254
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration One Estimate: 0h:4m:14s
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration Two Estimated Seconds: 436
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration Two Estimate: 0h:7m:16s
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration Three Estimated Seconds: 799
2024-02-03 06:47:47 - WELCOME DIALOG: Configuration Three Estimate: 0h:13m:19s
2024-02-03 06:47:47 - WELCOME DIALOG: Network Quality Test: Started: 2024-02-03 06:47:16.640, Ended: 2024-02-03 06:47:47.344; Download: 480.64 Mbps, Responsiveness: 781.4951171875
  1. Please wait while:
    • At least version 2.4.0.4750 of swiftDialog is automatically installed
    • The personalized “Welcome” dialog is displayed
    • The Dynamic Download Estimates are calculated
Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to userInput
Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to userInput
  1. After reviewing and interacting with the input fields, click Quit.
  2. Observe the output in Terminal (i.e., WELCOME DIALOG: dan clicked Quit at Welcome dialog):
2024-02-03 06:22:14 - WELCOME DIALOG: dan clicked Quit at Welcome dialog
2024-02-03 06:22:14 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2639 # # #
2024-02-03 06:22:14 - QUIT SCRIPT: Exiting …
2024-02-03 06:22:14 - QUIT SCRIPT: De-caffeinate …
2024-02-03 06:22:14 - Attempting to terminate the 'caffeinate' process …
2024-02-03 06:22:14 - (Termination message indicates success.)
/Users/dan/Downloads/Setup-Your-Mac-via-Dialog-reference.bash: line 2149:   922 Terminated: 15          caffeinate -dimsu -w $symPID
2024-02-03 06:22:14 - QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled
2024-02-03 06:22:14 - QUIT SCRIPT: Removing /var/tmp/dialogCommandFileWelcome.zCq …
2024-02-03 06:22:14 - QUIT SCRIPT: Removing /var/tmp/welcomeJSONFile.Ivd …
2024-02-03 06:22:14 - QUIT SCRIPT: Removing default dialog file …
2024-02-03 06:22:14 - COMPLETION ACTION: Removing /var/tmp/green-abstract-geometric-wallpaper_52683-29623.jpg …
2024-02-03 06:22:14 - COMPLETION ACTION: Removing /var/tmp/overlayicon.icns …
  1. Using Terminal, re-execute the Setup Your Mac script with elevated privileges by pressing the Up Arrow once and then pressing Return.
  2. Populate the input fields and modify the drop-down menus, then click Continue:
Setup Your Mac (1.14.0) "Welcome" dialog with input fields populated, drop-down menus selected and Dynamic Download Estimates displayed
Setup Your Mac (1.14.0) “Welcome” dialog with input fields populated, drop-down menus selected and Dynamic Download Estimates displayed
  1. Wait while Setup Your Mac runs in Verbose Debug Mode (displayed in the bottom, left-hand corner) and observe the expected failures (since Custom Triggers for the Jamf Pro policies have not yet been configured):
Setup Your Mac (1.14.0) "Verbose Debug Mode" with expected failures
Setup Your Mac (1.14.0) “Verbose Debug Mode” with expected failures
Setup Your Mac (1.14.0) displaying expected failures
Setup Your Mac (1.14.0) displaying expected failures
Setup Your Mac (1.14.0) "Failure" dialog with end-user instructions
Setup Your Mac (1.14.0) “Failure” dialog with end-user instructions
Setup Your Mac (1.14.0) "Debug Mode" completionActionOption
Setup Your Mac (1.14.0) “Debug Mode” completionActionOption
  1. After clicking the default buttons in each of the above dialog boxes, review the client-side Setup Your Mac log file via Console:
open /var/log/org.churchofjesuschrist.log

Note: When debugMode (Parameter 5) is set to true or verbose, Jamf Pro policies do not execute (which is why the validation checks fail); review the client-side log for the following:

SETUP YOUR MAC DIALOG: Confirm Policy Execution: DEBUG MODE: Skipping 'run_jamf_trigger
2. Dialogs
“Welcome”

Video

Organizations which do not need to capture any user input can display a video by specifying video for welcomeDialog (Parameter 6).

Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to video
Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to video
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# "Welcome" Video Settings and Features
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

welcomeVideo="--title \"$welcomeTitle\" \
--videocaption \"$welcomeCaption\" \
--video \"$welcomeVideoID\" \
--infotext \"$scriptVersion\" \
--button1text \"Continue …\" \
--autoplay \
--moveable \
--ontop \
--width '800' \
--height '600' \
--commandfile \"$welcomeCommandFile\" "

Note: When welcomeDialog (Parameter 6) is set to video, the “catch-all” policyJSON will be used in the main “Setup Your Mac” dialog.

* ) # Catch-all (i.e., used when `welcomeDialog` is set to `video`, `messageOnly` or `false`)

    overlayoverride=""
    policyJSON='
    {
        "steps": [
            {

Message Only

Specify messageOnly for welcomeDialog (Parameter 6), which displays for the number of seconds specified in timer.

Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to messageOnly
Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to messageOnly

Note No. 1: When welcomeDialog (Parameter 6) is set to messageOnly, the “catch-all” policyJSON will be used in the main “Setup Your Mac” dialog.

* ) # Catch-all (i.e., used when `welcomeDialog` is set to `video`, `messageOnly` or `false`)

overlayoverride=""
policyJSON='
{
    "steps": [
        {

Note No. 2: Administrators will most likely want to adjust the height of welcomeJSON.

elif [[ "${welcomeDialog}" == "messageOnly" ]]; then

    outputLineNumberInVerboseDebugMode

    updateScriptLog "WELCOME DIALOG: Displaying ${welcomeDialog} …"

    # Construct `welcomeJSON`, sans `textfield` and `selectitems`
    welcomeJSON='
    {
        "commandfile" : "'"${welcomeCommandFile}"'",
        "bannerimage" : "'"${welcomeBannerImage}"'",
        "bannertext" : "'"${welcomeBannerText}"'",
        "title" : "'"${welcomeTitle}"'",
        "message" : "'"${welcomeMessage}"'",
        "icon" : "'"${welcomeIcon}"'",
        "infobox" : "",
        "iconsize" : "198.0",
        "button1text" : "Continue",
        "timer" : "60",
        "infotext" : "'"${scriptVersion}"'",
        "blurscreen" : "true",
        "ontop" : "true",
        "titlefont" : "shadow=true, size=36, colour=#FFFDF4",
        "messagefont" : "size=14",
        "height" : "800"
    }
    '

User Input

Specify userInput for welcomeDialog (Parameter 6) to capture user input.

Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to userInput
Setup Your Mac (1.14.0) welcomeDialog (Parameter 6) set to userInput

Fields

The input fields in the “Welcome” dialog are enabled via SYM-Helper > Settings > Prompt For … or by manually editing the following variables to true (and disabled by setting the same variables to false):

The input fields in the "Welcome" dialog are enabled via SYM-Helper > Settings > Prompt For …
  • promptForUsername
  • promptForRealName
  • promptForEmail
  • promptForComputerName
  • promptForAssetTag
  • promptForRoom
  • promptForBuilding
  • promptForDepartment
  • promptForPosition
  • promptForConfiguration
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Welcome Message User Input Customization Choices (thanks, @rougegoat!)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# [SYM-Helper] These control which user input boxes are added to the first page of Setup Your Mac. If you do not want to ask about a value, set it to any other value
promptForUsername="true"
prefillUsername="true"          # prefills the currently logged in user's username
promptForRealName="true"
prefillRealname="true"          # prefills the currently logged in user's fullname
promptForEmail="true"
promptForComputerName="true"
promptForAssetTag="true"
promptForRoom="true"
promptForBuilding="true"
promptForDepartment="true"
promptForPosition="true"        # When set to true dynamically prompts the user to select from a list of positions or manually enter one at the welcomeDialog, see "positionListRaw" to define the selection / entry type
promptForConfiguration="true"   # Removes the Configuration dropdown entirely and uses the "Catch-all (i.e., used when `welcomeDialog` is set to `video` or `false`)" or presetConfiguration policyJSON

The listing of buildings or a departments can be “fetched” via SYM-Helper > Settings > Buildings / Departments > Fetch , or by manually entering an unsorted, comma-separated list (with possible duplication):

# [SYM-Helper] An unsorted, comma-separated list of buildings (with possible duplication). If empty, this will be hidden from the user info prompt
buildingsListRaw="Benson (Ezra Taft) Building,Brimhall (George H.) Building,BYU Conference Center,Centennial Carillon Tower,Chemicals Management Building,Clark (Herald R.) Building,Clark (J. Reuben) Building,Clyde (W.W.) Engineering Building,Crabtree (Roland A.) Technology Building,Ellsworth (Leo B.) Building,Engineering Building,Eyring (Carl F.) Science Center,Grant (Heber J.) Building,Harman (Caroline Hemenway) Building,Harris (Franklin S.) Fine Arts Center,Johnson (Doran) House East,Kimball (Spencer W.) Tower,Knight (Jesse) Building,Lee (Harold B.) Library,Life Sciences Building,Life Sciences Greenhouses,Maeser (Karl G.) Building,Martin (Thomas L.) Building,McKay (David O.) Building,Nicholes (Joseph K.) Building,Smith (Joseph F.) Building,Smith (Joseph) Building,Snell (William H.) Building,Talmage (James E.) Math Sciences/Computer Building,Tanner (N. Eldon) Building,Taylor (John) Building,Wells (Daniel H.) Building"

# A sorted, unique, JSON-compatible list of buildings
buildingsList=$( echo "${buildingsListRaw}" | tr ',' '\n' | sort -f | uniq | sed -e 's/^/\"/' -e 's/$/\",/' -e '$ s/.$//' )

# [SYM-Helper] An unsorted, comma-separated list of departments (with possible duplication). If empty, this will be hidden from the user info prompt
departmentListRaw="Asset Management,Sales,Australia Area Office,Purchasing / Sourcing,Board of Directors,Strategic Initiatives & Programs,Operations,Business Development,Marketing,Creative Services,Customer Service / Customer Experience,Risk Management,Engineering,Finance / Accounting,Sales,General Management,Human Resources,Marketing,Investor Relations,Legal,Marketing,Sales,Product Management,Production,Corporate Communications,Information Technology / Technology,Quality Assurance,Project Management Office,Sales,Technology"

# A sorted, unique, JSON-compatible list of departments
departmentList=$( echo "${departmentListRaw}" | tr ',' '\n' | sort -f | uniq | sed -e 's/^/\"/' -e 's/$/\",/' -e '$ s/.$//' )

Branding

Custom branding and support information for both the “Welcome” and the “Setup Your Mac” dialogs are controlled via SYM-Helper > Settings or as displayed below:

# [SYM-Helper] Branding overrides
brandingBanner="https://img.freepik.com/free-vector/green-abstract-geometric-wallpaper_52683-29623.jpg" # Image by pikisuperstar on Freepik
brandingBannerDisplayText="true"
brandingIconLight="https://cdn-icons-png.flaticon.com/512/979/979585.png"
brandingIconDark="https://cdn-icons-png.flaticon.com/512/740/740878.png"

# [SYM-Helper] IT Support Variables - Use these if the default text is fine but you want your org's info inserted instead
supportTeamName="Support Team Name"
supportTeamPhone="+1 (801) 555-1212"
supportTeamEmail="support@domain.com"
supportTeamWebsite="support.domain.com"
supportTeamHyperlink="[${supportTeamWebsite}](https://${supportTeamWebsite})"
supportKB="KB8675309"
supportTeamErrorKB="[${supportKB}](https://servicenow.company.com/support?id=kb_article_view&sysparm_article=${supportKB}#Failures)"

Processing

The actual processing of user input is handled later in the script and will most likely require additional customization, which should be thoroughly tested before being deployed in production (i.e., see code comments UNTESTED, UNSUPPORTED "YOYO" EXAMPLE):

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Display Welcome dialog
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ "${welcomeDialog}" == "video" ]]; then

    updateScriptLog "WELCOME DIALOG: Displaying ${welcomeVideoID} …"
    eval "${dialogBinary} --args ${welcomeVideo}"

    outputLineNumberInVerboseDebugMode
    if [[ -n "${presetConfiguration}" ]]; then
        symConfiguration="${presetConfiguration}"
    else
        symConfiguration="Catch-all (video)"
    fi
    updateScriptLog "WELCOME DIALOG: Using ${symConfiguration} Configuration …"
    policyJSONConfiguration

    eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
    dialogUpdateSetupYourMac "activate:"
    if [[ -n "${overlayoverride}" ]]; then
        dialogUpdateSetupYourMac "overlayicon: ${overlayoverride}"
    fi

elif [[ "${welcomeDialog}" == "messageOnly" ]]; then

    outputLineNumberInVerboseDebugMode

    updateScriptLog "WELCOME DIALOG: Displaying ${welcomeDialog} …"

    # Construct `welcomeJSON`, sans `textfield` and `selectitems`
    welcomeJSON='
    {
        "commandfile" : "'"${welcomeCommandFile}"'",
        "bannerimage" : "'"${welcomeBannerImage}"'",
        "bannertext" : "'"${welcomeBannerText}"'",
        "title" : "'"${welcomeTitle}"'",
        "message" : "'"${welcomeMessage}"'",
        "icon" : "'"${welcomeIcon}"'",
        "infobox" : "",
        "iconsize" : "198.0",
        "button1text" : "Continue",
        "timer" : "60",
        "infotext" : "'"${scriptVersion}"'",
        "blurscreen" : "true",
        "ontop" : "true",
        "titlefont" : "shadow=true, size=36, colour=#FFFDF4",
        "messagefont" : "size=14",
        "height" : "800"
    }
    '

    # Write Welcome JSON to disk
    echo "$welcomeJSON" > "$welcomeJSONFile"

    # Display Welcome dialog
    eval "${dialogBinary} --jsonfile ${welcomeJSONFile} --json"

    # Set Configuration
    if [[ -n "${presetConfiguration}" ]]; then
        symConfiguration="${presetConfiguration}"
    else
        symConfiguration="Catch-all (messageOnly)"
    fi
    updateScriptLog "WELCOME DIALOG: Using ${symConfiguration} Configuration …"
    policyJSONConfiguration

    # Display main SYM dialog
    eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
    dialogUpdateSetupYourMac "activate:"
    if [[ -n "${overlayoverride}" ]]; then
        dialogUpdateSetupYourMac "overlayicon: ${overlayoverride}"
    fi

elif [[ "${welcomeDialog}" == "userInput" ]]; then

    outputLineNumberInVerboseDebugMode

    # Estimate Configuration Download Times
    if [[ "${configurationDownloadEstimation}" == "true" ]] && [[ "${promptForConfiguration}" == "true" ]]; then

        outputLineNumberInVerboseDebugMode

        calculateFreeDiskSpace "WELCOME DIALOG"

        updateScriptLog "WELCOME DIALOG: Starting checkNetworkQualityConfigurations …"
        checkNetworkQualityConfigurations &

        updateScriptLog "WELCOME DIALOG: Write 'welcomeJSON' to $welcomeJSONFile …"
        echo "$welcomeJSON" > "$welcomeJSONFile"

        # If option to lock the continue button is set to true, open welcome dialog with button 1 disabled
        if [[ "${lockContinueBeforeEstimations}" == "true" ]]; then
            
            updateScriptLog "WELCOME DIALOG: Display 'Welcome' dialog with disabled Continue Button …"
            welcomeResults=$( eval "${dialogBinary} --jsonfile ${welcomeJSONFile} --json --button1disabled" )
            
        else

            updateScriptLog "WELCOME DIALOG: Display 'Welcome' dialog …"
            welcomeResults=$( eval "${dialogBinary} --jsonfile ${welcomeJSONFile} --json" )

        fi

    else

        # Display Welcome dialog, sans estimation of Configuration download times
        updateScriptLog "WELCOME DIALOG: Skipping estimation of Configuration download times"
        
        # Write Welcome JSON to disk
        welcomeJSON=${welcomeJSON//Analyzing …/}
        echo "$welcomeJSON" > "$welcomeJSONFile"
        welcomeResults=$( eval "${dialogBinary} --jsonfile ${welcomeJSONFile} --json" )

    fi

    # Evaluate User Input
    if [[ -z "${welcomeResults}" ]]; then
        welcomeReturnCode="2"
    else
        welcomeReturnCode="0"
    fi

    case "${welcomeReturnCode}" in

        0)  # Process exit code 0 scenario here
            updateScriptLog "WELCOME DIALOG: ${loggedInUser} entered information and clicked Continue"

            ###
            # Extract the various values from the welcomeResults JSON
            ###

            computerName=$(get_json_value_welcomeDialog "$welcomeResults" "Computer Name")
            userName=$(get_json_value_welcomeDialog "$welcomeResults" "User Name")
            realName=$(get_json_value_welcomeDialog "$welcomeResults" "Full Name")
            email=$(get_json_value_welcomeDialog "$welcomeResults" "E-mail")
            assetTag=$(get_json_value_welcomeDialog "$welcomeResults" "Asset Tag")
            symConfiguration=$(get_json_value_welcomeDialog "$welcomeResults" "Configuration" "selectedValue")
            if [ -n "$presetConfiguration" ]; then symConfiguration="${presetConfiguration}"; fi
            department=$(get_json_value_welcomeDialog "$welcomeResults" "Department" "selectedValue" | grep -v "Please select your department" )
            room=$(get_json_value_welcomeDialog "$welcomeResults" "Room")
            building=$(get_json_value_welcomeDialog "$welcomeResults" "Building" "selectedValue" | grep -v "Please select your building" )
            
            if [ -n "${positionListRaw}" ]; then
                position=$(get_json_value_welcomeDialog "$welcomeResults" "Position" "selectedValue" )
            else
                position=$(get_json_value_welcomeDialog "$welcomeResults" "Position")
            fi



            ###
            # Output the various values from the welcomeResults JSON to the log file
            ###

            updateScriptLog "WELCOME DIALOG: • Computer Name: $computerName"
            updateScriptLog "WELCOME DIALOG: • User Name: $userName"
            updateScriptLog "WELCOME DIALOG: • Real Name: $realName"
            updateScriptLog "WELCOME DIALOG: • E-mail: $email"
            updateScriptLog "WELCOME DIALOG: • Asset Tag: $assetTag"
            updateScriptLog "WELCOME DIALOG: • Configuration: $symConfiguration"
            updateScriptLog "WELCOME DIALOG: • Department: $department"
            updateScriptLog "WELCOME DIALOG: • Building: $building"
            updateScriptLog "WELCOME DIALOG: • Room: $room"
            updateScriptLog "WELCOME DIALOG: • Position: $position"


            ###
            # Select `policyJSON` based on selected Configuration
            ###

            policyJSONConfiguration



            ###
            # Evaluate Various User Input
            ###

            # Computer Name
            if [[ -n "${computerName}" ]]; then

                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                updateScriptLog "WELCOME DIALOG: Set Computer Name …"
                currentComputerName=$( scutil --get ComputerName )
                currentLocalHostName=$( scutil --get LocalHostName )

                # Sets LocalHostName to a maximum of 15 characters, comprised of first eight characters of the computer's
                # serial number and the last six characters of the client's MAC address
                firstEightSerialNumber=$( system_profiler SPHardwareDataType | awk '/Serial\ Number\ \(system\)/ {print $NF}' | cut -c 1-8 )
                lastSixMAC=$( ifconfig en0 | awk '/ether/ {print $2}' | sed 's/://g' | cut -c 7-12 )
                newLocalHostName=${firstEightSerialNumber}-${lastSixMAC}

                if [[ "${debugMode}" == "true" ]] || [[ "${debugMode}" == "verbose" ]] ; then

                    updateScriptLog "WELCOME DIALOG: DEBUG MODE: Would have renamed computer from: \"${currentComputerName}\" to \"${computerName}\" "
                    updateScriptLog "WELCOME DIALOG: DEBUG MODE: Would have renamed LocalHostName from: \"${currentLocalHostName}\" to \"${newLocalHostName}\" "

                else

                    # Set the Computer Name to the user-entered value
                    scutil --set ComputerName "${computerName}"

                    # Set the LocalHostName to `newLocalHostName`
                    scutil --set LocalHostName "${newLocalHostName}"

                    # Delay required to reflect change …
                    # … side-effect is a delay in the "Setup Your Mac" dialog appearing
                    sleep 5
                    updateScriptLog "WELCOME DIALOG: Renamed computer from: \"${currentComputerName}\" to \"$( scutil --get ComputerName )\" "
                    updateScriptLog "WELCOME DIALOG: Renamed LocalHostName from: \"${currentLocalHostName}\" to \"$( scutil --get LocalHostName )\" "

                fi

            else

                updateScriptLog "WELCOME DIALOG: ${loggedInUser} did NOT specify a new computer name"
                updateScriptLog "WELCOME DIALOG: • Current Computer Name: \"$( scutil --get ComputerName )\" "
                updateScriptLog "WELCOME DIALOG: • Current Local Host Name: \"$( scutil --get LocalHostName )\" "

            fi

            # User Name
            if [[ -n "${userName}" ]]; then
                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                reconOptions+="-endUsername \"${userName}\" "
            fi

            # Asset Tag
            if [[ -n "${assetTag}" ]]; then
                reconOptions+="-assetTag \"${assetTag}\" "
            fi

            # Real Name
            if [[ -n "${realName}" ]]; then
                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                reconOptions+="-realname \"${realName}\" "
            fi
            
            # E-mail
            if [[ -n "${email}" ]]; then
                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                reconOptions+="-email \"${email}\" "
            fi
            
            # Department
            if [[ -n "${department}" ]]; then
                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                reconOptions+="-department \"${department}\" "
            fi

            # Building
            if [[ -n "${building}" ]]; then reconOptions+="-building \"${building}\" "; fi
            
            # Room
            if [[ -n "${room}" ]]; then reconOptions+="-room \"${room}\" "; fi

            # Position
            if [[ -n "${position}" ]]; then reconOptions+="-position \"${position}\" "; fi

            # Output `recon` options to log
            updateScriptLog "WELCOME DIALOG: reconOptions: ${reconOptions}"

            ###
            # Display "Setup Your Mac" dialog (and capture Process ID)
            ###

            eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
            until pgrep -q -x "Dialog"; do
                outputLineNumberInVerboseDebugMode
                updateScriptLog "WELCOME DIALOG: Waiting to display 'Setup Your Mac' dialog; pausing"
                sleep 0.5
            done
            updateScriptLog "WELCOME DIALOG: 'Setup Your Mac' dialog displayed; ensure it's the front-most app"
            runAsUser osascript -e 'tell application "Dialog" to activate'
            if [[ -n "${overlayoverride}" ]]; then
                dialogUpdateSetupYourMac "overlayicon: ${overlayoverride}"
            fi
            ;;

        2)  # Process exit code 2 scenario here
            updateScriptLog "WELCOME DIALOG: ${loggedInUser} clicked Quit at Welcome dialog"
            completionActionOption="Quit"
            quitScript "1"
            ;;

        3)  # Process exit code 3 scenario here
            updateScriptLog "WELCOME DIALOG: ${loggedInUser} clicked infobutton"
            osascript -e "set Volume 3"
            afplay /System/Library/Sounds/Glass.aiff
            ;;

        4)  # Process exit code 4 scenario here
            updateScriptLog "WELCOME DIALOG: ${loggedInUser} allowed timer to expire"
            quitScript "1"
            ;;

        *)  # Catch all processing
            updateScriptLog "WELCOME DIALOG: Something else happened; Exit code: ${welcomeReturnCode}"
            quitScript "1"
            ;;

    esac

else

    ###
    # Select "Catch-all" policyJSON 
    ###

    outputLineNumberInVerboseDebugMode
    if [[ -n "$presetConfiguration" ]]; then
        symConfiguration="${presetConfiguration}"
    else
        symConfiguration="Catch-all ('Welcome' dialog disabled)"
    fi
    updateScriptLog "WELCOME DIALOG: Using ${symConfiguration} Configuration …"
    policyJSONConfiguration



    ###
    # Display "Setup Your Mac" dialog (and capture Process ID)
    ###

    eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
    until pgrep -q -x "Dialog"; do
        outputLineNumberInVerboseDebugMode
        updateScriptLog "WELCOME DIALOG: Waiting to display 'Setup Your Mac' dialog; pausing"
        sleep 0.5
    done
    updateScriptLog "WELCOME DIALOG: 'Setup Your Mac' dialog displayed; ensure it's the front-most app"
    runAsUser osascript -e 'tell application "Dialog" to activate'
    if [[ -n "${overlayoverride}" ]]; then
        dialogUpdateSetupYourMac "overlayicon: ${overlayoverride}"
    fi

fi
“Main”
The so-called “main” Setup Your Mac (1.13.0) dialog

Branding

Custom branding and support information for both the “Welcome” and the “Setup Your Mac” dialogs are controlled via SYM-Helper > Settings or as displayed below:

# [SYM-Helper] Branding overrides
brandingBanner="https://img.freepik.com/free-vector/green-abstract-geometric-wallpaper_52683-29623.jpg" # Image by pikisuperstar on Freepik
brandingBannerDisplayText="true"
brandingIconLight="https://cdn-icons-png.flaticon.com/512/979/979585.png"
brandingIconDark="https://cdn-icons-png.flaticon.com/512/740/740878.png"

# [SYM-Helper] IT Support Variables - Use these if the default text is fine but you want your org's info inserted instead
supportTeamName="Support Team Name"
supportTeamPhone="+1 (801) 555-1212"
supportTeamEmail="support@domain.com"
supportTeamWebsite="support.domain.com"
supportTeamHyperlink="[${supportTeamWebsite}](https://${supportTeamWebsite})"
supportKB="KB8675309"
supportTeamErrorKB="[${supportKB}](https://servicenow.company.com/support?id=kb_article_view&sysparm_article=${supportKB}#Failures)"

Configurations

The list of Jamf Pro policies to be executed by Setup Your Mac is controlled by policyJSON variables, which belong to one of four Configurations:

  • configurationOneName
  • configurationTwoName
  • configurationThreeName
  • Catch-all

(If only a single Configuration is required, modify the “catch-all” policyJSON.)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Configuration Variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

configurationDownloadEstimation="true"      # [ true (default) | false ]
correctionCoefficient="1.01"                # "Fudge factor" (to help estimate match reality)

configurationCatchAllSize="34"              # Catch-all Configuration in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationCatchAllInstallBuffer="0"      # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationOneName="Required"
configurationOneDescription="Minimum organization apps"
configurationOneSize="34"                   # Configuration One in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationOneInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationTwoName="Recommended"
configurationTwoDescription="Required apps and Microsoft Office"
configurationTwoSize="62"                   # Configuration Two in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationTwoInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationThreeName="Complete"
configurationThreeDescription="Recommended apps, Adobe Acrobat Reader and Google Chrome"
configurationThreeSize="106"                # Configuration Three in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationThreeInstallBuffer="0"         # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

Previously, when configuring Setup Your Mac, MacAdmins had to painstakingly convert their Jamf Pro policies to perfectly formatted JSON, cross their fingers — but not too many — and hope for the best.

Now, with SYM-Helper, a familiar, intuitive interface helps administrators build a near production-ready, customized Setup Your Mac script — with double-click and drag-and-drop ease — in minutes.

SYM-Helper makes building Configurations a breeze

Each Configuration’s policyJSON is comprised of steps which contain the following elements:

  • listitem: The text to be displayed in the list
  • icon: The hash of the icon to be displayed
  • progresstext: The text to be displayed below the progress bar
  • trigger: The Jamf Pro Policy Custom Event Name
    • Note: The recon trigger is built-in to SYM to update the computer’s inventory with your Jamf Pro server and most likely should be included at least once in each policyJSON
  • validation:
    • {absolute path} (simulates pre-1.6.0 behavior, for example:
      "/Applications/Microsoft Teams.app/Contents/Info.plist")
    • Local (for validation within the Setup Your Mac script, for example: "filevault")
    • Remote (for validation via a single-script Jamf Pro policy, for example: "symvGlobalProtect")
    • None (for triggers which don’t require validation; always evaluates as successful)
    • Recon (to update the computer’s inventory with your Jamf Pro server)
"${configurationOneName}" )

policyJSON='
{
    "steps": [
        {
            "listitem": "Rosetta",
            "icon": "8bac19160fabb0c8e7bac97b37b51d2ac8f38b7100b6357642d9505645d37b52",
            "progresstext": "Rosetta enables a Mac with Apple silicon to use apps built for a Mac with an Intel processor.",
            "trigger_list": [
                {
                    "trigger": "rosettaInstall",
                    "validation": "None"
                },
                {
                    "trigger": "rosetta",
                    "validation": "Local"
                }
            ]
        },
“Failure”
Setup Your Mac (1.13.0) “failure” dialog
failureDialog="true"        # Display the so-called "Failure" dialog (after the main SYM dialog) [ true | false 
###################################################################################
#
# Failure dialog
#
###################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# "Failure" dialog Title, Message and Icon
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

failureTitle="Failure Detected"
failureMessage="Placeholder message; update in the 'finalise' function"
failureIcon="SF=xmark.circle.fill,weight=bold,colour1=#BB1717,colour2=#F31F1F"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# "Failure" dialog Settings and Features
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

dialogFailureCMD="$dialogBinary \
--moveable \
--title \"$failureTitle\" \
--message \"$failureMessage\" \
--icon \"$failureIcon\" \
--iconsize 125 \
--width 625 \
--height 45% \
--position topright \
--button1text \"Close\" \
--infotext \"$scriptVersion\" \
--titlefont 'size=22' \
--messagefont 'size=14' \
--overlayicon \"$overlayicon\" \
--commandfile \"$failureCommandFile\" "

finalise function

To change the message displayed in the “Failure” dialog, modify the failureMessage as shown below:

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Finalise User Experience
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function finalise(){

    outputLineNumberInVerboseDebugMode

    if [[ "${configurationDownloadEstimation}" == "true" ]]; then

        outputLineNumberInVerboseDebugMode
        calculateFreeDiskSpace "FINALISE USER EXPERIENCE"

    fi

    if [[ "${jamfProPolicyTriggerFailure}" == "failed" ]]; then

        outputLineNumberInVerboseDebugMode
        updateScriptLog "Failed polcies detected …"
        if [[ -n "${webhookURL}" ]]; then
            updateScriptLog "Display Failure dialog: Sending webhook message"
            webhookStatus="Failures detected"
            webHookMessage
        fi

        if [[ "${failureDialog}" == "true" ]]; then

            outputLineNumberInVerboseDebugMode
            updateScriptLog "Display Failure dialog: ${failureDialog}"

            killProcess "caffeinate"
            if [[ "${brandingBannerDisplayText}" == "true" ]] ; then dialogUpdateSetupYourMac "title: Sorry ${loggedInUserFirstname}, something went sideways"; fi
            dialogUpdateSetupYourMac "icon: SF=xmark.circle.fill,weight=bold,colour1=#BB1717,colour2=#F31F1F"
            dialogUpdateSetupYourMac "progresstext: Failures detected. Please click Continue for troubleshooting information."
            dialogUpdateSetupYourMac "button1text: Continue …"
            dialogUpdateSetupYourMac "button1: enable"
            dialogUpdateSetupYourMac "progress: reset"
            
            # Wait for user-acknowledgment due to detected failure
            wait

            dialogUpdateSetupYourMac "quit:"
            eval "${dialogFailureCMD}" & sleep 0.3

            updateScriptLog "\n\n# # #\n# FAILURE DIALOG\n# # #\n"
            updateScriptLog "Jamf Pro Policy Name Failures:"
            updateScriptLog "${jamfProPolicyNameFailures}"

            failureMessage="A failure has been detected, ${loggedInUserFirstname}. \n\nPlease complete the following steps:\n1. Reboot and login to your ${modelName}  \n2. Login to Self Service  \n3. Re-run any failed policy listed below  \n\nThe following failed:  \n${jamfProPolicyNameFailures}"
            
            if [[ -n "${supportTeamName}" ]]; then

                supportContactMessage+="If you need assistance, please contact the **${supportTeamName}**:  \n"

                if [[ -n "${supportTeamPhone}" ]]; then
                    supportContactMessage+="- **Telephone:** ${supportTeamPhone}\n"
                fi

                if [[ -n "${supportTeamEmail}" ]]; then
                    supportContactMessage+="- **Email:** $supportTeamEmail\n"
                fi

                if [[ -n "${supportTeamWebsite}" ]]; then
                    supportContactMessage+="- **Web**: ${supportTeamHyperlink}\n"
                fi

                if [[ -n "${supportKB}" ]]; then
                    supportContactMessage+="- **Knowledge Base Article:** $supportTeamErrorKB\n"
                fi
            
            fi

            failureMessage+="\n\n${supportContactMessage}"

            dialogUpdateFailure "message: ${failureMessage}"

            dialogUpdateFailure "icon: SF=xmark.circle.fill,weight=bold,colour1=#BB1717,colour2=#F31F1F"
            dialogUpdateFailure "button1text: ${button1textCompletionActionOption}"

            # Wait for user-acknowledgment due to detected failure
            wait

            dialogUpdateFailure "quit:"
            quitScript "1"

        else

            outputLineNumberInVerboseDebugMode
            updateScriptLog "Display Failure dialog: ${failureDialog}"

            killProcess "caffeinate"
            if [[ "${brandingBannerDisplayText}" == "true" ]] ; then dialogUpdateSetupYourMac "title: Sorry ${loggedInUserFirstname}, something went sideways"; fi
            dialogUpdateSetupYourMac "icon: SF=xmark.circle.fill,weight=bold,colour1=#BB1717,colour2=#F31F1F"
            dialogUpdateSetupYourMac "progresstext: Failures detected."
            dialogUpdateSetupYourMac "button1text: ${button1textCompletionActionOption}"
            dialogUpdateSetupYourMac "button1: enable"
            dialogUpdateSetupYourMac "progress: reset"
            dialogUpdateSetupYourMac "progresstext: Errors detected; please ${progressTextCompletionAction// and } your ${modelName}, ${loggedInUserFirstname}."

            quitScript "1"

        fi

    else

        outputLineNumberInVerboseDebugMode
        updateScriptLog "All polcies executed successfully"
        if [[ -n "${webhookURL}" ]]; then
            webhookStatus="Successful"
            updateScriptLog "Sending success webhook message"
            webHookMessage
        fi

        if [[ "${brandingBannerDisplayText}" == "true" ]] ; then dialogUpdateSetupYourMac "title: ${loggedInUserFirstname}‘s ${modelName} is ready!"; fi
        dialogUpdateSetupYourMac "icon: SF=checkmark.circle.fill,weight=bold,colour1=#00ff44,colour2=#075c1e"
        dialogUpdateSetupYourMac "progresstext: Complete! Please ${progressTextCompletionAction}enjoy your new ${modelName}, ${loggedInUserFirstname}!"
        dialogUpdateSetupYourMac "progress: complete"
        dialogUpdateSetupYourMac "button1text: ${button1textCompletionActionOption}"
        dialogUpdateSetupYourMac "button1: enable"

        quitScript "0"

    fi

}

Debug Mode

Execute your customized SYM script via Terminal, toggling debugMode from verbose to true to false:

debugMode="${5:-"verbose"}"                                                     # Parameter 5: Debug Mode [ verbose (default) | true | false ]5

Note: When debugMode is set to true or verbose, Jamf Pro policies do not execute.

3. Racing-stripes
Dynamic Download Estimates
Dynamic Download Estimates helps your users better understand expected duration — based on their current Internet connection

Overview

Introduced in Setup Your Mac 1.10.0, Dynamic Download Estimates leverage the built-in macOS networkQuality binary to provide end-users with approximate Configuration durations, based on the actual speed of their specific Internet connection; these estimates can aid end-users in selecting their preferred Configuration.

In addition to correctionCoefficient, version 1.12.0 introduced “Install Buffers” which can be set to also include estimated installation time:

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Configuration Variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

configurationDownloadEstimation="true"      # [ true (default) | false ]
correctionCoefficient="1.01"                # "Fudge factor" (to help estimate match reality)

configurationCatchAllSize="34"              # Catch-all Configuration in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationCatchAllInstallBuffer="0"      # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationOneName="Required"
configurationOneDescription="Minimum organization apps"
configurationOneSize="34"                   # Configuration One in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationOneInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationTwoName="Recommended"
configurationTwoDescription="Required apps and Microsoft Office"
configurationTwoSize="62"                   # Configuration Two in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationTwoInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationThreeName="Complete"
configurationThreeDescription="Recommended apps, Adobe Acrobat Reader and Google Chrome"
configurationThreeSize="106"                # Configuration Three in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationThreeInstallBuffer="0"         # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

Estimating

To help MacAdmins provide their users accurate estimates, Setup Your Mac records various values to its log file:

  • Individual Elapsed Time (for each listitem in a Configuration’s policyJSON)
  • Starting and ending Disk Space
grep "Elapsed Time" /var/log/org.churchofjesuschrist.log 
2023-10-28 21:13:57 - SETUP YOUR MAC DIALOG: Elapsed Time for 'rosetta' 'Local': 0h:0m:9s
2023-10-28 21:14:11 - SETUP YOUR MAC DIALOG: Elapsed Time for 'filevault' 'Local': 0h:0m:5s
2023-10-28 21:17:39 - SETUP YOUR MAC DIALOG: Elapsed Time for 'sophosEndpoint' '/Applications/Sophos/Sophos Endpoint.app/Contents/Info.plist': 0h:3m:8s
2023-10-28 21:17:53 - SETUP YOUR MAC DIALOG: Elapsed Time for 'globalProtect' '/Applications/GlobalProtect.app/Contents/Info.plist': 0h:0m:14s
2023-10-28 21:26:15 - SETUP YOUR MAC DIALOG: Elapsed Time for 'symvMicrosoftOffice365' 'Remote': 0h:8m:22s
2023-10-28 21:27:22 - SETUP YOUR MAC DIALOG: Elapsed Time for 'microsoftTeams' '/Applications/Microsoft Teams.app/Contents/Info.plist': 0h:1m:7s
2023-10-28 21:29:33 - SETUP YOUR MAC DIALOG: Elapsed Time for 'adobeAcrobatReader' '/Applications/Adobe Acrobat Reader.app/Contents/Info.plist': 0h:2m:11s
2023-10-28 21:30:19 - SETUP YOUR MAC DIALOG: Elapsed Time for 'googleChrome' '/Applications/Google Chrome.app/Contents/Info.plist': 0h:0m:46s
2023-10-28 21:32:21 - SETUP YOUR MAC DIALOG: Elapsed Time for 'recon' 'recon': 0h:0m:33s
grep "Disk Space" /var/log/org.churchofjesuschrist.log 
2023-10-28 21:12:57 - WELCOME DIALOG: Disk Space: 476.8 GB free (96.44% available)
2023-10-28 21:32:22 - FINALISE USER EXPERIENCE: Disk Space: 459.3 GB free (92.90% available)

To leverage Dynamic Download Estimates, ensure the configurationDownloadEstimation variable is set to true.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Configuration Variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

configurationDownloadEstimation="true"      # [ true (default) | false ]
correctionCoefficient="1.01"                # "Fudge factor" (to help estimate match reality)

Enter the value for each Configuration — total file size (in gigabytes) multiplied by 7.451 — for the following variables:

  • configurationCatchAllSize
  • configurationOneSize
  • configurationTwoSize
  • configurationThreeSize

The correctionCoefficient variable allows for a “fudge factor” to help improve estimation accuracy.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Configuration Variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

configurationDownloadEstimation="true"      # [ true (default) | false ]
correctionCoefficient="1.01"                # "Fudge factor" (to help estimate match reality)

The “Install Buffers” introduced in 1.12.0 can also be leveraged to provide users a more accurate total duration.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Configuration Variables
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

configurationDownloadEstimation="true"      # [ true (default) | false ]
correctionCoefficient="1.01"                # "Fudge factor" (to help estimate match reality)

configurationCatchAllSize="34"              # Catch-all Configuration in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationCatchAllInstallBuffer="0"      # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationOneName="Required"
configurationOneDescription="Minimum organization apps"
configurationOneSize="34"                   # Configuration One in Gibibits (i.e., Total File Size in Gigabytes * 7.451)
configurationOneInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationTwoName="Recommended"
configurationTwoDescription="Required apps and Microsoft Office"
configurationTwoSize="62"                   # Configuration Two in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationTwoInstallBuffer="0"           # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

configurationThreeName="Complete"
configurationThreeDescription="Recommended apps, Adobe Acrobat Reader and Google Chrome"
configurationThreeSize="106"                # Configuration Three in Gibibits (i.e., Total File Size in Gigabytes * 7.451) 
configurationThreeInstallBuffer="0"         # Buffer time added to estimates to include installation time of packages, in seconds. Set to 0 to disable. 

To determine what value to specify for each Configuration Size-related variable, execute your customized Setup Your Mac script on a physical test Mac for your largest Configuration.

Once completed, make note of total duration and disk space:

grep "Elapsed Time" $scriptLog

grep "Disk Space" $scriptLog

Configuration Download Estimation Tester

Thanks to Andrew Spokes for contributing Configuration-Download-Estimation-Tester.bash.

This will allow you to quickly view and tweak the download estimates without having to re-run your Setup-Your-Mac script until you achieve the desired output and copy the configuration parameter values to your Setup-Your-Mac script

Testing Tips

Simulating Failures

When testing Setup Your Mac on an enrolled Mac, you may not observe any failures, even though that’s what you want.

Temporarily replacing instances of Info.plist with Info.plist.failed can easily simulate failures.

Simulate failures by replacing Info.plist with Info.plist.failed

Completion Actions

While Debug Mode can prove helpful during initial testing, eventually you’ll want to test-drive real-world scenarios (and, as you can imagine, testing forced-restarts includes some inherent inconvenience).

A trick I stumbled on is to first launch Terminal and elevate to root prior to testing. With an elevated Terminal, you’ll first be prompted for confirmation to forcibly quit Terminal, which you can cancel and continue testing.

Note: In Setup Your Mac (1.7.0 or later), the default completion actions now leverage the shutdown binary which negates this trick; toggle code comments as required:

"Restart Attended" )
    updateScriptLog "Restart, requiring user-interaction"
    killProcess "Self Service"
    wait
    # runAsUser osascript -e 'tell app "System Events" to restart'
    # sleep 5 && runAsUser osascript -e 'tell app "System Events" to restart' &
    sleep 5 && shutdown -r now &
    ;;

Unexpected Computer Inventory Delay

While testing via Terminal, you may observe the Computer Inventory step taking longer than expected.

Type Command k to quit the active dialog and you may find Terminal is requesting access to any number of user-specific items.

After responding to each access request, proceed with your testing.

Upgrading

A dedicated post about how MacAdmins using previous versions of Setup Your Mac can upgrade to the latest version is also available.


4. Implementation

Overview

While Setup Your Mac was originally designed to be executed only via a Jamf Pro Self Service policy, version 1.5.1 introduced additional checks to better execute with the Jamf Pro “Enrollment Complete” policy trigger.

Prior to using Setup Your Mac, we were using Jamf Pro policies triggered by enrollmentComplete (i.e., “Enrollment Complete Immediately after a computer completes the enrollment process”), but the successful execution of these policies was too unreliable for our needs.

Policies with an Enrollment Complete trigger do not run upon completion of enrollment under certain circumstances.

Jamf Pro Known Issues PI100009 - PI-004775

Currently — as can be observed in the first several seconds of the Setup Your Mac screencast — a device is initially considered as “non-compliant” and is only offered two policies:

  1. Setup Your Mac
  2. Update Computer Inventory

The successful execution of Setup Your Mac results in a compliant Mac.

Additionally, we require login to Self Service — including Multi-Factor Authentication — for every other policy; enabling Setup Your Mac at Enrollment Complete would bypass the required user login on the very first policy the user experiences. (See also: Setup Your Mac, please.)

Enrollment Complete

Thanks to Andrew Clark for documenting his approach for using Setup Your Mac with Jamf Pro enrollmentComplete trigger.

PreStage Enrollments

Thanks to Robert Schroeder for his write-up on using Setup Your Mac with Jamf Pro PreStage Enrollments.

Add your customized Setup Your Mac script to your Jamf Pro server
  1. Add your customized script to your Jamf Pro server
  2. Specify the following for Options > Parameter Labels
    • Parameter 4: Script Log Location [ /var/log/com.company.log ] (i.e., Your organization's default location for client-side logs)
    • Parameter 5: Debug Mode [ verbose (default) | true | false ]
    • Parameter 6: Welcome dialog [ userInput (default) | video | messageOnly | false ]
    • Parameter 7: Completion Action [ wait | sleep (with seconds) | Shut Down | Shut Down Attended | Shut Down Confirm | Restart | Restart Attended (default) | Restart Confirm | Log Out | Log Out Attended | Log Out Confirm ]
    • Parameter 8: Required Minimum Build [ disabled (default) | 23D ] (i.e., Your organization's required minimum build of macOS to allow users to proceed; use "23D" for macOS 14.3)
    • Parameter 9: Outdated OS Action [ /System/Library/CoreServices/Software Update.app (default) | jamfselfservice://content?entity=policy&id=117&action=view ] (i.e., Jamf Pro Self Service policy ID for operating system ugprades)
    • Parameter 10: Microsoft Teams or Slack Webhook URL [ Leave blank to disable (default) | https://microsoftTeams.webhook.com/URL | https://hooks.slack.com/services/URL ]
    • Parameter 11: Configuration (i.e., policyJSON; NOTE: Only used when welcomeDialog is set to video, false or messageOnly)
  3. Click Save
Setup Your Mac (1.14.0) Script Parameter Labels

Completion Actions (Parameter 7)

In addition to the previous wait and sleep options, Setup Your Mac (1.4.0) introduced the following Completion Action options:

Log OutRestartShut Down
 User is forcibly logged outComputer is forcibly restartedComputer is forcibly shut down
AttendedUser is forcibly logged out, after interacting with Setup Your Mac dialogsComputer is forcibly restarted, after user interacts with Setup Your Mac dialogsComputer is forcibly shut down, after user interacts with Setup Your Mac dialogs
ConfirmUser is prompted to Log Out via the dismissible, built-in macOS dialog boxUser is prompted to Restart via the dismissible, built-in macOS dialog boxUser is prompted to Shut Down via the dismissible, built-in macOS dialog box

Dynamic Button Label & Progress Text

Additionally, the label for the default button, button1text, and the message below the progress bar, progresstext, are dynamically updated based on the specified Completion Action:

Setup Your Mac dialogFailure dialog
SuccessfulFailure
Shut DownShutting Down …Continue …Shut Down
Shut Down AttendedShut Down
Shut Down Confirm
RestartRestarting …Restart
Restart AttendedRestart
Restart Confirm
Log OutLogging Out …Log Out
Log Out AttendedLog Out
Log Out Confirm

Required Minimum Build (Parameter 8)

Help mitigate zero-day attacks by specifying a minimum OS build before Setup Your Mac can be completed.

In the following example, the operating system of the testing computer is older than macOS 13.2 (22D49), and the user observes an error message to update:

Use the following table as a guide to determine your organization’s preferred value for Required Minimum Build:

VersionBuildRequired
Minimum
Build
14.3.123D6023D
14.323D5623D
14.2.123C7123C
14.123B7423B
14.023A34423A
13.6.122G31322G
12.7.121G92021G

Outdated OS Action (Parameter 9)

Determine what should happen when a user runs your customized Setup Your Mac policy on a computer with an outdated version of macOS (as determined by the value entered for Required Minimum Build):

Jamf Pro Policy

To open Jamf Pro’s Self Service to a specific policy:

  1. Navigate to the policy in Jamf Pro
  2. Click Self Service
  3. Scroll down to the Policy URLs section
  4. Copy the desired URL
  5. Paste the copied URL in Outdated OS Action (Parameter 9)

Open Software Update

To open Software Update, enter the following for Outdated OS Action (Parameter 9):
/System/Library/CoreServices/Software Update.app

Setup Your Mac (1.7.0 and later) Outdated OS Action Policy Script Parameters

Setup Your Mac (1.7.0 and later) Outdated OS Action (01:00; no audio)

Microsoft Teams or Slack Webhook URL (Parameter 10)

Specify either a Microsoft Teams or Slack Webhook URL in Parameter 10 to keep your entire team up-to-date on both successful and failed SYM executions; leave Parameter 10 blank to disable.

Slack integration is a new feature of Setup Your Mac (1.10.0)
Slack integration is a new feature of Setup Your Mac (1.10.0)

Note: Your policyJSON must include the recon trigger and validation — most frequently as its last listitem — when leveraging Teams or Slack integration:

        {
            "listitem": "Computer Inventory",
            "subtitle": "The listing of your Mac’s apps and settings",
            "icon": "https://ics.services.jamfcloud.com/icon/hash_ff2147a6c09f5ef73d1c4406d00346811a9c64c0b6b7f36eb52fcb44943d26f9",
            "progresstext": "A listing of your Mac’s apps and settings — its inventory — is sent automatically to the Jamf Pro server daily.",
            "trigger_list": [
                {
                    "trigger": "recon",
                    "validation": "recon"
                }
            ]
        }
    ]
}
'
;;

Note: When debugMode is enabled, the recon trigger does not actually execute and the computerID variable will be blank, causing the “View in Jamf Pro” button to not work as expected.

Specifying a Specific Version of swiftDialog

MacAdmins who wish to specify a specific version of swiftDialog to be used with Setup Your Mac can leverage the Package payload in the Jamf Pro policy, ensuring the SYM script’s Priority is set to After.

Use the Package payload to “lock” the version of swiftDialog

Please be aware the dialogCheck function includes a minimum version for swiftDialog:

function dialogCheck() {

    # Output Line Number in `verbose` Debug Mode
    if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "PRE-FLIGHT CHECK: # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi

    # Check for Dialog and install if not found
    if [ ! -e "/Library/Application Support/Dialog/Dialog.app" ]; then

        updateScriptLog "PRE-FLIGHT CHECK: swiftDialog not found. Installing..."
        dialogInstall

    else

        dialogVersion=$(/usr/local/bin/dialog --version)
        if [[ "${dialogVersion}" < "${swiftDialogMinimumRequiredVersion}" ]]; then
            
            updateScriptLog "PRE-FLIGHT CHECK: swiftDialog version ${dialogVersion} found but swiftDialog ${swiftDialogMinimumRequiredVersion} or newer is required; updating..."
            dialogInstall
            
        else

        updateScriptLog "PRE-FLIGHT CHECK: swiftDialog version ${dialogVersion} found; proceeding..."

        fi
    
    fi

}
Create a Jamf Pro Policy to Setup Your Mac
  1. Create a new Jamf Pro Policy, using the following as a guide for Options > General:
    • Set Display Name to Enrollment: Setup Your Mac (1.14.0)
    • Set Execution Frequency to Ongoing
  2. Select the Scripts payload and add your customized Setup Your Mac (1.14.0) via swiftDialog script, specifying the following Parameter Values
    • Script Log Location: /var/log/com.company.log
    • Debug Mode: verbose
    • Welcome dialog: userInput
    • Completion Action: Restart Attended
    • Required Minimum Build: 23D
    • Outdated OS Action: /System/Library/CoreServices/Software Update.app
    • Microsoft Teams or Slack Webhook URL: https://tenant.webhook.office.com/webhookb2/
Setup Your Mac (1.14.0) Jamf Pro Policy Script Payload
  1. Specify Scope as desired
    • Targets: All Computers
    • Limitations: No Limitations
    • Exclusions:
  2. Use the following for Self Service
    • Self Service Display Name: Setup Your Mac (1.14.0)
    • Button Name Before Initiation: Setup
    • Button Name After Initiation: Setup
    • Icon: (download)
    • Description:
## Welcome to your new Mac!  
  
Please click **Setup** to apply Church settings to your Mac. (Once completed, your Mac will restart.)  
  
Use this app, the **Workforce App Store**, to install your Church-assigned software and to configure your Mac after inital setup.

---

## Configurations

Select your preferred configuration:

- **Required:** Minimum Church apps
- **Recommended:** Required apps and Microsoft Office
- **Complete:** Recommended apps, Adobe Acrobat Reader and Google Chrome
    
### Required: Minimum Church apps

**FileVault** is built-in to macOS and provides full-disk encryption using XTS-AES-128 encryption with a 256-bit key to help prevent unauthorized access to the information on your startup disk.  
    
You'll enjoy next-gen protection with **Sophos Endpoint** which doesn’t rely on signatures to catch malware and means it catches zero-day threats without adversely affecting the performance of your device. You'll be protected before exploits even arrive.  
  
Use **Palo Alto GlobalProtect** to establish a Virtual Private Network (VPN) connection to Church headquarters.  
  
**Microsoft Teams** is a hub for teamwork in Office 365. Keep all your team’s chats, meetings, files, and apps together in one place.  
  
**Pro Tip:** By default, the listing of your computer's currently installed apps and system settings &mdash; its inventory &mdash; is automatically sent to the Jamf Pro server daily.
  1. Click Save
5. Troubleshooting
1. Welcome dialog doesn’t display

If, in your Jamf Pro policy, you’ve set Welcome dialog (i.e., Parameter 6) to userInput, but the “Welcome” dialog doesn’t display as expected, the issue is most often invalid JSON.

Please double-check the following:

  1. Confirm the “Welcome” dialog displays when the script is executed via Terminal using a freshly downloaded, timestamped copy of Setup Your Mac:
    • Enter your password when prompted
    • Confirm you observe the “Welcome” dialog
    • Click Quit
timestamp=$( date '+%Y-%m-%d-%H%M%S' ) ; curl -o ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash https://raw.githubusercontent.com/setup-your-mac/Setup-Your-Mac/main/Setup-Your-Mac-via-Dialog.bash ; sudo bash ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash
  1. Re-run your customized version of Setup Your Mac and review the client-side logs for entries which contain: WELCOME DIALOG
2023-08-19 16:42:33 - 

###
# Setup Your Mac (1.12.0)
# https://snelson.us/sym
###

2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Initiating …
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Setup Assistant is no longer running; proceeding …
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Finder & Dock are running; proceeding …
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Check for Logged-in System Accounts …
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Current Logged-in User: dan
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Current Logged-in User First Name: Dan
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Current Logged-in User ID: 503
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: 'requiredMinimumBuild' has been set to disabled; skipping OS validation.
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: macOS 13.5.1 (22G90) installed
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Caffeinating this script (PID: 29739)
2023-08-19 16:42:33 - QUIT SCRIPT: Re-enabling 'jamf' binary check-in
2023-08-19 16:42:33 - QUIT SCRIPT: 'jamf' binary check-in daemon not loaded, attempting to bootstrap and start
2023-08-19 16:42:33 - QUIT SCRIPT: Staring 'jamf' binary check-in daemon
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: swiftDialog version 2.3.0.4718 found; proceeding...
2023-08-19 16:42:33 - PRE-FLIGHT CHECK: Complete
/var/tmp/dialogCommandFileAdmin.lOU
/var/tmp/dialogCommandFileFailure.Ig4
/var/tmp/dialogCommandFilePrompt.8fR
/var/tmp/dialogCommandFileSetupYourMac.k19
/var/tmp/dialogCommandFileWelcome.cXg
2023-08-19 16:42:34 - WELCOME DIALOG: welcomeBannerImage is available, using it
2023-08-19 16:42:34 - WELCOME DIALOG: Auto-caching hosted 'abstract-orange-background-with-lines-halftone-effect_1017-32107.jpg' …
2023-08-19 16:42:35 - WELCOME DIALOG: bannerImage is available
2023-08-19 16:42:35 - WELCOME DIALOG: Disk Space: 455.1 GB free (92.05% available)
2023-08-19 16:42:35 - WELCOME DIALOG: Starting checkNetworkQualityConfigurations …
2023-08-19 16:42:35 - WELCOME DIALOG: Write 'welcomeJSON' to /var/tmp/welcomeJSONFile.Q84 …
2023-08-19 16:42:35 - WELCOME DIALOG: Display Welcome dialog 'infobox' animation …
2023-08-19 16:42:35 - WELCOME DIALOG: Display 'Welcome' dialog …
2023-08-19 16:42:35 - WELCOME DIALOG: dan entered information and clicked Continue
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
execution error: Error: SyntaxError: JSON Parse error: Unexpected identifier "JSON" (-2700)
2023-08-19 16:42:36 - WELCOME DIALOG: • Computer Name: 
2023-08-19 16:42:36 - WELCOME DIALOG: • User Name: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Real Name: 
2023-08-19 16:42:36 - WELCOME DIALOG: • E-mail: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Asset Tag: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Configuration: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Department: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Building: 
2023-08-19 16:42:36 - WELCOME DIALOG: • Room: 
2023-08-19 16:42:36 - WELCOME DIALOG: PolicyJSON Configuration: 
2023-08-19 16:42:36 - WELCOME DIALOG: dan did NOT specify a new computer name
  1. If you observe JSON Parse error in the logs, copy your entire welcomeJSON variable and paste into a new, blank document, then make the following modifications:
    • Delete welcomeJSON=' (being careful to retain the opening curly brace {)
    • Find "'" and replace with " (so the welcome-related variables will pass validation)
    • Delete the trailing single quote '
    • Validate the JSON by copying everything between the beginning and ending curly braces { … } and pasting at jsonlint.com
    • Review the displayed results and remediate as necessary until you observe Valid JSON
2. Unexpected Banner Image

If the Banner Image displayed in the “Welcome” and main “Setup Your Mac” dialogs isn’t as expected, the issue is most often an unreachable image resource.

Review the client-side logs and you’ll most likely observe the following:

2023-08-19 18:27:04 - WELCOME DIALOG: welcomeBannerImage is not available, using a default image
2023-08-19 18:27:04 - WELCOME DIALOG: bannerImage is not available, using alternative image

Manually validate that your specified image is accessible and correct as needed. (Thanks for the multiple PRs, @amadotejada!)

3. Setup Your Mac policy list doesn’t display

If the main Setup Your Mac dialog displays — but its policy list does not — the issue is most often invalid JSON in one (or more) of the Configuration-specific policyJSON variables.

Invalid JSON preventing policyJSON from displaying

Please double-check the following:

  1. Confirm the Configuration-specific Setup Your Mac policy list (i.e., policyJSON) displays when the script is executed via Terminal using a freshly downloaded, timestamped copy of Setup Your Mac:
timestamp=$( date '+%Y-%m-%d-%H%M%S' ) ; curl -o ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash https://raw.githubusercontent.com/setup-your-mac/Setup-Your-Mac/main/Setup-Your-Mac-via-Dialog.bash ; sudo bash ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash
  1. Re-run your customized version of Setup Your Mac and review the client-side logs for entries which contain: JSON Parse error (Note: If the logs include a division by 0 error, there is almost certainly invalid JSON in policyJSON.)
###
# VERBOSE DEBUG MODE | Dialog: v2.3.0.4718 • Setup Your Mac: v1.12.0
###

2023-08-19 16:52:27 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2674 # # #
2023-08-19 16:52:27 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2679 # # #
2023-08-19 16:52:27 - WELCOME DIALOG: Disk Space: 455.2 GB free (92.06% available)
2023-08-19 16:52:27 - WELCOME DIALOG: Starting checkNetworkQualityConfigurations …
2023-08-19 16:52:27 - WELCOME DIALOG: Write 'welcomeJSON' to /var/tmp/welcomeJSONFile.Swh …
2023-08-19 16:52:27 - WELCOME DIALOG: Display Welcome dialog 'infobox' animation …
2023-08-19 16:52:27 - WELCOME DIALOG: Display 'Welcome' dialog …
2023-08-19 16:52:58 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2239 # # #
/Users/dan/Desktop/Setup-Your-Mac-via-Dialog.bash: line 186:  5587 Terminated: 15          welcomeDialogInfoboxAnimation "$myPID"
2023-08-19 16:52:58 - WELCOME DIALOG: Completed networkQualityTest …
2023-08-19 16:52:58 - WELCOME DIALOG: 546.82 (Mbps)
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration One Estimated Seconds: 218
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration One Estimate: 0h:3m:38s
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration Two Estimated Seconds: 399
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration Two Estimate: 0h:6m:39s
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration Three Estimated Seconds: 690
2023-08-19 16:52:58 - WELCOME DIALOG: Configuration Three Estimate: 0h:11m:30s
2023-08-19 16:52:58 - WELCOME DIALOG: Network Quality Test: Started: 8/20/23, 4:52:28 PM, Ended: 8/20/23, 4:52:58 PM; Download: 546.82 Mbps, Responsiveness: 402
2023-08-19 16:53:38 - WELCOME DIALOG: dan entered information and clicked Continue
2023-08-19 16:53:39 - WELCOME DIALOG: • Computer Name: 
2023-08-19 16:53:39 - WELCOME DIALOG: • User Name: dan
2023-08-19 16:53:39 - WELCOME DIALOG: • Real Name: Dan K. Snelson
2023-08-19 16:53:39 - WELCOME DIALOG: • E-mail: dan@snelson.us
2023-08-19 16:53:39 - WELCOME DIALOG: • Asset Tag: 8675309
2023-08-19 16:53:39 - WELCOME DIALOG: • Configuration: Required
2023-08-19 16:53:39 - WELCOME DIALOG: • Department: Australia Area Office
2023-08-19 16:53:39 - WELCOME DIALOG: • Building: Harris (Franklin S.) Fine Arts Center
2023-08-19 16:53:39 - WELCOME DIALOG: • Room: 
2023-08-19 16:53:39 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 834 # # #
2023-08-19 16:53:39 - WELCOME DIALOG: PolicyJSON Configuration: Required
2023-08-19 16:53:39 - WELCOME DIALOG: dan did NOT specify a new computer name
2023-08-19 16:53:39 - WELCOME DIALOG: • Current Computer Name: "Dan's Sweet Lil' M2 MBA" 
2023-08-19 16:53:39 - WELCOME DIALOG: • Current Local Host Name: "F7NPN93H-5a66ec" 
2023-08-19 16:53:39 - WELCOME DIALOG: reconOptions: -endUsername "dan" -assetTag "8675309" -realname "Dan K. Snelson" -email "dan@snelson.us" -department "Australia Area Office" -building "Harris (Franklin S.) Fine Arts Center" 
2023-08-19 16:53:39 - WELCOME DIALOG: 'Setup Your Mac' dialog displayed; ensure it's the front-most app
2023-08-19 16:53:39 - Run "osascript -e tell application "Dialog" to activate" as "503" … 
2023-08-19 16:53:40 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2918 # # #
execution error: Error: SyntaxError: JSON Parse error: Expected '}' (-2700)
2023-08-19 16:53:40 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2934 # # #
execution error: Error: SyntaxError: JSON Parse error: Expected '}' (-2700)
/Users/dan/Desktop/Setup-Your-Mac-via-Dialog.bash: line 2937: 100 / totalProgressSteps : division by 0 (error token is " ")
2023-08-19 16:53:40 - SETUP YOUR MAC DIALOG: Total Number of Steps: 
2023-08-19 16:53:40 - SETUP YOUR MAC DIALOG: Progress Increment Value: 
  1. If you observe JSON Parse error in the logs:
    • Copy the Configuration-specific policyJSON variable between the beginning and ending curly braces { … }
    • Paste at jsonlint.com
    • Review the displayed results and remediate as necessary until you observe Valid JSON
4. Unexpected Jamf Pro Policy Execution

If your Jamf Pro policies aren’t executing as expected, complete the following steps to enable verbose policy execution:

  1. Ensure debug mode is set to false (since policies do not actually execute when debug mode is set to true)
  2. Search for and comment-out the following:
    eval "${jamfBinary} policy -trigger ${trigger}"
  3. Uncomment the following:
    eval "${jamfBinary} policy -trigger ${trigger} -verbose | tee -a ${scriptLog}"
  4. Re-run your customized Setup Your Mac script
  5. Review the client-side logs for the problematic policies
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Execute Jamf Pro Policy Custom Events (thanks, @smithjw)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function run_jamf_trigger() {

    outputLineNumberInVerboseDebugMode

    trigger="$1"

    if [[ "${debugMode}" == "true" ]] || [[ "${debugMode}" == "verbose" ]] ; then

        updateScriptLog "SETUP YOUR MAC DIALOG: DEBUG MODE: TRIGGER: $jamfBinary policy -event $trigger ${suppressRecon}"
        sleep "${debugModeSleepAmount}"

    else

        updateScriptLog "SETUP YOUR MAC DIALOG: RUNNING: $jamfBinary policy -event $trigger"
        eval "${jamfBinary} policy -event ${trigger} ${suppressRecon}"                                     # Add comment for policy testing
        # eval "${jamfBinary} policy -event ${trigger} ${suppressRecon} -verbose | tee -a ${scriptLog}"    # Remove comment for policy testing

    fi

}
5. Jamf Pro Remote Policy Validation Failures
Failed?!? Ensure one of the expected keywords is returned by your Remote validation script / policy.

When troubleshooting Remote Jamf Pro Policy Validation failures, ensure one of the following expected keywords is returned by your validation script / policy (thanks, @drtaru):

Policy ResultStatus Text
RunningRunning
SuccessInstalled
InstalledInstalled

###
# Remote
# Validation via a Jamf Pro policy which has a single-script payload, for example: "symvGlobalProtect"
# See: https://vimeo.com/782561166
###

"Remote" )
    if [[ "${debugMode}" == "true" ]] || [[ "${debugMode}" == "verbose" ]] ; then
        updateScriptLog "SETUP YOUR MAC DIALOG: DEBUG MODE: Remotely Confirm Policy Execution: Skipping 'run_jamf_trigger ${trigger}'"
        dialogUpdateSetupYourMac "listitem: index: $i, status: error, statustext: Debug Mode Enabled"
        sleep 0.5
    else
        updateScriptLog "SETUP YOUR MAC DIALOG: Remotely Validate '${trigger}' '${validation}'"
        dialogUpdateSetupYourMac "listitem: index: $i, status: wait, statustext: Checking …"
        result=$( "${jamfBinary}" policy -event "${trigger}" | grep "Script result:" )
        if [[ "${result}" == *"Running"* ]]; then
            dialogUpdateSetupYourMac "listitem: index: $i, status: success, statustext: Running"
        elif [[ "${result}" == *"Installed"* || "${result}" == *"Success"*  ]]; then
            dialogUpdateSetupYourMac "listitem: index: $i, status: success, statustext: Installed"
        else
            dialogUpdateSetupYourMac "listitem: index: $i, status: fail, statustext: Failed"
            jamfProPolicyTriggerFailure="failed"
            exitCode="1"
            jamfProPolicyNameFailures+="• $listitem  \n"
        fi
    fi
    ;;
6. Various Restart Completion Actions not Working as Expected

Background

Some MacAdmins using an Enrollment Complete trigger for Setup Your Mac have reported that the various “restart” Completion Actions fail to actually restart the computer after an otherwise successful execution.

Setup Your Mac (1.7.0 and later) attempts to address this issue by changing the default code for each Completion Action. (Also, each Completion Action includes alternative code options which should result in your desired behavior.)

The following are two examples from the various available Completion Actions.

Restart Attended Example

Most Completion Actions include three “one-liner” options to shut down, restart or log out:

"Restart Attended" )
    updateScriptLog "COMPLETION ACTION: Restart, requiring user-interaction"
    killProcess "Self Service"
    wait
    # runAsUser osascript -e 'tell app "System Events" to restart'
    # sleep 5 && runAsUser osascript -e 'tell app "System Events" to restart' &
    sleep 5 && shutdown -r now &
    ;;

If the default code option — highlighted above — does not work as expected, comment it out, then uncomment either of the other two lines and re-test.

7. Quit a running dialog

Specify a key sequence to quit a running dialog:

❯ dialog --help quitkey

   --quitkey <char>

	Set dialog quit key

        Use the specified character as the command+ key combination for quitting instead of "q".
        Capitol letters can be used in which case command+shift+<key> will be required

The “main” SYM dialog can be quit by pressing the k key.

--quitkey k \

Support, Feature Requests & Bug Reports

Support

The #setup-your-mac Channel on the MacAdmins Slack is a great resource when implementing Setup Your Mac in your environment.

“YOYO” Code

To the best of my recollection, Setup Your Mac (1.5.0) was the first time I’d publicly posted code which I considered to be knowingly incomplete and not fully tested (for the simple reason that we don’t use the additional input fields introduced in version 1.5.0 in our environment).

When you observe code blocks which include the following comment, please be aware that “you’re on your own.”

# UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
Feature Requests

Submit feature requests on GitHub.

While all requests are welcome, finding available cycles to custom-code a feature we won’t use in our production environment is always challenging.

Bug Reports

Before submitting a Setup Your Mac bug report on GitHub, please review the open swiftDialog issues to help determine the source of the issue.

Contributors

My personal thanks to each member of sym-devs for all their top-notch, on-demand support of Setup Your Mac. Thank you, thank you, thank you: BartLeslieAndrewRob and Andrew.

You’re invited to contribute and join the ever-growing list of contributors.

Posted in Jamf Pro, macOS, Scripts, Setup Your Mac, swiftDialog, Tips & Tricks

Related Posts