Menu Close

Setup Your Mac (1.9.0) via swiftDialog

Update: 11-Jun-2024

Setup Your Mac (1.15.0) with SYM-Helper (1.2.0) via swiftDialog (2.5.0)


For BYOD and user-initiated enrollments, Setup Your Mac (1.9.0) now provides more detailed feedback for “Previously Installed” apps

Setup Your Mac (1.9.0) screencast (01:39; no audio; edited for time)

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.

New Features

1.9.0 (01-Apr-2023)

BYOD / User-initiated Enrollments

Building on the significant enhancements of version 1.8.0, Setup Your Mac (1.9.0) now provides BYOD and user-initiated enrollments more detailed feedback, showing “Previously Installed” for apps the user installed prior to executing Setup Your Mac. (Thanks for the idea, @Manikandan!).

Setup Your Mac (1.9.0) provides more detailed feedback on previously installed apps
Setup Your Mac (1.9.0) provides more detailed feedback on previously installed apps

Toggle jamf Binary Check-ins

A new toggleJamfLaunchDaemon function easily allows stopping and starting jamf binary check-ins to temporarily pause policies with Recurring Check-in Triggers. (Thanks for the feature-complete Pull Request, @robjschroeder!)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Toggle `jamf` binary check-in (thanks, @robjschroeder!)
# shellcheck disable=SC2143
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function toggleJamfLaunchDaemon() {
    
jamflaunchDaemon="/Library/LaunchDaemons/com.jamfsoftware.task.1.plist"
if [[ "${debugMode}" == "true" ]] || [[ "${debugMode}" == "verbose" ]] ; then
    if [[ $(/bin/launchctl list | grep com.jamfsoftware.task.E) ]]; then
        updateScriptLog "PRE-FLIGHT CHECK: DEBUG MODE: Normally, 'jamf' binary check-in would be temporarily disabled"
    else
        updateScriptLog "QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled"
    fi
else
    while [[ ! -f "${jamflaunchDaemon}" ]] ; do
        sleep 0.1
    done
    if [[ $(/bin/launchctl list | grep com.jamfsoftware.task.E) ]]; then
        updateScriptLog "PRE-FLIGHT CHECK: Temporarily disable 'jamf' binary check-in"
        /bin/launchctl bootout system "${jamflaunchDaemon}"
    else
        updateScriptLog "QUIT SCRIPT: Re-enabling 'jamf' binary check-in"
        updateScriptLog "QUIT SCRIPT: 'jamf' binary check-in daemon not loaded, attempting to bootstrap and start"
        result="0"
        until [ $result -eq 3 ]; do
            /bin/launchctl bootstrap system "${jamflaunchDaemon}" && /bin/launchctl start "${jamflaunchDaemon}"
            result="$?"
            if [ $result = 3 ]; then
                updateScriptLog "QUIT SCRIPT: Staring 'jamf' binary check-in daemon"
            else
                updateScriptLog "QUIT SCRIPT: Failed to start 'jamf' binary check-in daemon"
            fi
        done
    fi
fi
}

toggleJamfLaunchDaemon

Implementation

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.)

PreStage Enrollments

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

Prerequisites

If the core functionality of Setup Your Mac meets your needs, writing code should not be required.

However, you must be comfortable modifying scripts before implementing this approach in production (i.e., customizing existing settings for your use-case, reading and editing JSON, etc.).

The Jamf Training Catalog, which is free to all Jamf customers, is a great place to start learning the basics.

Configuration

Complete the following steps to provide your users a seamless post-enrollment experience when setting up their new Macs.

A. Conduct a dry-run of the Setup Your Mac script

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/dan-snelson/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.)
tee: /var/log/org.churchofjesuschrist.log: Permission denied
2023-03-29 04:07:00 - 

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

tee: /var/log/org.churchofjesuschrist.log: Permission denied
2023-03-29 04:07:00 - PRE-FLIGHT CHECK: Initiating …
tee: /var/log/org.churchofjesuschrist.log: Permission denied
2023-03-29 04:07:00 - 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
2023-03-29 04:14:29 - 

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

2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Initiating …
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Setup Assistant is no longer running; proceeding …
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Finder & Dock are running; proceeding …
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: 'requiredMinimumBuild' has been set to disabled; skipping OS validation.
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: macOS 13.2.1 (22D68) installed
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Caffeinating this script (PID: 934)
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Check for Logged-in System Accounts …
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Current Logged-in User: dan
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Current Logged-in User First Name: Dan
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: Current Logged-in User ID: 501
2023-03-29 04:14:29 - QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled
2023-03-29 04:14:29 - PRE-FLIGHT CHECK: # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 272 # # #
2023-03-29 04:14:30 - PRE-FLIGHT CHECK: Dialog not found. Installing...
installer: Package name is Dialog
installer: Upgrading at base path /
installer: The upgrade was successful.
2023-03-29 04:14:36 - PRE-FLIGHT CHECK: swiftDialog version 2.1.0.4148 installed; proceeding...
2023-03-29 04:14:36 - PRE-FLIGHT CHECK: Complete
  1. Please wait while the latest production version of swiftDialog is automatically installed and the personalized “Welcome” dialog is displayed:
Setup Your Mac (1.9.0) welcomeDialog (Parameter 6) set to userInput
Setup Your Mac (1.9.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):
2023-03-29 04:14:36.380 defaults[1070:10382] 
The domain/default pair of (/Library/Preferences/com.jamfsoftware.jamf, self_service_app_path) does not exist
/..namedfork/rsrc: No such file or directory
2023-03-29 04:14:36 - 

###
# VERBOSE DEBUG MODE | Dialog: v2.1.0.4148 • Setup Your Mac: v1.9.0
###

2023-03-29 04:14:36 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 1979 # # #
2023-03-29 04:14:41 - WELCOME DIALOG: dan clicked Quit at Welcome dialog
2023-03-29 04:14:41 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 1870 # # #
2023-03-29 04:14:41 - QUIT SCRIPT: Exiting …
2023-03-29 04:14:41 - QUIT SCRIPT: De-caffeinate …
2023-03-29 04:14:41 - Attempting to terminate the 'caffeinate' process …
2023-03-29 04:14:41 - (Termination message indicates success.)
/Users/dan/Downloads/Setup-Your-Mac-via-Dialog-reference.bash: line 1730:   965 Terminated: 15          caffeinate -dimsu -w $$
2023-03-29 04:14:41 - QUIT SCRIPT: DEBUG MODE: Normally, 'jamf' binary check-in would be re-enabled
2023-03-29 04:14:41 - QUIT SCRIPT: Removing /var/tmp/overlayicon.icns …
2023-03-29 04:14:41 - QUIT SCRIPT: Removing /var/tmp/dialogWelcome.e6Q …
2023-03-29 04:14:41 - QUIT SCRIPT: Removing /var/tmp/dialogSetupYourMac.sFC …
2023-03-29 04:14:41 - QUIT SCRIPT: Removing /var/tmp/dialogFailure.sa6 …
2023-03-29 04:14:41 - QUIT SCRIPT: Removing default dialog file …
  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.9.0) "Welcome" dialog with input fields populated and drop-down menus modified
