Automation of steps for zero touch deployment

New Contributor III

Hi everyone,

For those of you that have achieved zero touch deployment with Jamf Pro; how have you set up the policies that should execute right after the enrolment? Is the best practice to set up Smart Groups, that look at enrolment time (i.e. <1 min ago), or is there a way to set the policies to run right after the enrolment?



Honored Contributor III

@JureJerebic You should look at the combination of DEPNotify and the DEPNotify Starter for Jamf Pro script. That combination makes it very simple to set up the enrollment process.

New Contributor

I have this covered in 2 ways. I have a set of policies that runs imediately after enrollment that is pointed at a smart group called "New Devices". This smart group is comprised of devices enrolled less than 3 days ago, which gives me a little leeway if I need to add or repush something to the devices. 

The second set of policies which is mostly software install runs at next check in against the same "New Devices" group, so about 15 minutes after they finish enrollment. I think I did that to allow me flexibility in changing my policies... It was a while back sorry.

New Contributor III

@sdagley DEPnotify is very cool, but it presumes that we go from the current process immediately into full zero touch deployment, which is a bit much, no?

Honored Contributor III

@JureJerebic No, there is no requirement for Automated Device Enrollment to use the DEPNotify/DEPNotify Starter process. You can start with a manually initiated enrollment process triggered by Enrollment Complete, and once it's working the way you want you can move to ADE.

New Contributor III

@sdagley How can they run side by side though? For example, have one test device use the DEPNotify for the enrolment, but the rest go through the normal current process?

Honored Contributor III

@JureJerebic Normally one would have Production and Dev environments, so the DEPNotify workflow development could be done separately from your current workflow. If you don't have multiple environments I'd suggest taking down your current workflow at the end of your normal work week and then bringing up the DEPNotify workflow over the weekend. It's really very straightforward, and you'll find several examples to give you ideas:


New Contributor

Olá @JureJerebic ,

Nosso processo de zero touch era com DEPNotifyscript DEPNotify Starter for Jamf Pro funcionava muito bem, e era muito fácil de implantar, porém começamos a ter problemas com alguns MacBooks, a interface do DEP simplesmente não executava...os programas eram executados em background, porém o usuário não sabia o que estava acontecendo.


Devido a isso, trocamos o processo de onboarding para o octory a interface dele é semelhante ao SplashBuddy

Estou gostando bastante dele.

Agora sobre as politicas no Jamf, nomeamos cada politica com números em ordem de prioridade, e utilizamos triggers, ex:

00 - Install Rosertta2

10 - Set HostName


Desta forma ao executar a trigger onboarding todas as politicas serão executadas ao mesmo tempo, criando uma fila de prioridade.


I'm sorry, I don't speak Spanish

Valued Contributor III

I actually have started a new way of loading up all the base software right after enrollment.  This helps in environments where a tech is setting up the machine for the end user before they log in.  Also this ensures the end user isnt sitting there waiting for 15 minutes while all their software installs.  

After this base software install we have jamf connect log them in and have the jamf connect notify script lookup the name of the user logging in and then figure out what building and then name the computer based on that lookup, and we use microsoft 365 and push a profile with the Microsoft SSO info ( as well as microsoft company portal).  


We have a trigger on enrollment complete that then runs a pop up showing what is installing and then adds a complete message, which happens on the Location screen during enrollment as long as it is left for a minute or two.  I attached our base app install script below which uses Jamf Helper to pop the messages about what is currently being installed.

So far we have seen this work 100% of the time pre-loading all our major software.

All kudos to mm2270 though for his help making this work for our workflow.



#by mm2270 and Gabe Shackney
#Keep Machine from going to sleep
caffeinate -i -s -d -t 1800 &
## Static paths to jamfHelper and the icon
jamf_helper="/Library/Application Support/JAMF/bin/"
icon="/Library/Desktop Pictures/PPSLogo.jpg"

## Bash array containing the custom triggers (events)

## Use the array length to figure out how many steps we have automatically

## Function that calls each policy trigger and customizes the message during each loop
## Uses a case statement to determine the heading text for each custom event trigger
function callPolicy ()

