A docutil idea

Bartoo
New Contributor III

that right now I've no idea how to execute!

Like everyone else, we're using it to set our docks, removing the default stuff from the dock that we don't need (like Mail, Photo Booth, etc) and adding the ones the user will need daily (Word, Outlook, etc).

Currently, we're doing this with three scripts that load the dock with apps associated with one of three builds we roll out. That's working just fine. But we always have a few users/job roles that have an app or four that isn't part of one of the three builds, so we add that manually. Moreover, I've been tasked with making docutil usable not just for my division, but several, each with multiple builds with their own specific apps and their own occasional exceptions.

So here's the idea for the script. Rather than statically use docutil to add a string of apps, that hopefully fits the apps installed with each build, the script contains a set of all our "approved" apps, then searches against /Applications/ for matches. Any matches are then added via dockutil.

The only maintenance on this script would be to add, as they become part of our loadouts, any new apps to the approved list and the docutil command to add it to the dock.

3 REPLIES 3

roiegat
Contributor III

I haven't used ducutil, but if there is a way to script it then what I would do is create a script that has your basic dock items you need, then use the parameters in the script grab the rest ($4, $5, etc). Scripts can accept up to 8 parameters so you should be able to fine tune it for your needs.

stevewood
Honored Contributor II
Honored Contributor II

@Bartoo one way would be to create a dictionary, or array, of the apps in a script and then iterate through that dictionary with an if/then loop or a case statement that then executes the appropriate dockutil command. The psuedo-code could look something like this:

appList={all of the apps}
counter=0
if $appList[$counter] then
dockutil --add $appList[$counter]
counter=counter+1
fi

Again, that's only psuedo-code but could be hashed out in Bash or Python.

Look
Valued Contributor III

My implementation uses a folder full of plist files that contain items required, the AD group of users that the item is relvant to and a string of arguments for dockutil.
A script is run from a launchagent that reads all the *.dockitems files in the folder and checks if each item in each file is available and relevant to the current user and then adds it using dockutil if it is.
I also have a flag file written to the user profile so that this only happen once on first login, but is easy to reset for a specific user if required.
If you want to add additional items to a machine or user you simply drop another plist file in the folder with the info you want.

This was written some time ago now and probably needs a rework, however we don't need that until next December so probably not going to happen before then.

This is the script (slightly sanitised to remove organistation references in flag files).

#!/bin/bash
# Clears the Dock
# Adds the contents of all .dock files in /Library/Scripts/DockItems
# Relaunches the Dock
# Only runs once per user

##Wait for Finder
Run_Count=0
Run_Delay=5
Run_Limit=10
while [[ ! "$(ps -c -u $USER | awk /Finder/)" ]] && [[ $Run_Count -lt $Run_Limit ]] && [[ ! -f ~/Library/Preferences/org.yourorg.Dock.plist ]]; do
sleep $Run_Delay
let Run_Count=$Run_Count+1
done
sleep 10

##Initial Variables
DOCK_UTIL="/Library/Scripts/DockItems/dockutil"
ITEM_STORE="/Library/Scripts/DockItems/"

echo "Pop Dock run Started for "$USER" at "$(date) > ~/Library/Logs/popDock.log
IFS=$'
'
if [[ "$(ls "$ITEM_STORE" | awk /DockItems.plist/)" ]]  && [[ ! -f ~/Library/Preferences/org.yourorg.Dock.plist ]];then
$DOCK_UTIL --remove all --no-restart
for CONFIG in "$ITEM_STORE"*.DockItems.plist
do
echo >> ~/Library/Logs/popDock.log
echo $CONFIG >> ~/Library/Logs/popDock.log
if [ "$(/usr/libexec/PlistBuddy -c "print :" "$CONFIG" | awk -F" =" '/= Dict/ { print $1 }' | sed -e 's/^[[:space:]]*//')" ]
then
    for DOCK_ITEM in $(/usr/libexec/PlistBuddy -c "print :" "$CONFIG" | awk -F" =" '/= Dict/ { print $1 }' | sed -e 's/^[[:space:]]*//')
    do
    APP_PATH=$(/usr/libexec/PlistBuddy -c "print :"$DOCK_ITEM":path" "$CONFIG")
    APP_PATH=$(echo $APP_PATH | sed 's,~,'$(echo ~)',g')
    if [ -a "$APP_PATH" ]
    then    
        ARG=$(/usr/libexec/PlistBuddy -c "print :"$DOCK_ITEM":argument" "$CONFIG")
        SCOPE=$(/usr/libexec/PlistBuddy -c "print :"$DOCK_ITEM":scope" "$CONFIG")
        if [ -z "$SCOPE" ] || [ "$SCOPE" == "all" ] || [ "$SCOPE" == "All" ]
        then
            SCOPE="ALL"
        fi
        if [ "$SCOPE" == "ALL" ] || [ "$(id | awk /$SCOPE/)" ]
        then
        echo "ADDING $DOCK_ITEM with path: $APP_PATH Scope: $SCOPE argument: $ARG" >> ~/Library/Logs/popDock.log
        IFS=" "
        $DOCK_UTIL --add "$APP_PATH" $ARG --no-restart
        IFS=$'
'
        else
        echo "SKIPPING $DOCK_ITEM as user is not a member of $SCOPE" >> ~/Library/Logs/popDock.log
        fi
    else
        echo "$DOCK_ITEM NOT FOUND! path: $APP_PATH" >> ~/Library/Logs/popDock.log
    fi
    done
else
    echo "No items detected in $CONFIG" >> ~/Library/Logs/popDock.log
fi
done
$DOCK_UTIL --add /Applications/Launchpad.app --position first
touch ~/Library/Preferences/org.yourorg.Dock.plist
else
echo >> ~/Library/Logs/popDock.log
echo "FINISHING no config found or dock already configured" >> ~/Library/Logs/popDock.log
fi
echo >> ~/Library/Logs/popDock.log
echo "Pop Dock run finished for "$USER" at "$(date) >> ~/Library/Logs/popDock.log

This is a sample .dockitems file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Home</key>
    <dict>
        <key>path</key>
        <string>~/</string>
        <key>argument</key>
        <string>--view list --display folder --position first</string>
        <key>scope</key>
        <string>ALL</string>
    </dict>   
    <key>Adobe Apps</key>
    <dict>
        <key>path</key>
        <string>/Users/Shared/Adobe Apps/</string>
        <key>argument</key>
        <string>--view list --display stack --position middle</string>
        <key>scope</key>
        <string>ALL</string>
    </dict>   
    <key>Downloads</key>
    <dict>
        <key>path</key>
        <string>~/Downloads</string>
        <key>argument</key>
        <string>--view list --display folder --position last</string>
        <key>scope</key>
        <string>ALL</string>
    </dict>   
</dict>
</plist>