Setup Your Mac (1.9.0) “Welcome” dialog with input fields populated and drop-down menus modified
  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.9.0) "Verbose Debug Mode" with expected failures
Setup Your Mac (1.9.0) “Verbose Debug Mode” with expected failures
Setup Your Mac (1.9.0) "Failure" dialog with end-user instructions
Setup Your Mac (1.9.0) “Failure” dialog with end-user instructions
Setup Your Mac (1.9.0) "Debug Mode" completionActionOption
Setup Your Mac (1.9.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 Debug Mode 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
B. 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
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.

C. Review the default Welcome dialog

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.9.0) welcomeDialog (Parameter 6) set to video
Setup Your Mac (1.9.0) welcomeDialog (Parameter 6) set to video

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

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

    policyJSON='
    {
        "steps": [
            {

User Input

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

The input fields in the “Welcome” dialog are controlled by a single welcomeJSON variable (thanks to Bart Reardon) and you can add, modify or remove fields as required.

Setup Your Mac (1.9.0) welcomeDialog (Parameter 6) set to userInput
Setup Your Mac (1.9.0) welcomeDialog (Parameter 6) set to userInput
####################################################################################################
#
# Welcome dialog
#
####################################################################################################

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

welcomeTitle="Happy $( date +'%A' ), ${loggedInUserFirstname} and welcome to your new Mac!"
welcomeMessage="Please enter your Mac's **Asset Tag**, select your preferred **Configuration** then click **Continue** to start applying settings to your new Mac.  \n\nOnce completed, the **Wait** button will be enabled and you'll be able to review the results before restarting your Mac.  \n\nIf you need assistance, please contact the Help Desk: +1 (801) 555-1212.  \n\n---  \n\n#### Configurations  \n- **Required:** Minimum organization apps  \n- **Recommended:** Required apps and Microsoft Office  \n- **Complete:** Recommended apps, Adobe Acrobat Reader and Google Chrome"
welcomeBannerImage="https://img.freepik.com/free-photo/yellow-watercolor-paper_95678-446.jpg"
welcomeBannerText="Happy $( date +'%A' ), ${loggedInUserFirstname} and welcome to your new Mac!"
welcomeCaption="Please review the above video, then click Continue."
welcomeVideoID="vimeoid=803933536"

# Welcome icon set to either light or dark, based on user's Apperance setting (thanks, @mm2270!)
appleInterfaceStyle=$( /usr/bin/defaults read /Users/"${loggedInUser}"/Library/Preferences/.GlobalPreferences.plist AppleInterfaceStyle 2>&1 )
if [[ "${appleInterfaceStyle}" == "Dark" ]]; then
    welcomeIcon="https://cdn-icons-png.flaticon.com/512/740/740878.png"
else
    welcomeIcon="https://cdn-icons-png.flaticon.com/512/979/979585.png"
fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# "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\" "



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# "Welcome" JSON for Capturing User Input (thanks, @bartreardon!)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

welcomeJSON='
{
    "bannerimage" : "'"${welcomeBannerImage}"'",
    "bannertext" : "'"${welcomeBannerText}"'",
    "title" : "'"${welcomeTitle}"'",
    "message" : "'"${welcomeMessage}"'",
    "icon" : "'"${welcomeIcon}"'",
    "iconsize" : "198.0",
    "button1text" : "Continue",
    "button2text" : "Quit",
    "infotext" : "'"${scriptVersion}"'",
    "blurscreen" : "true",
    "ontop" : "true",
    "titlefont" : "shadow=true, size=28",
    "messagefont" : "size=14",
    "textfield" : [
        {   "title" : "Computer Name",
            "required" : false,
            "prompt" : "Computer Name"
        },
        {   "title" : "User Name",
            "required" : false,
            "prompt" : "User Name"
        },
        {   "title" : "Asset Tag",
            "required" : true,
            "prompt" : "Please enter the seven-digit Asset Tag",
            "regex" : "^(AP|IP|CD)?[0-9]{7,}$",
            "regexerror" : "Please enter (at least) seven digits for the Asset Tag, optionally preceed by either AP, IP or CD."
        }
    ],
    "selectitems" : [
        {   "title" : "Configuration",
            "default" : "Required",
            "values" : [
                "Required",
                "Recommended",
                "Complete"
            ]
        },  
        {   "title" : "Department",
            "default" : "Please select your department",
            "values" : [
                "Please select your department",
                "Asset Management",
                "Australia Area Office",
                "Board of Directors",
                "Business Development",
                "Corporate Communications",
                "Creative Services",
                "Customer Service / Customer Experience",
                "Engineering",
                "Finance / Accounting",
                "General Management",
                "Human Resources",
                "Information Technology / Technology",
                "Investor Relations",
                "Legal",
                "Marketing",
                "Operations",
                "Product Management",
                "Production",
                "Project Management Office",
                "Purchasing / Sourcing",
                "Quality Assurance",
                "Risk Management",
                "Sales",
                "Strategic Initiatives & Programs",
                "Technology"
            ]
        }
    ],
    "height" : "725"
}
'

The processing of user input is handled later in the script and will most likely require additional customization, which, again, 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 "
    eval "${dialogBinary} --args ${welcomeVideo}"

    # Output Line Number in `verbose` Debug Mode
    if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "WELCOME DIALOG: # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi
    symConfiguration="Catch-all (video)"
    policyJSONConfiguration

    eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
    dialogSetupYourMacProcessID=$!
    until pgrep -q -x "Dialog"; do
        # Output Line Number in `verbose` Debug Mode
        if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "# # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi
        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'

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

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

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

    welcomeResults=$( eval "${dialogApp} --jsonfile ${welcomeCommandFile} --json" )

    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")
            assetTag=$(get_json_value_welcomeDialog "$welcomeResults" "Asset Tag")
            symConfiguration=$(get_json_value_welcomeDialog "$welcomeResults" "Configuration" "selectedValue")
            department=$(get_json_value_welcomeDialog "$welcomeResults" "Department" "selectedValue")



            ###
            # 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: • Asset Tag: $assetTag"
            updateScriptLog "WELCOME DIALOG: • Configuration: $symConfiguration"
            updateScriptLog "WELCOME DIALOG: • Department: $department"



            ###
            # 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

            # Department
            if [[ -n "${department}" ]]; then
                # UNTESTED, UNSUPPORTED "YOYO" EXAMPLE
                reconOptions+="-department \"${department}\" "
            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
            dialogSetupYourMacProcessID=$!
            until pgrep -q -x "Dialog"; do
                # Output Line Number in `verbose` Debug Mode
                if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "# # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi
                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'
            ;;

        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 
    ###

    # Output Line Number in `verbose` Debug Mode
    if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "WELCOME DIALOG: # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi
    symConfiguration="Catch-all ('Welcome' dialog disabled)"
    policyJSONConfiguration



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

    eval "${dialogSetupYourMacCMD[*]}" & sleep 0.3
    dialogSetupYourMacProcessID=$!
    until pgrep -q -x "Dialog"; do
        # Output Line Number in `verbose` Debug Mode
        if [[ "${debugMode}" == "verbose" ]]; then updateScriptLog "# # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. ${LINENO} # # #" ; fi
        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'

fi
D. Review the default Setup Your Mac dialog

Review the default Setup Your Mac dialog.

Setup Your Mac (1.9.0) main dialog
Setup Your Mac (1.9.0) main dialog

The list of Jamf Pro policies to be executed is controlled by one of four policyJSON variables (with special thanks to smithjw, drtaru and wakco):

  • Required
  • Recommended
  • Complete
  • Catch-all

First, configure the setupYourMacPolicyArrayIconPrefixUrl to the fully qualified domain name of the server which hosts your icons, including any required sub-directories. (See Jamf’s Cloud Services Connection: Icon Service.)

Next, for each Configuration-specific policyJSON, specify:

  • 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 Setup Your Mac recon trigger — which must use a validation of None — executes jamf recon and should be included at least once in each policyJSON to perform the actual computer inventory update with your Jamf Pro server for user-provided information (i.e., Computer Name, Asset Tag, Department, etc.)
  • 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, for example: recon; always evaluates as successful)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# "Setup Your Mac" policies to execute (Thanks, Obi-@smithjw!)
#
# For each configuration step, specify:
# - listitem: The text to be displayed in the list
# - icon: The hash of the icon to be displayed on the left
#   - See: https://vimeo.com/772998915
# - progresstext: The text to be displayed below the progress bar
# - trigger: The Jamf Pro Policy Custom Event Name
# - validation: [ {absolute path} | Local | Remote | None ]
#   See: https://snelson.us/2023/01/setup-your-mac-validation/
#       - {absolute path} (simulates pre-v1.6.0 behavior, for example: "/Applications/Microsoft Teams.app/Contents/Info.plist")
#       - Local (for validation within this 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, for example: recon; always evaluates as successful)
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Thanks, @wakco: If you would prefer to get your policyJSON externally replace it with:
#  - policyJSON="$(cat /path/to/file.json)" # For getting from a file, replacing /path/to/file.json with the path to your file, or
#  - policyJSON="$(curl -sL https://server.name/jsonquery)" # For a URL, replacing https://server.name/jsonquery with the URL of your file.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Thanks, @astrugatch: I added this line to global variables:
# jsonURL=${10} # URL Hosting JSON for policy_array
#
# And this line replaces the entirety of the policy_array (~ line 503):
# policy_array=("$(curl -sL $jsonURL)")
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# shellcheck disable=SC1112 # use literal slanted single quotes for typographic reasons
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# The fully qualified domain name of the server which hosts your icons, including any required sub-directories
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

setupYourMacPolicyArrayIconPrefixUrl="https://ics.services.jamfcloud.com/icon/hash_"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Select `policyJSON` based on Configuration selected in "Welcome" dialog (thanks, @drtaru!)
# shellcheck disable=SC1112 # use literal slanted single quotes for typographic reasons
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function policyJSONConfiguration() {

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

    updateScriptLog "WELCOME DIALOG: PolicyJSON Configuration: $symConfiguration"

    case ${symConfiguration} in

        "Required" )

            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"
                            }
                        ]
                    },
                    {
                        "listitem": "FileVault Disk Encryption",
                        "icon": "f9ba35bd55488783456d64ec73372f029560531ca10dfa0e8154a46d7732b913",
                        "progresstext": "FileVault is built-in to macOS and provides full-disk encryption to help prevent unauthorized access to your Mac.",
                        "trigger_list": [
                            {
                                "trigger": "filevault",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint",
                        "icon": "c70f1acf8c96b99568fec83e165d2a534d111b0510fb561a283d32aa5b01c60c",
                        "progresstext": "You’ll enjoy next-gen protection with Sophos Endpoint which doesn’t rely on signatures to catch malware.",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpoint",
                                "validation": "/Applications/Sophos/Sophos Endpoint.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint Services (Remote)",
                        "icon": "c05d087189f0b25a94f02eeb43b0c5c928e5e378f2168f603554bce2b5c71209",
                        "progresstext": "Remotely validating Sophos Endpoint services …",
                        "trigger_list": [
                            {
                                "trigger": "symvSophosEndpointRTS",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect",
                        "icon": "ea794c5a1850e735179c7c60919e3b51ed3ed2b301fe3f0f27ad5ebd394a2e4b",
                        "progresstext": "Use Palo Alto GlobalProtect to establish a Virtual Private Network (VPN) connection to Church headquarters.",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "/Applications/GlobalProtect.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect Services (Remote)",
                        "icon": "709e8bdf0019e8faf9df85ec0a68545bfdb8bfa1227ac9bed9bba40a1fa8ff42",
                        "progresstext": "Remotely validating Palo Alto GlobalProtect services …",
                        "trigger_list": [
                            {
                                "trigger": "symvGlobalProtect",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Final Configuration",
                        "icon": "4723e3e341a7e11e6881e418cf91b157fcc081bdb8948697750e5da3562df728",
                        "progresstext": "Finalizing Configuration …",
                        "trigger_list": [
                            {
                                "trigger": "finalConfiguration",
                                "validation": "None"
                            },
                            {
                                "trigger": "reconAtReboot",
                                "validation": "None"
                            }
                        ]
                    },
                    {
                        "listitem": "Computer Inventory",
                        "icon": "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": "None"
                            }
                        ]
                    }
                ]
            }
            '
            ;;

        "Recommended" )

            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"
                            }
                        ]
                    },
                    {
                        "listitem": "FileVault Disk Encryption",
                        "icon": "f9ba35bd55488783456d64ec73372f029560531ca10dfa0e8154a46d7732b913",
                        "progresstext": "FileVault is built-in to macOS and provides full-disk encryption to help prevent unauthorized access to your Mac.",
                        "trigger_list": [
                            {
                                "trigger": "filevault",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint",
                        "icon": "c70f1acf8c96b99568fec83e165d2a534d111b0510fb561a283d32aa5b01c60c",
                        "progresstext": "You’ll enjoy next-gen protection with Sophos Endpoint which doesn’t rely on signatures to catch malware.",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpoint",
                                "validation": "/Applications/Sophos/Sophos Endpoint.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint Services (Local)",
                        "icon": "c05d087189f0b25a94f02eeb43b0c5c928e5e378f2168f603554bce2b5c71209",
                        "progresstext": "Locally validating Sophos Endpoint services …",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpointServices",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect",
                        "icon": "ea794c5a1850e735179c7c60919e3b51ed3ed2b301fe3f0f27ad5ebd394a2e4b",
                        "progresstext": "Use Palo Alto GlobalProtect to establish a Virtual Private Network (VPN) connection to Church headquarters.",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "/Applications/GlobalProtect.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect Services (Local)",
                        "icon": "709e8bdf0019e8faf9df85ec0a68545bfdb8bfa1227ac9bed9bba40a1fa8ff42",
                        "progresstext": "Locally validating Palo Alto GlobalProtect services …",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Microsoft Office 365",
                        "icon": "10e2ebed512e443189badcaf9143293d447f4a3fd8562cd419f6666ca07eb775",
                        "progresstext": "Microsoft Office 365 for Mac gives you the essentials to get it all done with the classic versions of the Office applications.",
                        "trigger_list": [
                            {
                                "trigger": "microsoftOffice365",
                                "validation": "/Applications/Microsoft Outlook.app/Contents/Info.plist"
                            },
                            {
                                "trigger": "symvMicrosoftOffice365",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Microsoft Teams",
                        "icon": "dcb65709dba6cffa90a5eeaa54cb548d5ecc3b051f39feadd39e02744f37c19e",
                        "progresstext": "Microsoft Teams is a hub for teamwork in Office 365. Keep all your team’s chats, meetings and files together in one place.",
                        "trigger_list": [
                            {
                                "trigger": "microsoftTeams",
                                "validation": "/Applications/Microsoft Teams.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Final Configuration",
                        "icon": "4723e3e341a7e11e6881e418cf91b157fcc081bdb8948697750e5da3562df728",
                        "progresstext": "Finalizing Configuration …",
                        "trigger_list": [
                            {
                                "trigger": "finalConfiguration",
                                "validation": "None"
                            },
                            {
                                "trigger": "reconAtReboot",
                                "validation": "None"
                            }
                        ]
                    },
                    {
                        "listitem": "Computer Inventory",
                        "icon": "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": "None"
                            }
                        ]
                    }
                ]
            }
            '
            ;;

        "Complete" )

            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"
                            }
                        ]
                    },
                    {
                        "listitem": "FileVault Disk Encryption",
                        "icon": "f9ba35bd55488783456d64ec73372f029560531ca10dfa0e8154a46d7732b913",
                        "progresstext": "FileVault is built-in to macOS and provides full-disk encryption to help prevent unauthorized access to your Mac.",
                        "trigger_list": [
                            {
                                "trigger": "filevault",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint",
                        "icon": "c70f1acf8c96b99568fec83e165d2a534d111b0510fb561a283d32aa5b01c60c",
                        "progresstext": "You’ll enjoy next-gen protection with Sophos Endpoint which doesn’t rely on signatures to catch malware.",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpoint",
                                "validation": "/Applications/Sophos/Sophos Endpoint.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint Services (Local)",
                        "icon": "c05d087189f0b25a94f02eeb43b0c5c928e5e378f2168f603554bce2b5c71209",
                        "progresstext": "Locally validating Sophos Endpoint services …",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpointServices",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint Services (Remote)",
                        "icon": "c05d087189f0b25a94f02eeb43b0c5c928e5e378f2168f603554bce2b5c71209",
                        "progresstext": "Remotely validating Sophos Endpoint services …",
                        "trigger_list": [
                            {
                                "trigger": "symvSophosEndpointRTS",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect",
                        "icon": "ea794c5a1850e735179c7c60919e3b51ed3ed2b301fe3f0f27ad5ebd394a2e4b",
                        "progresstext": "Use Palo Alto GlobalProtect to establish a Virtual Private Network (VPN) connection to Church headquarters.",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "/Applications/GlobalProtect.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect Services (Local)",
                        "icon": "709e8bdf0019e8faf9df85ec0a68545bfdb8bfa1227ac9bed9bba40a1fa8ff42",
                        "progresstext": "Locally validating Palo Alto GlobalProtect services …",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect Services (Remote)",
                        "icon": "709e8bdf0019e8faf9df85ec0a68545bfdb8bfa1227ac9bed9bba40a1fa8ff42",
                        "progresstext": "Remotely validating Palo Alto GlobalProtect services …",
                        "trigger_list": [
                            {
                                "trigger": "symvGlobalProtect",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Microsoft Office 365",
                        "icon": "10e2ebed512e443189badcaf9143293d447f4a3fd8562cd419f6666ca07eb775",
                        "progresstext": "Microsoft Office 365 for Mac gives you the essentials to get it all done with the classic versions of the Office applications.",
                        "trigger_list": [
                            {
                                "trigger": "microsoftOffice365",
                                "validation": "/Applications/Microsoft Outlook.app/Contents/Info.plist"
                            },
                            {
                                "trigger": "symvMicrosoftOffice365",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Microsoft Teams",
                        "icon": "dcb65709dba6cffa90a5eeaa54cb548d5ecc3b051f39feadd39e02744f37c19e",
                        "progresstext": "Microsoft Teams is a hub for teamwork in Office 365. Keep all your team’s chats, meetings and files together in one place.",
                        "trigger_list": [
                            {
                                "trigger": "microsoftTeams",
                                "validation": "/Applications/Microsoft Teams.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Adobe Acrobat Reader",
                        "icon": "988b669ca27eab93a9bcd53bb7e2873fb98be4eaa95ae8974c14d611bea1d95f",
                        "progresstext": "Views, prints, and comments on PDF documents, and connects to Adobe Document Cloud.",
                        "trigger_list": [
                            {
                                "trigger": "adobeAcrobatReader",
                                "validation": "/Applications/Adobe Acrobat Reader.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Google Chrome",
                        "icon": "12d3d198f40ab2ac237cff3b5cb05b09f7f26966d6dffba780e4d4e5325cc701",
                        "progresstext": "Google Chrome is a browser that combines a minimal design with sophisticated technology to make the Web faster.",
                        "trigger_list": [
                            {
                                "trigger": "googleChrome",
                                "validation": "/Applications/Google Chrome.app/Contents/Info.plist"
                            }
                        ]
                    },
                    {
                        "listitem": "Final Configuration",
                        "icon": "4723e3e341a7e11e6881e418cf91b157fcc081bdb8948697750e5da3562df728",
                        "progresstext": "Finalizing Configuration …",
                        "trigger_list": [
                            {
                                "trigger": "finalConfiguration",
                                "validation": "None"
                            },
                            {
                                "trigger": "reconAtReboot",
                                "validation": "None"
                            }
                        ]
                    },
                    {
                        "listitem": "Computer Inventory",
                        "icon": "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": "None"
                            }
                        ]
                    }
                ]
            }
            '
            ;;

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

            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"
                            }
                        ]
                    },
                    {
                        "listitem": "FileVault Disk Encryption",
                        "icon": "f9ba35bd55488783456d64ec73372f029560531ca10dfa0e8154a46d7732b913",
                        "progresstext": "FileVault is built-in to macOS and provides full-disk encryption to help prevent unauthorized access to your Mac.",
                        "trigger_list": [
                            {
                                "trigger": "filevault",
                                "validation": "Local"
                            }
                        ]
                    },
                    {
                        "listitem": "Sophos Endpoint",
                        "icon": "c70f1acf8c96b99568fec83e165d2a534d111b0510fb561a283d32aa5b01c60c",
                        "progresstext": "You’ll enjoy next-gen protection with Sophos Endpoint which doesn’t rely on signatures to catch malware.",
                        "trigger_list": [
                            {
                                "trigger": "sophosEndpoint",
                                "validation": "/Applications/Sophos/Sophos Endpoint.app/Contents/Info.plist"
                            },
                            {
                                "trigger": "symvSophosEndpointRTS",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Palo Alto GlobalProtect",
                        "icon": "ea794c5a1850e735179c7c60919e3b51ed3ed2b301fe3f0f27ad5ebd394a2e4b",
                        "progresstext": "Use Palo Alto GlobalProtect to establish a Virtual Private Network (VPN) connection to Church headquarters.",
                        "trigger_list": [
                            {
                                "trigger": "globalProtect",
                                "validation": "/Applications/GlobalProtect.app/Contents/Info.plist"
                            },
                            {
                                "trigger": "symvGlobalProtect",
                                "validation": "Remote"
                            }
                        ]
                    },
                    {
                        "listitem": "Final Configuration",
                        "icon": "4723e3e341a7e11e6881e418cf91b157fcc081bdb8948697750e5da3562df728",
                        "progresstext": "Finalizing Configuration …",
                        "trigger_list": [
                            {
                                "trigger": "finalConfiguration",
                                "validation": "None"
                            },
                            {
                                "trigger": "reconAtReboot",
                                "validation": "None"
                            }
                        ]
                    },
                    {
                        "listitem": "Computer Inventory",
                        "icon": "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": "None"
                            }
                        ]
                    }
                ]
            }
            '
            ;;

    esac

}
E. Customize the Setup Your Mac script

After adding Custom Events to your Jamf Pro Policies as required, use your favorite editor to modify ~/Downloads/Setup-Your-Mac-via-Dialog-reference.bash for your environment:

  1. “Welcome” dialog
    1. “Welcome” dialog Title, Message, Banner Image, Banner Text, Caption, Video ID and Icon
    2. “Welcome” JSON
  2. “Setup Your Mac” dialog
    1. “Setup Your Mac” dialog Title, Message, Overlay Icon, Banner Image, Banner Text, Help Message, Infobox and Icon
    2. “Setup Your Mac” dialog Settings and Features
    3. “Setup Your Mac” policies to execute
      1. setupYourMacPolicyArrayIconPrefixUrl (i.e., the fully qualified domain name of the server which hosts your icons, including any required sub-directories; see Jamf’s Cloud Services Connection: Icon Service.)
      2. Configuration-specific policyJSON variables (i.e., Required, Recommended, Complete and Catch-all)
        • listitem: The text to be displayed in the list
        • icon: The hash of the icon to be displayed on the left
        • progresstext: The text to be displayed below the progress bar
        • trigger: The Jamf Pro Policy Custom Event Name
          • Note: The Setup Your Mac recon trigger — which must use a validation of None — executes jamf recon and should be included at least once in each policyJSON to perform the actual computer inventory update with your Jamf Pro server for user-provided information (i.e., Computer Name, Asset Tag, Department, etc.)
        • validation: [ {absolute path} | Local | Remote | None ]
        • Note: You can validate the JSON by copying everything between the beginning and ending curly braces { … } and pasting at jsonlint.com
  3. “Failure” dialog
    • “Failure” dialog Title, Message and Icon
    • “Failure” dialog Settings and Features
Setup Your Mac (1.9.0) Failure dialog
Setup Your Mac (1.9.0) Failure dialog
  1. finalise function
    • dialogUpdateSetupYourMac "title: Sorry ${loggedInUserFirstname}, something went sideways"
    • dialogUpdateFailure "message: A failure has been detected, ${loggedInUserFirstname}.
F. 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/org.churchofjesuschrist.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 | 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) | 22E ] (i.e., Your organization's required minimum build of macOS to allow users to proceed; use "22E" for macOS 13.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)
  3. Click Save
Setup Your Mac (1.9.0) Script Parameter Labels
Setup Your Mac (1.9.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)

G. 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.9.0)
    • Set Execution Frequency to Ongoing
  2. Select the Scripts payload and add your customized Setup Your Mac (1.9.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: 22E
    • Outdated OS Action: /System/Library/CoreServices/Software Update.app
Setup Your Mac (1.9.0) Jamf Pro Policy Script Payload
Setup Your Mac (1.9.0) Jamf Pro Policy Script Payload
  1. Specify Scope as desired
    • Targets: All Computers
    • Limitations: No Limitations
    • Exclusions:
      • All Jamf Pro Compliant Computers
      • macOS 10.15.Catalina and earlier
      • Setup Your Mac: Complete
  2. Use the following for Self Service
    • Self Service Display Name: Setup Your Mac (1.9.0)
    • Button Name Before Initiation: Setup
    • Button Name After Initiation: Setup
    • Icon: Setup Your Mac 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 — its inventory — is automatically sent to the Jamf Pro server daily.
Setup Your Mac (1.9.0) Jamf Pro Policy Self Service Configuration
Setup Your Mac (1.9.0) Jamf Pro Policy Self Service Configuration
  1. Click Save
H. 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 it 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
    • Click Quit
timestamp=$( date '+%Y-%m-%d-%H%M%S' ) ; curl -o ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash https://raw.githubusercontent.com/dan-snelson/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
sudo bash ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash
2023-03-31 07:16:48 - 

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

2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Initiating …
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Setup Assistant is no longer running; proceeding …
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Finder & Dock are running; proceeding …
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: macOS 13 installed; checking build version ...
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: macOS 13.3 (22E252) installed; proceeding ...
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Caffeinating this script (PID: 2397)
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Check for Logged-in System Accounts …
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Current Logged-in User: dan
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Current Logged-in User First Name: Dan
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Current Logged-in User ID: 501
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: DEBUG MODE: Normally, 'jamf' binary check-in would be temporarily disabled
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: swiftDialog version 2.1.0.4148 found; proceeding...
2023-03-31 07:16:48 - PRE-FLIGHT CHECK: Complete
2023-03-31 07:16:49 - 

###
# VERBOSE DEBUG MODE | Dialog: v2.1.0.4148 • Setup Your Mac: v1.9.0
###

2023-03-31 07:16:49 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 1979 # # #
2023-03-31 07:16:49 - 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)
  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. Setup Your Mac dialog doesn’t display

