Skip to main content
Solved

Deploy a default dock layout after the enrollment, where the end-user can change it after.

  • March 26, 2026
  • 6 replies
  • 64 views

KeremDurdabak
Forum|alt.badge.img+1

Hi, I want to deploy an initial default Dock layout after enrollment is completed, where the end user can later change it to whatever suits them.

I’ve heard of multiple methods, such as using Dock items in Jamf Pro settings, scripts, Outset with docklib, and dockutil. I was wondering what the easiest and most hassle-free approach would be as an MDM administrator. Thanks in advance.

Best answer by mvu

We use dockutil in tandem with Jamf Setup Manager.

docktil is easy to setup. Set it, forget it. Users can do whatever with the Dock after.


• Basically two parts. Push the dockutil package. Push a dockutil script that you customize with Dock items you want.


• Link: https://github.com/kcrawford/dockutil

• Link: https://github.com/mvdbent/setDock/blob/main/setDock-defaultDock.sh (Edited link: Script I use)

6 replies

FerrisBNA
Forum|alt.badge.img+4
  • Contributor
  • March 26, 2026

I don’t know the origin of the original script, but here is what I use during enrollment.  After it runs, the end-user can modify the dock however they choose.

#!/bin/bash

# ---------------------------------------------------------------------------
# Jamf Pro Script: Reset and Rebuild Dock for Logged-In User (macOS-safe)
# Uses launchctl asuser + sudo -u (no runuser)
# ---------------------------------------------------------------------------

# Paths (explicit to avoid PATH surprises)
STAT="/usr/bin/stat"
PGREP="/usr/bin/pgrep"
LAUNCHCTL="/bin/launchctl"
SUDO="/usr/bin/sudo"
KILLALL="/usr/bin/killall"
SLEEP="/bin/sleep"

# Get the logged-in console user
loggedInUser=$($STAT -f "%Su" /dev/console)

# Verify a user is logged in
if [ "$loggedInUser" = "root" ] || [ -z "$loggedInUser" ]; then
echo "No logged-in user detected. Exiting."
exit 1
fi

loggedInUID=$(/usr/bin/id -u "$loggedInUser")
echo "Detected logged-in user: $loggedInUser (UID: $loggedInUID)"

# ---------------------------------------------------------------------------
# Wait for Finder and Dock to be running (max wait = 60 seconds)
# ---------------------------------------------------------------------------
timeout=60
elapsed=0
while true; do
finderPID=$($PGREP -x Finder)
dockPID=$($PGREP -x Dock)

if [[ -n "$finderPID" && -n "$dockPID" ]]; then
echo "Finder (PID: $finderPID) and Dock (PID: $dockPID) are active."
break
fi

if (( elapsed >= timeout )); then
echo "Timeout waiting for Finder/Dock. Proceeding anyway."
break
fi

echo "Waiting for Finder and Dock... (${elapsed}/${timeout}s)"
$SLEEP 2
((elapsed+=2))
done

# ---------------------------------------------------------------------------
# Commands to run as the logged-in user
# Note: we set a safe PATH and quote app paths with spaces.
# ---------------------------------------------------------------------------
read -r -d '' userCommand <<'EOF'
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

# Kill any installer process running
killall Installer 2>/dev/null || true
sleep 5

/usr/local/bin/dockutil --remove all --no-restart || true
sleep 10

/usr/local/bin/dockutil --add "/Applications/Adobe Acrobat Reader.app" --position 2 --no-restart
/usr/local/bin/dockutil --add "/Applications/Cisco/Cisco Secure Client.app" --position 3 --no-restart
/usr/local/bin/dockutil --add "/Applications/Google Chrome.app" --position 4 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Edge.app" --position 5 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Excel.app" --position 6 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft OneNote.app" --position 7 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Outlook.app" --position 8 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft PowerPoint.app" --position 9 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Teams.app" --position 10 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Word.app" --position 11 --no-restart
/usr/local/bin/dockutil --add "/Applications/OneDrive.app" --position 12 --no-restart
/usr/local/bin/dockutil --add "/Applications/Windows App.app" --position 13 --no-restart
/usr/local/bin/dockutil --add "/Applications/Safari.app" --position 14 --no-restart
/usr/local/bin/dockutil --add "/Applications/Self Service.app" --position 15 --no-restart
/usr/local/bin/dockutil --add "/Applications/System Settings.app" --position 16 --no-restart
/usr/local/bin/dockutil --add "/Applications/zoom.us.app" --position 17 --no-restart

