-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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 applyThe upside is that batching is natural — there is no --no-restart juggling for a
multi-item change, because nothing restarts until you ask.
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.
| 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 |
| 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
|
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.
| 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 |
| 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 |
| 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
|
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.appThe Windows equivalent:
taskbarutil reset --no-restart
taskbarutil add "Microsoft Edge"
taskbarutil add "Outlook"
taskbarutil add "Calculator"
taskbarutil applyreset --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.
TaskbarUtil — Apache-2.0 — github.com/windowsadmins/taskbarutil
Getting started
Reference
Operating it
Internals