If the main “Setup Your Mac” dialog doesn’t display as expected, the issue is most often unreachable image resources.

Specify verbose for debugMode (Parameter 5) and you’ll most likely observe the following in the logs:

2023-03-29 12:52:27 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:28 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:28 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:28 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:28 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:29 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:29 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:29 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:29 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:30 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:30 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:30 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:30 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:31 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:31 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing
2023-03-29 12:52:31 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2149 # # #
2023-03-29 12:52:31 - WELCOME DIALOG: Waiting to display ‘Setup Your Mac’ dialog; pausing

Individually validate each image resource and remediate as required.

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:
    • Enter your password when prompted
    • Enter an Asset Tag
    • Select the Configuration you’re troubleshooting
    • Click Continue
timestamp=$( date '+%Y-%m-%d-%H%M%S' ) ; curl -o ~/Downloads/Setup-Your-Mac-via-Dialog-$timestamp.bash https://raw.githubusercontent.com/dan-snelson/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.)
2023-03-04 10:02:07 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2091 # # #
execution error: Error: SyntaxError: JSON Parse error: Expected ']' (-2700)
2023-03-04 10:02:07 - # # # SETUP YOUR MAC VERBOSE DEBUG MODE: Line No. 2108 # # #
execution error: Error: SyntaxError: JSON Parse error: Expected ']' (-2700)
/Users/dan/Downloads/Setup-Your-Mac-via-Dialog-reference.bash: line 2111: 100 / totalProgressSteps : division by 0 (error token is " ")
2023-03-04 10:02:07 - SETUP YOUR MAC DIALOG: Total Number of Steps: 
2023-03-04 10:02:07 - 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 (shown as Line 1338 below):
    eval "${jamfBinary} policy -trigger ${trigger}"
  3. Uncomment the following (shown as Line 1339 below):
    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() {

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

    trigger="$1"

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

        updateScriptLog "SETUP YOUR MAC DIALOG: DEBUG MODE: TRIGGER: $jamfBinary policy -trigger $trigger"
        if [[ "$trigger" == "recon" ]]; then
            updateScriptLog "SETUP YOUR MAC DIALOG: DEBUG MODE: RECON: $jamfBinary recon ${reconOptions}"
        fi
        sleep 1

    elif [[ "$trigger" == "recon" ]]; then

        dialogUpdateSetupYourMac "listitem: index: $i, status: wait, statustext: Updating …, "
        updateScriptLog "SETUP YOUR MAC DIALOG: Updating computer inventory with the following reconOptions: \"${reconOptions}\" …"
        eval "${jamfBinary} recon ${reconOptions}"

    else

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

    fi

}
5. Jamf Pro Remote Policy Validation Failures

