Skip to main content

I have been using docutil for many years at this point (along with BuildADock). It works great. I am building a new lab and it's a weird setup. Not every computer will have the same versions of software installed (mainly Adobe) for some stupid licensing issues. I'm wondering if there is a way to use wildcards in the docutil script? For example, I have three sets of computers that have either Adobe CC 2023, 2024, or 2025. The software installs are the same, but the version year is different. Rather than make different docks for all the variations in the lab, is there a way to use a wildcard so it puts whichever version of Photoshop onto the dock that is installed onto the computer?

@kwoodard Do all of the different years of the Adobe apps have the same bundle ID? (I don't have any Adobe installs handy to check) If so you could use mdfind to find what app is installed by its bundle ID and then feed that to dockutil to create a Dock entry for it. Here's an example that looks for Chrome in the /Applications folder:


#!/bin/zsh

# Utility - List all Google Chrome apps in /Applications
#

AppBundleID="com.google.Chrome"
SearchLocation="/Applications"

# Find all copies of Chrome in the /Applications folder
OIFS=$IFS
IFS=$'\\n'
files=($(mdfind -onlyin "$SearchLocation" "kMDItemCFBundleIdentifier == $AppBundleID"))
IFS=$OIFS

# Loop through all found copies
for AppPath in "${files[@]}"
do
if [[ -e "$AppPath/Contents/Info.plist" ]]; then
echo $AppPath
fi
done

@kwoodard Do all of the different years of the Adobe apps have the same bundle ID? (I don't have any Adobe installs handy to check) If so you could use mdfind to find what app is installed by its bundle ID and then feed that to dockutil to create a Dock entry for it. Here's an example that looks for Chrome in the /Applications folder:


#!/bin/zsh

# Utility - List all Google Chrome apps in /Applications
#

AppBundleID="com.google.Chrome"
SearchLocation="/Applications"

# Find all copies of Chrome in the /Applications folder
OIFS=$IFS
IFS=$'\\n'
files=($(mdfind -onlyin "$SearchLocation" "kMDItemCFBundleIdentifier == $AppBundleID"))
IFS=$OIFS

# Loop through all found copies
for AppPath in "${files[@]}"
do
if [[ -e "$AppPath/Contents/Info.plist" ]]; then
echo $AppPath
fi
done

My scripting is still pretty terrible...how would I pass the output to docutil? I assume some sort of variable.


My scripting is still pretty terrible...how would I pass the output to docutil? I assume some sort of variable.


@kwoodard Think of it as an opportunity to improve :-) 


The basic dockutil command to add an item to the Dock is "dockutil --add <path to item>" so if you just wanted to add all items that were found by mdfind in my example above to the Dock you'd replace the 


 


echo $AppPath

 


with


dockutil --add "$AppPath"

 


@kwoodard Think of it as an opportunity to improve :-) 


The basic dockutil command to add an item to the Dock is "dockutil --add <path to item>" so if you just wanted to add all items that were found by mdfind in my example above to the Dock you'd replace the 


 


echo $AppPath

 


with


dockutil --add "$AppPath"

 


OK, that is kind of what I was thinking of trying later today. Thank you! I will report back if this works.


OK, that is kind of what I was thinking of trying later today. Thank you! I will report back if this works.


@kwoodard Were you able to successfully create a script to addd random versions of Photoshop to the Dock?


@kwoodard Were you able to successfully create a script to addd random versions of Photoshop to the Dock?


I have literally been working two jobs and have not had a chance to test. However, next week is the last week of instruction followed by a week of final exams. I already told my boss that I have to switch gears and work on my labs, so starting Monday, this is the first thing I will be working on. I have nearly 400 Macs that I use this with and about 12 unique docks to contend with. One modification I want to attempt is to create a master dock script that has all the software the labs use, but since the software isn’t installed on every computer, add some logic to the script that if the software is not installed, that dock item is not created (so there aren’t any ? icons). End user can still modify the dock after creation, but the initial dock will have our suggested default configuration. 


@kwoodard Were you able to successfully create a script to addd random versions of Photoshop to the Dock?


