Posted on 02-02-2016 02:06 PM
Hey everyone,
I am new to Dockutil and am having an issue running the script while imaging. The laptops being imaged are 10.11.3 MacBook Airs and Pros. What I want out of Dockutil is to add Google Chrome and Slack to newly imaged docks. I have created a pkg of Dockutil to download on each machine during imaging as well as a dmg (captured in Composer) that moves the Dockutil script to the /usr/local/bin location. I also set up a policy to execute the command "sh /usr/local/bin/dockutiltest.sh" that runs upon login once per computer per user. Both the pkg and dmg are loaded and stored on the machine; however, when I look at the policy logs I get plist errors:
Executing Policy Execute Dockutil Script
Running command sh /usr/local/bin/dockutiltest.sh...
Result of command:
/var/root/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
/var/root/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
No matching processes were found
Running Recon...
Retrieving inventory preferences from https://casper.boost.caffeine.io:8443/...
Locating accounts...
Searching path: /Applications
Locating package receipts...
Locating software updates...
Locating printers...
If I'm on the machine's terminal and execute commands, it works. I'm not sure what else I can change/edit to make the script run either after it reboots from imaging or upon login. Here is the script I have in the dmg that should run on each machine:
/usr/local/bin/dockutil --add '/Applications/Slack.app'
/usr/local/bin/dockutil --add '/Applications/Google Chrome.app'
killall -KILL Dock
I also want to note that I know you can make policies that update the dock for you but I don't want to scope that to "all computers" because this should be solely on fresh imaged machines.
Any ideas or suggestions would be extremely helpful!!! Thanks guys!!
Posted on 02-02-2016 02:37 PM
I use a script and a launch agent to accomplish this per user.
#!/bin/bash
# Running checkSetupDone function to determine if the rest of this script needs to run.
# Yes, if $HOME/Library/Preferences/com.corp.docksetup.plist file does not exist.
# Otherwise, assume this setup script has already run for this user and does not
# need to run again.
checkSetupDone() {
if [ -f $HOME/Library/Preferences/com.corp.docksetup.plist ] ; then
exit 0
fi
}
configureDefaultDock() {
DOCKUTIL=/usr/local/bin/dockutil
$DOCKUTIL --remove all --no-restart
$DOCKUTIL --add '/Applications/Launchpad.app' --no-restart
$DOCKUTIL --add '/Applications/Safari.app' --no-restart
$DOCKUTIL --add '/Applications/Self Service.app' --no-restart
$DOCKUTIL --add '/Applications/Mission Control.app' --no-restart
$DOCKUTIL --add '/Applications/Microsoft Word.app' --no-restart
$DOCKUTIL --add '/Applications/Microsoft Outlook.app' --no-restart
$DOCKUTIL --add '/Applications/Microsoft PowerPoint.app' --no-restart
$DOCKUTIL --add '/Applications/Microsoft Excel.app' --no-restart
$DOCKUTIL --add '/Applications/Microsoft Lync.app' --no-restart
$DOCKUTIL --add '/Applications/Cisco/Cisco AnyConnect Secure Mobility Client.app' --no-restart
$DOCKUTIL --add '/Applications' --no-restart
$DOCKUTIL --add '~/Downloads'
touch $HOME/Library/Preferences/com.corp.docksetup.plist
}
checkSetupDone
configureDefaultDock
exit 0
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.company.dockSetup</string>
<key>ProgramArguments</key>
<array>
<string>/bin/sh</string>
<string>/Library/Scripts/companyDockSetup.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Posted on 02-02-2016 02:38 PM
@tayyreyes - to get mine to work, I had to reference the actual user in the dockutil command. Here's the beginning part of mine, that I think I adapted from someone else's script here on JAMF Nation:
#!/bin/sh
sleep 10
LoggedInUser=$3
LoggedInUserHome="/Users/$3"
plist=$LoggedInUserHome/Library/Preferences/com.apple.dock.plist
echo "Logged in user is $LoggedInUser"
echo "Logged in user's home $LoggedInUserHome"
if [ -e /usr/local/bin/dockutil ] ; then
dockutilVersion=`/usr/local/bin/dockutil --version`
echo "dockutil version: $dockutilVersion"
echo "Clearing Dock..."
sudo /usr/local/bin/dockutil --remove all --no-restart $LoggedInUserHome
echo "Adding Launchpad..."
sudo /usr/local/bin/dockutil --add '/Applications/Launchpad.app' --no-restart $LoggedInUserHome
echo "Adding Self Service..."
sudo /usr/local/bin/dockutil --add '/Applications/Self Service.app' --no-restart $LoggedInUserHome
echo "Adding Google Chrome..."
sudo /usr/local/bin/dockutil --add '/Applications/Google Chrome.app' --no-restart $LoggedInUserHome
else
echo "dockutil not installed, skipping initial dock setup..."
fi
Posted on 02-02-2016 02:40 PM
Hi @tayyreyes I would say the main issue is because the Casper Suite will run scripts in a root context by default. Dockutil expects to be operating on the Dock plist of the user running the script, unless its directed to run on the plist at a different location.
The main error in the output under Result of command where it says:
/var/root/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
Is what reveals the issue.
To resolve this, you can use the built in Casper Suite script parameter of $3, which resolves to the logged in user's name to help locate the correct Dock.plist to operate on. Very simple example:
#!/bin/sh
/usr/local/bin/dockutil --add '/Applications/Slack.app' /Users/$3
Also, I'm not sure I understand what you meant by "I also set up a policy to execute the command "sh /usr/local/bin/dockutiltest.sh" that runs upon login" Do you mean you deployed your dockutil script to the machine and then have it being run by a policy later? If so, its not strictly necessary to do this. Certainly possible, but the Casper Suite can just download and run the script directly from your JSS when the policy runs, rather than pre-deploying the script. Also, doing it that will let you use the $3 variable.
Hope that helps. Post back if you have more questions.
Posted on 02-02-2016 02:47 PM
Thank you @jhbush1973 and @jkuo! I will check your scripts out and see if I can get them to apply to our settings.
Also, thanks @mm2270 for explaining that error. Your explanation makes sense and I want to test using $3 to see if this works. Should I add this to the script itself that's in the dmg I created to specify the file location? Or should I update the script and add it to Casper Admin to add that file on the image itself? Thanks again!
Posted on 02-02-2016 03:02 PM
@tayyreyes - no problem!
Regarding the $3, you would just use it in the script (see the variable LoggedInUserHome in my example, or /Users/$3 in @mm2270 's example), and then you can set a Casper policy for the script to run on login.
Posted on 02-02-2016 03:31 PM
@tayyreyes, just keep in mind that $3 actually only works in 3 triggers that I know of - login, logout and Self Service. If a script is run under any other trigger, it won't understand $3 as being the logged in user. But since you said you were running a script at login, this should work OK to use it.
As for using $3 in a script that is called by a command directly to the path of the script to run it, well, I guess it will work, but honestly I've never done it that way, so I don't know. Usually I let Casper run my scripts for me by adding the script directly into a policy, rather than deploying a file down first and then having it run the script by its path.
If you want to deploy the script file, and you find its not working with $3 in it for some reason, your choices would be:
/usr/local/jamf/bin/jamf runScript -script dockutiltest.sh -path /usr/local/bin/
The syntax is a little odd, but basically, you put in the script name only after the -script flag, then the path to the script only after the -path flag. That runs the script the same as if the policy downloaded it from the JSS and ran it directly.
Posted on 02-02-2016 03:40 PM
@jhbush1973 I actually just tried out your script and it works great when I push it out to a test machine via Casper Remote. I want to continue to test this out with imaging but quick question with your second script. Is that the launch agent that calls for the 1st script to run at reboot? How do you incorporate that? Do you put it as a file in a certain location? Or did you create a policy for that script to run?
Posted on 02-02-2016 04:48 PM
Tried putting the script in a policy with the "login" trigger. Here is the script (using @jhbush1973's script as reference ) that works when I remotely push it to the laptop via Casper Remote:
configureDefaultDock() { DOCKUTIL=/usr/local/bin/dockutil
$DOCKUTIL --remove all --no-restart
$DOCKUTIL --add '/Applications/Launchpad.app' --no-restart
$DOCKUTIL --add '/Applications/Safari.app' --no-restart
$DOCKUTIL --add '/Applications/Calendar.app' --no-restart
$DOCKUTIL --add '/Applications/Notes.app' --no-restart
$DOCKUTIL --add '/Applications/Photos.app' --no-restart
$DOCKUTIL --add '/Applications/App Store.app' --no-restart
$DOCKUTIL --add '/Applications/System Preferences.app' --no-restart
$DOCKUTIL --add '/Applications/Google Chrome.app' --no-restart
$DOCKUTIL --add '/Applications/Slack.app' --no-restart
$DOCKUTIL --add '/Applications/Self Service.app' --no-restart
$DOCKUTIL --add '~/Downloads'
touch $HOME/Library/Preferences/com.corp.docksetup.plist
}
configureDefaultDock
killall -KILL Dock
Sending remotely it loads correctly and looks good. However, when putting it in a policy, it doesn't update on the scoped machine. It will restart the Finder showing the script is being ran but it doesn't show up the way I set it to. Any ideas?
Posted on 02-02-2016 04:57 PM
I'd try it with the home directory immediately after the --no-restart, e.g. the /Users/$3 or the $LoggedInUserHome examples from above.
Posted on 02-02-2016 08:55 PM
@tayyreyes in reference to @jhbush1973's script, his was being run by a LaunchAgent, which actually runs scripts or commands as the logged in user. As such, his script doesn't need to have the path to a home directory for dockutil to work on, since it can only be running as the logged in user. That's just how LaunchAgents work.
When you place that same script into a policy, again, its going to run the dockutil commands as 'root' So you run into the same issue as before where its not able to affect the changes since its expecting to make changes to the root account's Dock, not the user's Dock that's logged in.
As @jkuo mentioned, you can add the user home with /Users/$3
, or /Users/$loggedInUser
or whatever at the end of each dockutil line and that should address the issue.
Posted on 02-03-2016 05:42 PM
+1 on having trouble with dockutil. So I watered down the examples to this
#!/bin/bash LoggedInUser=$3 LoggedInUserHome="/Users/$3" plist=$LoggedInUserHome/Library/Preferences/com.apple.dock.plist echo "Logged in user is $LoggedInUser" echo "Logged in user's home $LoggedInUserHome" sudo /usr/local/bin/dockutil --add '/Applications/Notes.app' $LoggedInUserHome
I ran it by calling the JamF binary such as /usr/local/jamf/bin/jamf runScript -script dockutiltest.sh -path /usr/local/bin/ and I get this result:
Running script dutest.sh... Script exit code: 1 Script result: Logged in user is Logged in user's home /Users/ /Users/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
Notice the it's not resolving the logged in user or the user's home. Why?
Posted on 02-03-2016 06:28 PM
@ericyue You can't use $3 to resolve to the username when a script is run normally in Terminal. It only applies when a script is called by the jamf binary during login, logout and Self Service, and perhaps one other time I'm not thinking of. But when you run it with sudo jamf runScript, etc.
it has no idea what $3 means, so that's why its not working.
This is generally why I avoid using $3 in my scripts. While its nice to just drop that in and have it work, its limited, since it won't work in all instances where a script might be called. For the sake of greater flexibility and portability, I prefer to use a method similar to what @jkuo posted several posts above to get the logged in user name. The one I've been using more lately is:
stat -f%Su /dev/console
If you replace
loggedInUser=$3
with
loggedInUser=$(stat -f%Su /dev/console)
and try it again it should work,
Posted on 02-04-2016 11:54 AM
Thank you guys for all your help! I wasn't able to figure out how to put the script into my image but instead I created a policy. Here is the final script that worked for us:
LoggedInUser=$3
LoggedInUserHome="/Users/$3"
configureDefaultDock() {
echo "Logged in user is $LoggedInUser" echo "Logged in user's home $LoggedInUserHome"
if [ -e /usr/local/bin/dockutil ] ; then
dockutilVersion=/usr/local/bin/dockutil --version
echo "dockutil version: $dockutilVersion"
echo "Clearing Dock..."
/usr/local/bin/dockutil --remove all --no-restart $LoggedInUserHome
echo "Adding Launchpad..." /usr/local/bin/dockutil --add '/Applications/Launchpad.app' --no-restart $LoggedInUserHome echo "Adding Safari..." /usr/local/bin/dockutil --add '/Applications/Safari.app' --no-restart $LoggedInUserHome echo "Adding Calendar..." /usr/local/bin/dockutil --add '/Applications/Calendar.app' --no-restart $LoggedInUserHome echo "Adding Notes..." /usr/local/bin/dockutil --add '/Applications/Notes.app' --no-restart $LoggedInUserHome echo "Adding Photos..." /usr/local/bin/dockutil --add '/Applications/Photos.app' --no-restart $LoggedInUserHome echo "Adding App Store..." /usr/local/bin/dockutil --add '/Applications/App Store.app' --no-restart $LoggedInUserHome echo "Adding System Preferences..." /usr/local/bin/dockutil --add '/Applications/System Preferences.app' --no-restart $LoggedInUserHome echo "Adding Google Chrome..." /usr/local/bin/dockutil --add '/Applications/Google Chrome.app' --no-restart $LoggedInUserHome echo "Adding Slack..." /usr/local/bin/dockutil --add '/Applications/Slack.app' --no-restart $LoggedInUserHome echo "Adding Self Service..." /usr/local/bin/dockutil --add '/Applications/Self Service.app' --no-restart $LoggedInUserHome echo "Adding Downloads..." /usr/local/bin/dockutil --add '~/Downloads' --no-restart $LoggedInUserHome
touch $LoggedInUserHome/Library/Preferences/com.company.docksetup.plist
else echo "dockutil not installed, skipping initial dock setup..." fi
}
configureDefaultDock
killall -KILL Dock
exit 0
Thanks again!!!
Posted on 09-06-2016 06:03 PM
@tayyreyes Do you still use this script?
I've created my own version for 10.11 using yours and others I've found and nothing seems to work.
Here's mine:
#!/bin/sh
LoggedInUser=$(python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
LoggedInUserHome="/Users/$LoggedInUser"
configureDefaultDock() {
echo "Logged in user is $LoggedInUser"
echo "Logged in user's home $LoggedInUserHome"
if -e '/usr/local/bin/dockutil'
then dockutilVersion=$(/usr/local/bin/dockutil --version)
echo "dockutil version: $dockutilVersion"
echo "Clearing Dock..." /usr/local/bin/dockutil --remove all --no-restart "$LoggedInUserHome"
echo "Adding Launchpad..." /usr/local/bin/dockutil --add '/Applications/Launchpad.app' --no-restart --position 1 "$LoggedInUserHome"
echo "Adding Calendar..." /usr/local/bin/dockutil --add '/Applications/Calendar.app' --no-restart --position 2 "$LoggedInUserHome"
echo "Adding TextEdit..." /usr/local/bin/dockutil --add '/Applications/TextEdit.app' --no-restart --position 3 "$LoggedInUserHome"
echo "Adding App Store..." /usr/local/bin/dockutil --add '/Applications/App Store.app' --no-restart --position 4 "$LoggedInUserHome"
echo "Adding Google Chrome..." /usr/local/bin/dockutil --add '/Applications/Google Chrome.app' --no-restart --position 5 "$LoggedInUserHome"
echo "Adding GarageBand..." /usr/local/bin/dockutil --add '/Applications/GarageBand.app' --no-restart --position 6 "$LoggedInUserHome"
echo "Adding Applications..." /usr/local/bin/dockutil --add '~/Applications' --no-restart --position 7 "$LoggedInUserHome"
echo "Adding Downloads..." /usr/local/bin/dockutil --add '~/Downloads' --no-restart --position 8 "$LoggedInUserHome"
touch "$LoggedInUserHome"/Library/Preferences/com.company.docksetup.plist
else echo "dockutil not installed, skipping initial dock setup..."
fi
}
configureDefaultDock
killall -KILL Dock
exit 0
I get "line 11: -e: command not found"
The dockutil file is definitely in /usr/local/bin/, but it doesn't appear to find it.
Is there some strange condition when using -e that it has to be a regular file, or have an extension?
Posted on 09-06-2016 06:49 PM
just wondering why are you guys using scripts if you can use Policy instead.
i got mine working by creating Dock Items and Policy to run once per user per computer.
Posted on 09-06-2016 09:24 PM
@khey This doesn't solve the issue of OS X adding unnecessary apps to the Dock and from what I've read the Dock Items policy is really inconsistent.
Posted on 09-06-2016 10:01 PM
Posted on 10-27-2017 08:19 AM
Scripts execute as the root user so unless you run that as the logged in user it will be trying to modify the root account's dock.