When troubleshooting Remote Jamf Pro Policy Validation failures, ensure the keyword Running is returned by your validation script / policy.

Failed?!? Ensure the keyword Running is returned by your Remote validation script / policy.
###
# 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 -trigger "${trigger}" | grep "Script result:" )
        if [[ "${result}" == *"Running"* ]]; then
            dialogUpdateSetupYourMac "listitem: index: $i, status: success, statustext: Running"
        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 Mac Admins 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

The Restart Completion Action includes three options to restart the computer, show below as lines:

  • 1792
  • 1793
  • 1794 new default in Setup Your Mac (1.7.0 and later)
"Restart" )
    updateScriptLog "Restart sans user interaction"
    killProcess "Self Service"
    # 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 of Line 1794 does not work as expected, comment it out, then uncomment either Line 1792 or Line 1793 and re-test.

Restart Attended

The Restart Attended Completion Action also includes three options to restart the computer, show below as lines:

  • 1801
  • 1802
  • 1803 new default in Setup Your Mac (1.7.0 and later)
"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 &
    ;;

If the default code option of Line 1803 does not work as expected, comment it out, then uncomment either Line 1801 or Line 1802 and re-test.

With Inspiration and Code from

Special Thanks

A special thanks to the growing number of Mac Admins contributing code and ideas to help make Setup Your Mac what it is today.