#!/bin/zsh

# List of specific bundle identifiers to add to the Dock
apps_to_add=(
"com.apple.Safari"
"com.apple.mail"
"com.google.Chrome"
"com.microsoft.Word"
)

# Path to dockutil
dockutil_path="/usr/local/bin/dockutil" # adjust if needed

# Optional: clear existing Dock items first
$dockutil_path --remove all --no-restart

# Process each bundle identifier
for bundle_id in "${apps_to_add[@]}"; do
app_path=$(mdfind "kMDItemCFBundleIdentifier == '$bundle_id'" | head -n 1)
if [[ -n "$app_path" && -e "$app_path" ]]; then
echo "Adding $app_path to Dock..."
"$dockutil_path" --add "$app_path" --no-restart
else
echo "App not found for bundle ID: $bundle_id"
fi
done

# Restart Dock once at the end
killall Dock

This is what I have come up with, but still working on it. I haven't had a chance to test, but I know the bits by themselves work. Will test and report back tomorrow.


OK, that is kind of what I was thinking of trying later today. Thank you! I will report back if this works.

@kwoodard Were you able to successfully create a script to addd random versions of Photoshop to the Dock?

OK. Got to spend some time on this and have a working script. Hope you and others find this helpful.

Considering making this a new thread as well to get more traction...what do you think?

#!/bin/zsh

# Get current user and home directory
currentUser=$(stat -f "%Su" /dev/console)
userHome=$(dscl . -read /Users/"$currentUser" NFSHomeDirectory | awk '{print $2}')
markerPlist="$userHome/Library/Preferences/com.ARC.docksetup.plist"

# --- 1. Check for existing Dock setup marker ---
if [ -f "$markerPlist" ]]; then
echo "Dock already set up for $currentUser. Exiting."
exit 0
fi

# --- 2. Wait for Dock process to be ready ---
echo "Waiting for Dock to launch..."
until pgrep -x Dock >/dev/null; do
sleep 1
done
echo "Dock is running. Proceeding..."

# --- 3. Define bundle IDs to add to Dock ---
bundleIDs=(
"com.apple.launchpad.launcher"
"com.apple.Safari"
"com.google.Chrome"
"com.apple.mail"
"com.apple.iCal"
"com.apple.Notes"
"com.microsoft.Word"
"com.microsoft.Excel"
"com.microsoft.Powerpoint"
"com.adobe.Acrobat.Pro"
"com.jamfsoftware.selfservice.mac"
"com.apple.systempreferences"
)

dockutil="/usr/local/bin/dockutil"

# --- 4. Ensure dockutil is installed ---
if [ ! -x "$dockutil" ]]; then
echo "dockutil not found at $dockutil. Please install it."
exit 1
fi

sleep 2

echo "Removing existing Dock items..."
$dockutil --remove all --no-restart "$userHome"
sleep 2

echo "Adding applications to the Dock from bundle IDs..."
for bundleID in "${bundleIDss@]}"; do
appPath=$(mdfind "kMDItemCFBundleIdentifier == '$bundleID'" | grep -m1 '\.app$')
if [ -n "$appPath" && -e "$appPath" ]]; then
echo "Adding: $appPath"
$dockutil --add "$appPath" --no-restart "$userHome"
sleep 1
else
echo "Could not find app for bundle ID: $bundleID"
fi
done

sleep 2

echo "Restarting Dock..."
killall Dock

# --- 5. Set Dock preferences: size and magnification ---
echo "Setting Dock preferences..."
defaults write com.apple.dock tilesize -int 36
defaults write com.apple.dock magnification -bool true
defaults write com.apple.dock largesize -int 64

# --- 6. Create marker plist to prevent re-running ---
echo "Creating marker plist to mark completion..."
defaults write "$markerPlist" setupComplete -bool true

# --- 7. Final Dock restart to apply preferences ---
killall Dock

echo "Dock setup complete for user: $currentUser"

 


