Skip to content

Coming From dockutil

Rod Christiansen edited this page Sep 3, 2026 · 1 revision

Coming From dockutil

If you script macOS Docks with dockutil, most of your instincts transfer and two of them will actively mislead you. Read the two differences first; the tables are only useful once they are in your head.

Difference one: authoring and applying are separate steps

dockutil edits the plist and the Dock reloads. One command, one visible result.

TaskbarUtil's add, remove, move and replace edit a config file in %LOCALAPPDATA% and change nothing on screen. Only apply deploys the config as policy and rebuilds the taskbar. Every mutating command prints a reminder to that effect.

taskbarutil add "Google Chrome"
taskbarutil add "Windows Terminal"
taskbarutil apply

The upside is that batching is natural — there is no --no-restart juggling for a multi-item change, because nothing restarts until you ask.

Difference two: the pin list is all-or-nothing

dockutil's --remove takes an item out and leaves the rest of the Dock alone, including whatever the user added themselves.

TaskbarUtil deploys PinListPlacement="Replace", which means the layout file is the taskbar. apply also deletes the Taskband registry subtree and start2.bin to force Explorer to rebuild. Anything the user pinned by hand is gone. There is no supported way on Windows 11 to remove one pin and leave the rest intact — Microsoft removed the shell verbs that would allow it.

The practical consequence: taskbarutil remove removes from your config, not from a user's current taskbar. To take one app off a user's taskbar you deploy a complete layout that omits it, and everything else they had is replaced too.

Verb mapping

dockutil taskbarutil Notes
--add <path> add <app> Takes a friendly name, a .lnk, an .exe or an AUMID. Does not take effect until apply
--remove <label> remove <app> Removes from the config; deploying it replaces the whole pin list
--move <label> move <app> Requires one of --position, --before, --after
--find <label> see notes find <query> searches installed apps, not the current layout. To find something in the layout, read show
--list list Prints legacy pin shortcuts (alphabetical) and, when policy is active, the policy layout in real order
show Prints the config: pins, identifiers and raw XML. No dockutil equivalent
apply Deploys the config as policy and rebuilds the taskbar. The step dockutil does not need
reset Removes the policy and restores the stock taskbar
settings Toggles built-in taskbar items (search, task view, widgets, resume, copilot, chat). Shell config, not pinning

Flag mapping

dockutil taskbarutil Notes
--position <n> --position <n> / -p 1-based in both. Out of range appends rather than erroring
--before <label> --before <app> Target must already be in the config, or exit 3
--after <label> --after <app> Same
--replacing <label> replace <old> <new> A separate verb rather than a modifier on add
--no-restart --no-restart On apply and reset. Policy is written, layout lands at next sign-in
--allhomes --allhomes On apply only, and it does not mean the same thing — see below
--label <text> No equivalent. Display names come from the resolver and are not stored in the XML
--view, --display, --sort Folder-stack options; the taskbar has no stacks
--section apps|others The taskbar has no second section under a divider
--type spacer No equivalent. The Windows 11 taskbar has no spacer tile
--hostname, --homeloc No equivalent. Everything is local
--version --version Same
--verbose / -v Diagnostics on stderr
--dry-run Preview without writing. Honoured by every mutating command except settings
--uwp, --app-id Bypass resolution and use the argument verbatim as an AUMID or DesktopApplicationID
--type desktop|uwp|all Filter on find

--allhomes is not the same thing

On macOS, dockutil --allhomes walks /Users and edits each user's plist on disk, whether or not that user is logged in.

On Windows, a user's HKCU only exists as a loaded hive when the user has a session. taskbarutil apply --allhomes enumerates profiles from ProfileList, skips any profile whose hive is not loaded in HKEY_USERS, and reports the count it actually applied to. On a machine with one signed-in user it will say "1 user profile(s)" no matter how many profiles exist on disk.

To compensate, it always copies the layout into C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml, which seeds profiles created after that point. Profiles that already exist and are not currently signed in get nothing. See Deployment At Scale for the pattern that actually covers everyone.

--allhomes also requires elevation, and it points every user's policy at a shared copy in C:\ProgramData\TaskbarUtil\LayoutModification.xml rather than at per-user files.

Concept mapping

macOS concept Windows equivalent Notes
com.apple.dock.plist LayoutModification.xml Both are the desired state, but the XML is policy input, not live state. Explorer's live state is in undocumented binaries
killall Dock Explorer restart Far more disruptive: kills StartMenuExperienceHost, ShellExperienceHost and explorer.exe; the desktop has no taskbar for 5–15 seconds
App bundle path .lnk path, DesktopApplicationID, or AUMID Three identifier kinds, and picking the right one is most of what find is for
/Applications scan Start Menu scan + Get-AppxPackage Two independent inventories, ranked together
Dock "others" section No equivalent
Stacks / folders in the Dock No equivalent
Per-user plist, no privilege needed HKCU policy, no privilege needed Except under GPO, where the tool falls back to a file copy
~/Library/Preferences %LOCALAPPDATA%\TaskbarUtil Where the config lives

Things with no Windows equivalent

dockutil capability Why not
Removing one item without touching the rest Windows 11 removed the pin/unpin shell verbs; the layout policy is Replace-only
Pinning a folder or a stack The taskbar has no stack concept
Spacers and separators No such tile type in the Windows 11 taskbar
Custom labels on a pin The layout schema has no place to store one; names are derived from the identifier
Editing an offline user's state A logged-out user's HKCU is not loaded; only the Default profile can be seeded
Applying to a remote host Everything is local; run the tool in the target session
Reordering without a shell restart Order lives in the Taskband binary value, which must be deleted and rebuilt

Things Windows has that macOS does not

taskbarutil capability Notes
settings Show and hide search, task view, widgets, resume, copilot and chat, and report when a Group Policy has locked one
Policy-locked pins With PinListPlacement="Replace" and no PinGeneration, users cannot keep their own pins across an apply
GPO fallback When the policy key is GPO-owned, the layout is written to the user's Shell directory instead
Default-profile seeding Layouts can be staged for users who do not exist yet
A rolled audit log Every mutating operation with its outcome, under C:\ProgramData\ManagedUtilities\logs

Translating a dockutil script

A typical macOS login script:

dockutil --remove all --no-restart
dockutil --add /Applications/Safari.app --no-restart
dockutil --add /Applications/Mail.app --no-restart
dockutil --add /Applications/Calendar.app

The Windows equivalent:

taskbarutil reset --no-restart
taskbarutil add "Microsoft Edge"
taskbarutil add "Outlook"
taskbarutil add "Calculator"
taskbarutil apply

reset --no-restart stands in for --remove all: it clears the policy and deletes the config so the subsequent add calls start from an empty list, without paying for a shell restart you are about to pay for anyway. The single apply at the end does the one restart. This is exactly the shape of the scripts in the repository's examples/ directory.

Clone this wiki locally