grep -n "[Tt]hanks" ~/Downloads/Setup-Your-Mac-via-Dialog-reference.bash
13:#   - Previously installed apps with a `filepath` validation now display "Previously Installed" (instead of a generic "Installed"; Issue No. 13; thanks for the idea, @Manikandan!)
14:#   - Allow "first name" to correctly handle names in "Lastname, Firstname" format (Pull Request No. 11; thanks, @meschwartz!)
15:#   - Corrected `PATH` (thanks, @Theile!)
16:#   - `Configuration` no longer displays in SYM's `infobox` when `welcomeDialog` is set to `false` or `video` (Issue No. 12; thanks, @Manikandan!)
18:#   - New `toggleJamfLaunchDaemon` function (Pull Request No. 16; thanks, @robjschroeder!)
20:#   - Corrected an issue where inventory would be submitted twice (thanks, @Manikandan!)
190:# Pre-flight Check: Ensure computer does not go to sleep during SYM (thanks, @grahampugh!)
225:# Pre-flight Check: Toggle `jamf` binary check-in (thanks, @robjschroeder!)
267:# Pre-flight Check: Validate / install swiftDialog (Thanks big bunches, @acodega!)
400:# Welcome icon set to either light or dark, based on user's Apperance setting (thanks, @mm2270!)
429:# "Welcome" JSON for Capturing User Input (thanks, @bartreardon!)
527:# Create `overlayicon` from Self Service's custom icon (thanks, @meschwartz!)
574:# "Setup Your Mac" policies to execute (Thanks, Obi-@smithjw!)
591:# Thanks, @wakco: If you would prefer to get your policyJSON externally replace it with:
597:# Thanks, @astrugatch: I added this line to global variables:
616:# Select `policyJSON` based on Configuration selected in "Welcome" dialog (thanks, @drtaru!)
1246:# Run command as logged-in user (thanks, @scriptingosx!)
1367:# Parse JSON via osascript and JavaScript for the Welcome dialog (thanks, @bartreardon!)
1380:# Execute Jamf Pro Policy Custom Events (thanks, @smithjw)
1513:                    updateScriptLog "SETUP YOUR MAC DIALOG: Locally Validate Policy Result: Rosetta 2 … " # Thanks, @smithjw!
1728:# Kill a specified process (thanks, @grahampugh!)
1865:# Quit Script (thanks, @bartreadon!)
2247:# When `welcomeDialog` is set to `false` or `video`, set the value of `infoboxConfiguration` to null (thanks for the idea, @Manikandan!)