Nice script. I added a couple of tweaks. 

  • Force reset of the dock even if flag file exists using -f or -F
  • Added --- for output for it to stand out better

    Adding applications to the Dock from bundle IDs...

    Adding: /System/Applications/Launchpad.app

    --- adding /System/Applications/Launchpad.app

    Adding: /Applications/Google Chrome.app

    --- adding /Applications/Google Chrome.app

    Adding: /Applications/Microsoft Edge.app

    --- adding /Applications/Microsoft Edge.app

#!/bin/zsh --no-rcs

# Get current user and home directory
currentUser=$(stat -f "%Su" /dev/console)
userHome=$(dscl . -read /Users/"$currentUser" NFSHomeDirectory | awk '{print $2}')
markerPlist="$userHome/Library/Preferences/com.ARC.docksetup.plist"

# --- 0. Force reset the dock with -f or -F
if [ ${1:u} == "-F" ]]; then
rm -rf "${markerPlist}"
fi
# --- 1. Check for existing Dock setup marker ---
if [ -f "${markerPlist}" ]]; then
echo "Dock already set up for $currentUser. Exiting."
exit 0
fi

# --- 2. Wait for Dock process to be ready ---
echo "Waiting for Dock to launch..."
until pgrep -x Dock >/dev/null; do
sleep 1
done
echo "Dock is running. Proceeding..."

# --- 3. Define bundle IDs to add to Dock ---
bundleIDs=(
"com.apple.launchpad.launcher"
"com.google.Chrome"
"com.microsoft.edgemac"
"com.microsoft.VSCode"
"com.microsoft.Word"
"com.microsoft.Excel"
"com.microsoft.Outlook"
"com.microsoft.teams2"
"com.github.atom"
"us.zoom.xos"
"com.apple.Preview"
"com.mothersruin.SuspiciousPackageApp"
"com.apple.Terminal"
"com.adobe.Photoshop"
"com.apple.ScreenSharing"
"com.apple.Stickies"
"com.jamfsoftware.Composer"
"com.apple.systempreferences"
"com.jamfsoftware.selfservice.mac"
)

dockutil="/usr/local/bin/dockutil"

# --- 4. Ensure dockutil is installed ---
if [ ! -x "$dockutil" ]]; then
echo "dockutil not found at $dockutil. Please install it."
exit 1
fi

sleep 2

echo "Removing existing Dock items..."
$dockutil --remove all --no-restart "$userHome"
sleep 2

echo "Adding applications to the Dock from bundle IDs..."
for bundleID in "${bundleIDss@]}"; do
appPath=$(mdfind "kMDItemCFBundleIdentifier == '$bundleID'" | grep -m1 '\.app$')
if [ -n "$appPath" && -e "$appPath" ]]; then
echo "Adding: $appPath"
echo "---" $($dockutil --add "$appPath" --no-restart "$userHome")
sleep 1
else
echo "Could not find app for bundle ID: $bundleID"
fi
done

sleep 2

echo "Restarting Dock..."
killall Dock

# --- 5. Set Dock preferences: size and magnification ---
echo "Setting Dock preferences..."
defaults write com.apple.dock tilesize -int 36
defaults write com.apple.dock magnification -bool true
defaults write com.apple.dock largesize -int 64

# --- 6. Create marker plist to prevent re-running ---
echo "Creating marker plist to mark completion..."
defaults write "$markerPlist" setupComplete -bool true

# --- 7. Final Dock restart to apply preferences ---
killall Dock

echo "Dock setup complete for user: $currentUser"

 


Nice script. I added a couple of tweaks. 

  • Force reset of the dock even if flag file exists using -f or -F
  • Added --- for output for it to stand out better

    Adding applications to the Dock from bundle IDs...

    Adding: /System/Applications/Launchpad.app

    --- adding /System/Applications/Launchpad.app

    Adding: /Applications/Google Chrome.app

    --- adding /Applications/Google Chrome.app

    Adding: /Applications/Microsoft Edge.app

    --- adding /Applications/Microsoft Edge.app

#!/bin/zsh --no-rcs