/usr/local/bin/dockutil --add "/Applications" --view list --no-restart
/usr/local/bin/dockutil --add "~/Desktop" --view list --no-restart
/usr/local/bin/dockutil --add "~/Downloads" --view list --no-restart

sleep 5
killall Dock || true
EOF

# ---------------------------------------------------------------------------
# Execute as the logged-in user in their GUI session
# ---------------------------------------------------------------------------
echo "Running Dock rebuild as $loggedInUser..."
$LAUNCHCTL asuser "$loggedInUID" $SUDO -u "$loggedInUser" /bin/bash -lc "$userCommand"
rc=$?

echo "Dock rebuild finished with exit code: $rc"
exit $rc

 


KeremDurdabak
Forum|alt.badge.img+1
  • Author
  • New Contributor
  • March 26, 2026

I don’t know the origin of the original script, but here is what I use during enrollment.  After it runs, the end-user can modify the dock however they choose.

#!/bin/bash

# ---------------------------------------------------------------------------
# Jamf Pro Script: Reset and Rebuild Dock for Logged-In User (macOS-safe)
# Uses launchctl asuser + sudo -u (no runuser)
# ---------------------------------------------------------------------------

# Paths (explicit to avoid PATH surprises)
STAT="/usr/bin/stat"
PGREP="/usr/bin/pgrep"
LAUNCHCTL="/bin/launchctl"
SUDO="/usr/bin/sudo"
KILLALL="/usr/bin/killall"
SLEEP="/bin/sleep"

# Get the logged-in console user
loggedInUser=$($STAT -f "%Su" /dev/console)

# Verify a user is logged in
if [ "$loggedInUser" = "root" ] || [ -z "$loggedInUser" ]; then
echo "No logged-in user detected. Exiting."
exit 1
fi

loggedInUID=$(/usr/bin/id -u "$loggedInUser")
echo "Detected logged-in user: $loggedInUser (UID: $loggedInUID)"

# ---------------------------------------------------------------------------
# Wait for Finder and Dock to be running (max wait = 60 seconds)
# ---------------------------------------------------------------------------
timeout=60
elapsed=0
while true; do
finderPID=$($PGREP -x Finder)
dockPID=$($PGREP -x Dock)

if [[ -n "$finderPID" && -n "$dockPID" ]]; then
echo "Finder (PID: $finderPID) and Dock (PID: $dockPID) are active."
break
fi

if (( elapsed >= timeout )); then
echo "Timeout waiting for Finder/Dock. Proceeding anyway."
break
fi

echo "Waiting for Finder and Dock... (${elapsed}/${timeout}s)"
$SLEEP 2
((elapsed+=2))
done

# ---------------------------------------------------------------------------
# Commands to run as the logged-in user
# Note: we set a safe PATH and quote app paths with spaces.
# ---------------------------------------------------------------------------
read -r -d '' userCommand <<'EOF'
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

# Kill any installer process running
killall Installer 2>/dev/null || true
sleep 5

/usr/local/bin/dockutil --remove all --no-restart || true
sleep 10