Support, Feature Requests & Bug Reports

Support

The #setup-your-mac Channel on the Mac Admins Slack and 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 and please note that 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.

Feature History

1.9.0 (01-Apr-2023)

  • Previously installed apps with a filepath validation now display “Previously Installed” (instead of a generic “Installed”; Issue No. 13; thanks for the idea, @Manikandan!)
  • Allow “first name” to correctly handle names in “Lastname, Firstname” format (Pull Request No. 11; thanks @meschwartz!)
  • Corrected PATH (thanks, @Theile!)
  • Configuration no longer displays in SYM’s infobox when welcomeDialog is set to false or video (Addresses Issue No. 12; thanks, @Manikandan!)
  • Updated icon hashes
  • toggleJamfLaunchDaemon function (Pull Request No. 16; thanks, @robjschroeder!)
  • Formatted policyJSON with Erik Lynd’s JSON Tools
  • Corrected an issue where inventory would be submitted twice (thanks, @Manikandan!)

1.8.1 (11-Mar-2023)

  • Added currentLoggedInUser function to better validate loggedInUser (Addresses Issue No. 2)
  • Added new Microsoft Office 365 Remote Validation (Pull Request No. 3)
  • Improved logging when welcomeDialog is video or false (Addresses Issue No. 4)
  • Create overlayicon from Self Service’s custom icon (thanks, Mike Schwartz!)

