Dockutil not working on Catalina

hendersond
New Contributor III

We are using Dockutil to take everything off the Dock and the populate it with a few items the first time a user logs in. We have been using a similar script on High Sierra and Mojave for a few years and it works great. Below the script is the error message I receive. I am logging in using a dummy user called Scott Towels (TowelsS). After it bombs when Scott logs in, if I go in and flush the policy in Jamf and then login as Scott again, the script runs fine and the Dock is perfect. It almost appears that Catalina on first login has not fully finished creating the users directories, therefore the com.apple.dock.plist is not there yet when the script attempts to run

!/bin/sh

sleep 20
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 + " ");')

su $LoggedInUser -c '/usr/local/bin/dockutil --remove all --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Google Chrome.app --position 1 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Word.app --position 2 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Excel.app --position 3 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Calculator.app --position 4 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Acronis Files Connect.app --position 5 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Photos.app --position 6 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Music.app --position 7'

Executing Policy z2-Dockutil Catalina
Running script Dockutil Catalina...
Script exit code: 1
Script result: /Users/towelss/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
/Users/towelss/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist
[message repeats 6 times]
Error running script: return code was 1.

12 REPLIES 12

dsavageED
Contributor III

You can force launch the dock to create the preference.

#!/bin/sh
DOCK_PREF="/Users/$USER/Library/Preferences/com.apple.dock.plist"
if [ -f "${DOCK_PREF}" ]; then
    echo "Dock preference exists."
else
    su $USER -c /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock
     echo "Force launching the Dock."
fi

hendersond
New Contributor III

So do I tack on what you have wrote into my script at the beginning as shown below?

!/bin/sh

DOCK_PREF="/Users/$USER/Library/Preferences/com.apple.dock.plist"
if [ -f "${DOCK_PREF}" ]; then echo "Dock preference exists."
else su $USER -c /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock echo "Force launching the Dock."
fi

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 + " ");')

su $LoggedInUser -c '/usr/local/bin/dockutil --remove all --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Google Chrome.app --position 1 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Word.app --position 2 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Excel.app --position 3 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Calculator.app --position 4 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Acronis Files Connect.app --position 5 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Photos.app --position 6 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Music.app --position 7'

ryan_ball
Valued Contributor

@hendersond Why don't you wait until the Dock is launched before using dockutil rather than sleeping:

until [[ $(pgrep -x Dock) ]]; do
    wait
done

Plus you should make sure that "Perform login hook actions in background" is checked in your Jamf Pro Check-In settings.

hendersond
New Contributor III

I have two scripts that run. The first runs once per user per computer and it deletes all the items in the Dock and then adds back select items. I added this to the script
until [[ $(pgrep -x Dock) ]]; do wait
done

I also checked "Perform login hook actions in background"
I have another script that runs on login and is ongoing. It puts a file share into the Dock
I ran into two issue
1. The first script ran but it was about 12 seconds after the desktop appeared. In other words, the full Dock showed for 12 seconds and then the script ran and the Dock I wanted appeared. This is quite the delay
2. My second script ran the first time but every subsequent login would not run even though it was set for ongoing

There must be some differences in the way catalina handles all of this since all of this was working fine under High Sierra and Mojave

ryan_ball
Valued Contributor

How many other policies are running at login?

ryan_ball
Valued Contributor

If you are wanting something to happen at a specific time in the login process no matter what policies are being executed, it is better to have that done in a LaunchAgent in my opinion.

I made something a while back called DockBuilder that uses a LaunchAgent to kick off the process, but this might be a bit too complicated.

Also, is it not possible for everything to be done in 1 script, rather than 2?

hendersond
New Contributor III

The one script deletes everything out of the Dock and adds back in 7 items. This runs once per computer per user. From that point users and add or remove items from the Dock as needed. The other script adds a fileshare to the Dock that everyone uses. I have this one Ongoing. If a person deletes this fileshare from the Dock it should then reappear at next login hence the need for it to run on Login but on an Ongoing basis. There is certainly something different with Catalina since we have been using this same setup with High Sierra and Mojave for 3 years and it has worked perfect. As I mentioned this combination works perfect:
Added in the code snippet you provided that waits until the Dock is ready before running the rest of the script. This ensures that dock plist is there to manipulate
Checked the box to have "Perform login hook actions in background"
The users logs in, the first scripts which creates the Dock we want waits until the Dock is ready. It then runs and we get the proper Dock. The second script runs and puts the fileshare in the Dock. At this point everything is perfect. Even if the user logs off and back on, everything is perfect. If the user tosses the fileshare off the Dock, logs off and then back on the second script which is set to ongoing never runs (I see this in policy history in Jamf) and the fileshare never reappears

larry_barrett
Valued Contributor

What if you used smart groups as the trigger. E.g. Smart Group 1 is missing the fileshare. Smart Group 2 has the fileshare. Run script based on group membership?

I manage my dock using the built in JAMF tools, but only on shared lab computers.

ryan_ball
Valued Contributor

@hendersond post both of the scripts using the “>_” button so we can more easily check out the code. Redact the file share url if you need to.

hendersond
New Contributor III

First script that removes everything from the Dock and adds back 7 items. The policy associated with this script is set to Login, Once per computer per user

#!/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 + "
");')

su $LoggedInUser -c '/usr/local/bin/dockutil --remove all --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Google Chrome.app --position 1 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Word.app --position 2 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Microsoft Excel.app --position 3 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Calculator.app --position 4 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /Applications/Acronis Files Connect.app --position 5 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Photos.app --position 6 --no-restart'
su $LoggedInUser -c '/usr/local/bin/dockutil --add /System/Applications/Music.app --position 7'

Second script which puts a fileshare in the Dock. The policy associated with this script is set to Login, Ongoing

#!/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 + "
");')

su "$LoggedInUser" -c '/usr/local/bin/dockutil --add smb://fs1.vcs.local/Shared Files --label 'Shared Files' --position end'

hendersond
New Contributor III

I like the idea of using a Smartgroup to flag who is missing the fileshare I am not sure how to check whether the fileshare is in the Dock or not

larry_barrett
Valued Contributor

@hendersond Probably need to use an extension attribute where its either true or false. There's some good examples on here on how to do an Extension Attribute (EA), but I don't have a specific example for you.