# Get current user and home directory
currentUser=$(stat -f "%Su" /dev/console)
userHome=$(dscl . -read /Users/"$currentUser" NFSHomeDirectory | awk '{print $2}')
markerPlist="$userHome/Library/Preferences/com.ARC.docksetup.plist"

# --- 0. Force reset the dock with -f or -F
if [ ${1:u} == "-F" ]]; then
rm -rf "${markerPlist}"
fi
# --- 1. Check for existing Dock setup marker ---
if [ -f "${markerPlist}" ]]; then
echo "Dock already set up for $currentUser. Exiting."
exit 0
fi

# --- 2. Wait for Dock process to be ready ---
echo "Waiting for Dock to launch..."
until pgrep -x Dock >/dev/null; do
sleep 1
done
echo "Dock is running. Proceeding..."

# --- 3. Define bundle IDs to add to Dock ---
bundleIDs=(
"com.apple.launchpad.launcher"
"com.google.Chrome"
"com.microsoft.edgemac"
"com.microsoft.VSCode"
"com.microsoft.Word"
"com.microsoft.Excel"
"com.microsoft.Outlook"
"com.microsoft.teams2"
"com.github.atom"
"us.zoom.xos"
"com.apple.Preview"
"com.mothersruin.SuspiciousPackageApp"
"com.apple.Terminal"
"com.adobe.Photoshop"
"com.apple.ScreenSharing"
"com.apple.Stickies"
"com.jamfsoftware.Composer"
"com.apple.systempreferences"
"com.jamfsoftware.selfservice.mac"
)

dockutil="/usr/local/bin/dockutil"

# --- 4. Ensure dockutil is installed ---
if [ ! -x "$dockutil" ]]; then
echo "dockutil not found at $dockutil. Please install it."
exit 1
fi

sleep 2

echo "Removing existing Dock items..."
$dockutil --remove all --no-restart "$userHome"
sleep 2

echo "Adding applications to the Dock from bundle IDs..."
for bundleID in "${bundleIDss@]}"; do
appPath=$(mdfind "kMDItemCFBundleIdentifier == '$bundleID'" | grep -m1 '\.app$')
if [ -n "$appPath" && -e "$appPath" ]]; then
echo "Adding: $appPath"
echo "---" $($dockutil --add "$appPath" --no-restart "$userHome")
sleep 1
else
echo "Could not find app for bundle ID: $bundleID"
fi
done

sleep 2

echo "Restarting Dock..."
killall Dock

# --- 5. Set Dock preferences: size and magnification ---
echo "Setting Dock preferences..."
defaults write com.apple.dock tilesize -int 36
defaults write com.apple.dock magnification -bool true
defaults write com.apple.dock largesize -int 64

# --- 6. Create marker plist to prevent re-running ---
echo "Creating marker plist to mark completion..."
defaults write "$markerPlist" setupComplete -bool true

# --- 7. Final Dock restart to apply preferences ---
killall Dock

echo "Dock setup complete for user: $currentUser"

 

What is the force reset for, not one that I have seen? The second part where it adds the icons to the dock, is that for logging purposes?


What is the force reset for, not one that I have seen? The second part where it adds the icons to the dock, is that for logging purposes?

  1. Let’s say you have a user that jacks up the dock so bad and calls for help, OR you change the default apps and want to test it. -f or -F is generally on most unix commands is force. So, the -f would remove the flag file and run the rest of the script — rebuilding the dock. You then don’t have to manually go an remove your flag file before running the script.
  2. Better logging purposes visually. Easier for your eyes to parse.

What is the force reset for, not one that I have seen? The second part where it adds the icons to the dock, is that for logging purposes?

  1. Let’s say you have a user that jacks up the dock so bad and calls for help, OR you change the default apps and want to test it. -f or -F is generally on most unix commands is force. So, the -f would remove the flag file and run the rest of the script — rebuilding the dock. You then don’t have to manually go an remove your flag file before running the script.
  2. Better logging purposes visually. Easier for your eyes to parse.

I understand. I have a script I run via Apple Remote Desktop that removes the users dockfile so the next time they sign in, the dock is recreated.