1.8.0 (04-Mar-2023)

  • Introduces fully customizable “Configurations” (thanks, @drtaru!)
    • Required: Minimum organizational apps (i.e., full disk encryption, endpoint security, VPN, communication tools, etc.)
    • Recommended: Required apps and Microsoft Office
    • Complete: Recommended apps, Adobe Acrobat Reader and Google Chrome
  • Play video at Welcome dialog (Script Parameter 6) by specifying video (Addresses Issue No. 36)
    • Breaking Change for users of Setup Your Mac prior to 1.8.0 ?
      • To capture user input, welcomeDialog (Script Parameter 6) must be set to userInput
  • Addresses Issue No. 39 (thanks big bunches, @wakco!)
  • Addresses Issue No. 43 (thanks, @wakco)
  • Removed the following from the Welcome dialog
    • Comment
    • Select B
    • Select C
  • Dedicated repository

1.7.2 (28-Feb-2023)

  • Reordered Pre-Flight Check to not validate OS until AFTER Setup Assistant / Finder & Dock
  • Added disabled option for requiredMinimumBuild
  • Added Pre-flight Check for Self Service’s brandingimage.png
  • Pre-flight Check logging messages now saved client-side
  • Addresses Issue No. 41

1.7.1 (07-Feb-2023)

  • Addresses Issue No. 35
  • Improves user-interaction with helpmessage under certain circumstances (thanks, @bartreardon!)
  • Increased debugMode delay (thanks for the heads-up, @Lewis B!)
  • Changed Banner Image (to something much, much smaller)

1.7.0 (01-Feb-2023)

  • Adds compatibility for and leverages new features of swiftDialog 2.1.0
    • bannertext
    • helpmessage
    • infobox
    • progress-related racing-stripes (which now require swiftDialog 2.1.0+)
  • Completion Actions
    • Adjusted default code option (to hopefully help Mac Admins using an Enrollment Complete trigger [i.e., runAsUser doesn’t work too well when _mbsetupuser is the logged-in user])
  • Combined listitem steps for installation and validation (thanks, @roiegat!)
  • Validate Operating System Version, Build and Outdated OS Action
    • Addresses Issue No. 31
    • Introduces the ability to specify a requiredMinimumBuild as Script Parameter 8 (thanks, @SirDrSpiderpig!)
      • For example, to only allow macOS Ventura 13.2 (or later), specify: 22D
    • Introduces Outdated OS Action
      • Open Self Service to your OS update policy: jamfselfservice://content?entity=policy&id=117&action=view
    • Open Software Update (default): /System/Library/CoreServices/Software Update.app
  • Temporarily disables jamf binary check-in (thanks, @mactroll and @cube!)
    • Purposely commented-out the code to re-enable the jamf binary; presumes the Mac will be restarted
  • Separated “Global Variables” from “Dialog Variables” to allow for additional Script Parameters
  • Improved Pre-flight Check messaging
  • Introduces verbose as an option for Debug Mode
    • Most useful when first deploying Setup Your Mac