## This case statement determines which heading text we need to use in jamfHelper for each policy trigger
case $trigger in
	heading_text="Rosetta if needed"
	heading_text="Outstanding Policies"
	heading_text="Microsoft Company Portal"
	heading_text="Creative Cloud if needed"
	heading_text="Microsoft Office"
	heading_text="Google Chrome"
	heading_text="Mozilla Firefox"
	heading_text="Set Dock Utility"
	heading_text="Set Desktop Utility"
	heading_text="Cisco Umbrella if needed"
	heading_text="Firmware Password if needed"

## Call jamfHelper and customize the display slightly
"$jamf_helper" \
	-windowType utility \
	-title "Base App Installs" \
	-heading "$heading_text" \
	-description "Completing Step $i of $total_steps" \
	-icon "$icon" &
	## Call the Jamf policy by it's event trigger
	/usr/local/bin/jamf policy -event "$trigger"
	/bin/sleep 2
	## Shut down the jamfHelper background process to get ready for the next one
	killall jamfHelper

## Start the loop over the custom event triggers array
## For each one it processes, it calls the function above
## We increase the count of the "step" after each one completes
for trigger in "${custom_triggers[@]}"; do
	echo "Calling policy trigger $trigger"
	let i=$((i+1))

## When we get to this point, we're done with the policy loop, so show the installs complete message here
"$jamf_helper" \
	-windowType utility \
	-title "Base App Installs" \
	-heading "Completed Installs" \
	-description "Base App Installs Complete." \
	-icon "$icon" \
	-timeout 2

## Final message
"$jamf_helper" \
	-windowType utility \
	-lockHUD \
	-icon "$icon" \
	-title "Tech Office" \
	-heading "Base App Installs Complete" \
	-description "Click Continue for Login Screen" \
	-button1 "Continue" -defaultButton 1

exit 0




Gabe Shackney
Princeton Public Schools


Like @GabeShack we are also using a script (although very different from Gabe's) for our deployment.  In our case the policy that runs the script is only available via self service to devices enrolled through Apple School Manager and a Prestage Enrollment SMART group, but that's just our setup; using a Prestage is not a requirement.  There are several benefits we get from the script; we can control the order of installations (important, since some of our apps still require rosetta to install), we can collect user info via AppleScript dialogs, and we use some of that collected info during a final recon to update the jamf computer record.

The next iteration that we're building and testing now will trigger automatically, no need for running the policy through self service, bringing it one step closer to zero touch.

Contributor II

I have a simple script that I wrote that is executed at enrollment Complete by jamf.
the script waits until the setup assistant is complete, then installs self service, and then kicks off DEP Notify.
self service is installed first so i can use its branding images inside DEP Notify


# ENROLLEMNT SCRIPT to call must run Jamf policys #
# Created by Michael on 6/9/19					  #

# Check if Setup Assistance Process is Still Running.
# If yes, wait till it finishes so this script will NOT proceed while running the Setup Assistant (Location Settings..etc)

SetupAssistance_process=$(/bin/ps auxww | grep -q "[S]etup")
while [ $? -eq 0 ]
    /bin/echo "Setup Assistant Still Running... Sleep for 2 seconds..."
    /bin/sleep 2
    SetupAssistance_process=$(/bin/ps auxww | grep -q "[S]etup")

# Call Rosetta 2 policy
jamf policy -trigger Rosetta_2
# Call self service policy
jamf policy -trigger self_service
#call DEP notify policy
jamf policy -trigger DEP_Notify

exit 0


Contributor II

- One policy triggered on Enrollment Complete (using the restart and files & processes payloads)



[ $( /usr/bin/arch ) = "arm64" ] && /usr/sbin/softwareupdate --install-rosetta --agree-to-license; /usr/sbin/languagesetup -langspec "English (Australia)"; /usr/sbin/systemsetup -settimezone xx/xx -setusingnetworktime on -setnetworktimeserver xx.xx.xx; jamf setComputerName -useSerialNumber; jamf policy -event XXX


Works great. After the reboot I have a few more policies on startup trigger (boostrap escrow, enable ARD / Kickstart etc.) then finally check in trigger for software install. Done 

New Contributor III

Is DEPNotify still necessary when we'll have Jamf Connect?

Valued Contributor III

Not specifically DEP notify but JAMF connect has a connect notify script you can use during the first login. 

Gabe Shackney
Princeton Public Schools