/usr/local/bin/dockutil --add "/Applications/Adobe Acrobat Reader.app" --position 2 --no-restart
/usr/local/bin/dockutil --add "/Applications/Cisco/Cisco Secure Client.app" --position 3 --no-restart
/usr/local/bin/dockutil --add "/Applications/Google Chrome.app" --position 4 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Edge.app" --position 5 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Excel.app" --position 6 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft OneNote.app" --position 7 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Outlook.app" --position 8 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft PowerPoint.app" --position 9 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Teams.app" --position 10 --no-restart
/usr/local/bin/dockutil --add "/Applications/Microsoft Word.app" --position 11 --no-restart
/usr/local/bin/dockutil --add "/Applications/OneDrive.app" --position 12 --no-restart
/usr/local/bin/dockutil --add "/Applications/Windows App.app" --position 13 --no-restart
/usr/local/bin/dockutil --add "/Applications/Safari.app" --position 14 --no-restart
/usr/local/bin/dockutil --add "/Applications/Self Service.app" --position 15 --no-restart
/usr/local/bin/dockutil --add "/Applications/System Settings.app" --position 16 --no-restart
/usr/local/bin/dockutil --add "/Applications/zoom.us.app" --position 17 --no-restart

/usr/local/bin/dockutil --add "/Applications" --view list --no-restart
/usr/local/bin/dockutil --add "~/Desktop" --view list --no-restart
/usr/local/bin/dockutil --add "~/Downloads" --view list --no-restart

sleep 5
killall Dock || true
EOF

# ---------------------------------------------------------------------------
# Execute as the logged-in user in their GUI session
# ---------------------------------------------------------------------------
echo "Running Dock rebuild as $loggedInUser..."
$LAUNCHCTL asuser "$loggedInUID" $SUDO -u "$loggedInUser" /bin/bash -lc "$userCommand"
rc=$?

echo "Dock rebuild finished with exit code: $rc"
exit $rc

 

Hi, I am using Jamf Setup Manager, does this require me to install DockUtil on the Setup Manager on behalf of the user first? Also, can I trigger it on the Setup Manager and after login it will just work automatically? Thanks!

 

Chubs
Forum|alt.badge.img+24
  • Jamf Heroes
  • March 26, 2026

What Pat said.  So if you set it with a utility (jamf or otherwise) it almost sets a “desired state” of the Dock.  If you set it with a script, it’s “one and done”.  

Up to you - I’d do some testing though to see what works.  IMO if you’re going to let them modify the Dock, then just keep it standard.


mvu
Forum|alt.badge.img+22
  • Jamf Heroes
  • Answer
  • March 26, 2026

We use dockutil in tandem with Jamf Setup Manager.

docktil is easy to setup. Set it, forget it. Users can do whatever with the Dock after.


• Basically two parts. Push the dockutil package. Push a dockutil script that you customize with Dock items you want.


• Link: https://github.com/kcrawford/dockutil

• Link: https://github.com/mvdbent/setDock/blob/main/setDock-defaultDock.sh (Edited link: Script I use)


KeremDurdabak
Forum|alt.badge.img+1
  • Author
  • New Contributor
  • March 27, 2026

We use dockutil in tandem with Jamf Setup Manager.

docktil is easy to setup. Set it, forget it. Users can do whatever with the Dock after.


• Basically two parts. Push the dockutil package. Push a dockutil script that you customize with Dock items you want.


• Link: https://github.com/kcrawford/dockutil

• Link: https://github.com/mvdbent/setDock/blob/main/setDock-defaultDock.sh (Edited link: Script I use)

Hi, this works really well actually, Thank you so much for your answer!


FerrisBNA
Forum|alt.badge.img+4
  • Contributor
  • March 27, 2026

We use dockutil in tandem with Jamf Setup Manager.

docktil is easy to setup. Set it, forget it. Users can do whatever with the Dock after.


• Basically two parts. Push the dockutil package. Push a dockutil script that you customize with Dock items you want.


• Link: https://github.com/kcrawford/dockutil

• Link: https://github.com/mvdbent/setDock/blob/main/setDock-defaultDock.sh (Edited link: Script I use)

After reviewing this script, I accept defeat :-)

All seriousness, very nice find, very clean.

-Pat