1.6.0 (09-Jan-2023)

  • Addresses Issue No. 21
    • ? Breaking Change ? (for users of Setup Your Mac prior to 1.6.0)
      • policy_array‘s path has been replaced with validation
    • ? The confirmPolicyExecution function confirms if the policy needs to be executed
    • ? The validatePolicyResult function validates if the policy succeeded and the related service is running, based on the specified validation option
    • Validation Options:
      • {absolute path} (simulates pre-1.6.0 behavior, for example: "/Applications/Microsoft Teams.app/Contents/Info.plist")
      • Local (for validation within this script, for example: "filevault")
      • Remote (for validation validation via a single-script Jamf Pro policy, for example: "symvGlobalProtect")
      • None (for triggers which don’t require validation, for example: recon; always evaluates as successful)
  • Enhanced policy logging options to address Issue No. 25
    • Search for and comment-out the following (shown as Line 782):
      eval "${jamfBinary} policy -trigger ${trigger}"
    • Uncomment the following (shown as Line 783):
      eval "${jamfBinary} policy -trigger ${trigger} -verbose | tee -a ${scriptLog}"
    • Ensure debug mode is set to false
  • Added Rosetta 2 policy execution and validation
  • Enhanced logging

1.5.1 (07-Dec-2022)

  • Updates to “Pre-flight Checks”
    • Moved section to start of script
    • Added additional check for Setup Assistant (for Mac Admins using an “Enrollment Complete” trigger)

1.5.0 (28-Nov-2022)

  • ? Prompt user for additional fields at Welcome dialog
    • New fields are included in a single welcomeJSON variable (thanks for all your efforts and feedback, @drtaru and @iDrewbs!)
    • Dynamic reconOptions based on user’s input at Welcome dialog
    • Thanks for your patience, @remusache, @midiman1000, @erikmadams, @colorenz, @benphilware
  • Breaking Changes ? (for users of Setup Your Mac prior to 1.5.0)
    • Script Parameter Reordering (sorry; I’ll strive not to ever do this again)
      • Parameter 4: Script Log Location [ /var/tmp/org.churchofjesuschrist.log ]
      • Parameter 5: Debug Mode [ true (default) | false ]
      • Parameter 6: Welcome Screen [ true (default) | 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 ]
  • Miscellaneous Improvements
    • Moved code blocks and variables to better reflect the Welcome > Setup Your Mac > Failure workflow
    • Random code clean-up

1.4.0 (21-Nov-2022)

  • Significantly enhanced Completion Action options
    • ✅ Addresses Issue 15 (thanks, @mvught, @riddl0rd, @iDrewbs and @master-vodawagner)
    • ? Dynamically set button1text based on the value of completionActionOption (thanks, @jared-a-young)
    • ? Dynamically set progresstext based on the value of completionActionOption (thanks, @iDrewbs)
    • ? Three new flavors: Shut DownRestart or Log Out
      • Forced: Zero user-interaction
        • Added brute-force killProcess "Self Service"
        • Added hack to allow Policy Logs to be shipped to Jamf Pro server
      • ⚠️ Attended: Forced, but only after user-interaction (thanks, @owainiorwerth)
        • Added hack to allow Policy Logs to be shipped to Jamf Pro server
      • Confirm: Displays built-in macOS user-dismissible dialog box
    • Sleep
    • Wait (default)
  • Improved Debug Mode behavior
    • DEBUG MODE | now only displayed as infotext (i.e., bottom, left-hand corner)
    • completionAction informational-only with simple dialog box (thanks, @_____???)
    • Swapped blurscreen for moveable
    • General peformance increases
  • Miscellaneous Improvements
    • Removed jamfDisplayMessage function and reverted dialogCheck function to use osascript (with an enhanced error message)
    • Replaced “Installing …” with “Updating …” for recon-flavored trigger
    • Changed “Updating Inventory” to “Computer Inventory” for recon-flavored listitem
    • Changed exit code to 1 when user quits “Welcome” screen
    • Changed welcomeIcon URLs
    • Changed URL for Harvesting Self Service icons screencast (thanks, @nstrauss)

1.3.0 (09-Nov-2022)

  • Script Parameter Changes:
    • ⚠️ Parameter 4: debug mode enabled by default
    • Parameter 7: Script Log Location
  • ? Embraced drastic speed improvements in ?swiftDialog v2?
  • Caffeinated script (thanks, @grahampugh!)
  • Enhanced wait exiting logic
  • Personalized dialogs
  • General script standardization

1.2.10 (05-Oct-2022)

  • Modifications for swiftDialog v2 (thanks, @bartreardon!)
    • Added I/O pause to dialog_update_setup_your_mac
    • Added list: show when displaying policy_array
    • Re-ordered Setup Your Mac progress bar commands
  • More specific logging for various dialog update functions
  • Confirm Setup Assistant complete and user at Desktop (thanks, @ehemmete!)

1.2.9 (03-Oct-2022)

  • Added setupYourMacPolicyArrayIconPrefixUrl variable (thanks for the idea, @mani2care!)
  • Removed unnecessary listitem icon updates (thanks, @bartreardon!)
  • Output swiftDialog version when running in debug mode
  • Updated URL for Zoom icon

1.2.8 (19-Sep-2022)

  • Replaced “ugly” completionAction if … then … else with “more readabale” case statement (thanks, @pyther!)
  • Updated “method for determining laptop/desktop” (thanks, @acodega and @scriptingosx!)
  • Additional tweaks discovered during internal production deployment

1.2.7 (10-Sep-2022)

1.2.6 (29-Aug-2022)

  • Adjust I/O timing (for policy_array loop)

1.2.5 (24-Aug-2022)

  • Resolves #3 (thanks, @pyther!)

1.2.4 (18-Aug-2022)

  • Swap “Installing …” and “Pending …” status indicators (thanks, @joncrain)

1.2.3 (15-Aug-2022)

  • Updates for switftDialog v1.11.2
  • Report failures in Jamf Pro Policy Triggers

1.2.2 (07-Jun-2022)

  • Added “dark mode” for logo (thanks, @mm2270)
  • Added “compact” for --liststyle

1.2.1 (01-Jun-2022)

  • Made Asset Tag Capture optional (via Jamf Pro Script Paramter 5)

1.2.0 (30-May-2022)

  • Changed --infobuttontext to --infotext
  • Added regex and regexerror for Asset Tag Capture
  • Replaced @adamcodega’s apps with @smithjw’s policy_array
  • Added progress update
  • Added filepath validation

1.1.0 (19-May-2022)

  • Added initial “Welcome Screen” with Asset Tag Capture and Debug Mode

1.0.0 (30-Apr-2022)

  • First “official” release
Posted in Device Management, Jamf Pro, macOS, Scripts, Tips & Tricks

Related Posts