I always prefered to create dock items or entries to enhance the user experience on my managed macOS clients. Not so savy macOS user can find their newly installed applications easily in the dock (in my experience especially Windows users think that the dock is their only way to start software) and experienced user simply get a good indication, that the software was successfully installed (the feedback of Jamf’s Self Service is a bit lacking in my opinion).

In the past I used great tools like dockutil or docklib to manage dockitems. I predeployed these binaries, and used scripts in the Self Service policies (after the installation) to create the dock items.

And yet I searched for an alternative, when I started to build up a new Jamf instance. Dockutil triggers a deprecation warning on macOS 12 Montery (see this issue), since it’s running on python 2.7. You could supress the warning (see Graham’s great blog post), but I didn’t want to build up a new instance with workarounds.

Docklib is working great on Montery, but seemed a bit overkill for my needs. I only want to add dock items of applications at the end of the dock. No need for precise positioning or creating dock items for multiple users on a single machine.

Jamf’s Dock Items

Jamf Pro provides a mechanism to create dock items for a long time. You can predefine the item in the global settings under Computer Management:

Jamf Pro Dock Items

After defining them, you can use the item in a policy in the Dock Item Section:

Jamf Pro Dock Item in Policy

You have the possability to add the item to the end or the beginning of the dock, or remove it.

Drawbacks compared to the other solutions

Like I already mentioned, you are not able to postion the item precisely. But there are also other positive and negative aspects compared to docklib and dockutil:

Positive

  • No custom binary needed on the client (which needs to be installed first and updated) -> Less overhead
  • No python dependency -> No need to manage and install python3 like when you want to use docklib
  • Fully manageable via AutoPKG with my written custom processor
  • Easy to use

Negative

  • Pretty unflexible
  • Not suitable for multiuser deployments
  • No way to control dock restarts (the dock process get’s always killed by Jamf. This causes a ‘screen flashing’ for the user and minimized apps open up again)

Usage via AutoPKG

I guess Jamf’s Dock Items weren’t used often in the “macOS Automation Community”, since a lot of ‘mouse work’ was needed to create a dock entry (create it first in the general settings, switch back to the policy and add it there…).

So I decided to write a AutoPKG custom processor, which could be used in recipes to create dock entries and automate the process. I took Graham Pugh’s great JamfUploader as a base, and wrote some code to use Jamf’s API (sadly the classic API is needed, since there is no way to create dock items in the v2 API).

Graham was so kind to merge my code into his repo, so you can find the processor in his default recipe repo: autopkg/grahampugh-recipes. If you use already his uploaders, simply update the repo. If you never used his processors, add the repo to AutoPKG: autopkg repo-add grahampugh-recipes.

After that you can simply use the processor com.github.grahampugh.jamf-upload.processors/JamfDockItemUploader in your recipes. For example:

[...]

Input:
  NAME: MozillaFirefox
  [...]
  DOCK_ITEM_NAME: '%NAME%'
  DOCK_ITEM_TYPE: 'App'
  DOCK_ITEM_PATH: 'file:///Applications/Firefox.app/'

Process:
  - Processor: com.github.grahampugh.jamf-upload.processors/JamfDockItemUploader
    Arguments:
      dock_item_name: '%DOCK_ITEM_NAME%'
      dock_item_type: '%DOCK_ITEM_TYPE%'
      dock_item_path: '%DOCK_ITEM_PATH%'
      replace_dock_item: True

After the creation of a dock item, you can use it’s name in your policy template:

<?xml version="1.0"?>
<policy>
  <general>
    <name>%POLICY_NAME%</name>
    <enabled>true</enabled>
    <frequency>Ongoing</frequency>
    <category>
      <name>%POLICY_CATEGORY%</name>
    </category>
    <trigger_other>%POLICY_NAME%</trigger_other>
  </general>
  <scope>
    <all_computers>true</all_computers>
  </scope>
  [...]
  <dock_items>
    <size>1</size>
    <dock_item>
      <name>%DOCK_ITEM_NAME%</name>
      <action>Add To End</action>
    </dock_item>
  </dock_items>
</policy>

A full recipe to create an installer and upload a category, the package itself, the dock item and a policy to install the application could look like this:

Description: Upload the firefox pkg to Jamf.
Identifier: com.eisenschmiede.recipes.jamf.MozillaFirefox
ParentRecipe: com.github.autopkg.pkg.FirefoxSignedPkg
MinimumVersion: '2.3'

Input:
  NAME: MozillaFirefox
  CATEGORY: Internet
  POLICY_CATEGORY: '%CATEGORY%'
  POLICY_NAME: 'Install_%NAME%'
  POLICY_REPLACE: 'True'
  POLICY_TEMPLATE: 'Policy_SelfService_AllDevices.xml'
  POLICY_SELFSERVICE_NAME: 'Mozilla Firefox'
  POLICY_SELFSERVICE_DESC: 'Ein Webbrowser von Mozilla.'
  DOCK_ITEM_NAME: '%NAME%'
  DOCK_ITEM_TYPE: 'App'
  DOCK_ITEM_PATH: 'file:///Applications/Firefox.app/'

Process:
  - Processor: com.github.grahampugh.jamf-upload.processors/JamfDockItemUploader
    Arguments:
      dock_item_name: '%DOCK_ITEM_NAME%'
      dock_item_type: '%DOCK_ITEM_TYPE%'
      dock_item_path: '%DOCK_ITEM_PATH%'
      replace_dock_item: True

  - Processor: com.github.grahampugh.jamf-upload.processors/JamfCategoryUploader
    Arguments:
      category_name: '%CATEGORY%'

  - Processor: com.github.grahampugh.jamf-upload.processors/JamfPackageUploader
    Arguments:
      pkg_category: '%CATEGORY%'

  - Processor: com.github.grahampugh.jamf-upload.processors/JamfPolicyUploader
    Arguments:
      policy_name: '%POLICY_NAME%'
      policy_template: '%POLICY_TEMPLATE%'
      replace_policy: '%POLICY_REPLACE%'
      icon: '%NAME%.png'

A description of the possible values for the processor can be found in it’s README file.