← BACK TO HOME

The Shell Crossover, Part 4: macOS Preferences, Plists, and the defaults Command

Translate registry habits into macOS preference work with plist files, preference domains, defaults, plutil, and the boundary with configuration profiles.

Windows administrators often reach for the registry when they need to inspect or change application behavior. macOS does not have a single registry hive. It has preference domains, property list files, and a user defaults system.

That difference matters. A plist file is not a registry hive, and the defaults command is not Group Policy. The closer translation is this: defaults is a local preference inspection and modification tool, while configuration profiles are the managed enforcement layer.

The preference map

Windows conceptmacOS conceptTypical location
HKCU application settingsPer-user preferences~/Library/Preferences
HKLM machine settingsLocal computer preferences/Library/Preferences
.reg exportProperty list file.plist file
reg.exe querydefaults read, plutil -pNative command-line tools
Group Policy or MDM policyConfiguration profileInstalled by MDM or user approval

Preference files usually use reverse-DNS names. For example, Finder preferences are commonly associated with the com.apple.finder domain.

ls "$HOME/Library/Preferences" | grep '^com\.apple\.finder'

PowerShell can list the same files.

Get-ChildItem -Path "$HOME/Library/Preferences" -Filter "com.apple.finder*"

Preference domains are the unit of work

A preference domain is the logical name used by the defaults system. It often lines up with a plist file, but do not build scripts that assume every domain maps perfectly to one file in one location.

Read a full domain:

defaults read com.apple.finder

Read one key:

defaults read com.apple.finder ShowPathbar

Run the same command from PowerShell when you want to keep a PowerShell-driven workflow.

& /usr/bin/defaults read com.apple.finder ShowPathbar

If a key does not exist, defaults returns a nonzero exit code. Treat that as a possible “not configured” state, not automatically as a system failure.

if defaults read com.apple.finder ShowPathbar >/dev/null 2>&1; then
  echo "ShowPathbar is present."
else
  echo "ShowPathbar is not set for this user."
fi

Writing a local preference

The defaults write pattern is domain, key, type, value.

defaults write com.apple.finder ShowPathbar -bool true
killall Finder

PowerShell version:

& /usr/bin/defaults write com.apple.finder ShowPathbar -bool true
& /usr/bin/killall Finder

Some applications read preferences live. Others read them at launch. Finder and Dock examples often need a process restart to show the change.

Modern macOS also routes preference reads and writes through cfprefsd, the preferences daemon behind CFPreferences and UserDefaults. That means a value may be cached by a running app even after a local defaults write. Do not build scripts around killing cfprefsd. Restart the affected app, test with a clean session when needed, or log out and back in when you are validating user-scoped behavior.

Sandboxed applications add another wrinkle. Their preferences may live inside a container, such as a path under ~/Library/Containers/.../Data/Library/Preferences, rather than the obvious ~/Library/Preferences domain path. A direct defaults write com.vendor.app Key ... may write a value but not affect the sandboxed app you intended to configure. For managed state, prefer a supported configuration profile or the application’s documented management keys.

Do not use defaults write as your fleet policy strategy. It is useful for labs, troubleshooting, preference discovery, and unmanaged local changes. It does not replace a configuration profile.

Deleting a local preference key

Deleting a key removes the local value and lets the application fall back to its default behavior or a managed value.

defaults delete com.apple.finder ShowPathbar
killall Finder

PowerShell version:

& /usr/bin/defaults delete com.apple.finder ShowPathbar
& /usr/bin/killall Finder

Avoid deleting an entire domain unless you have a clear rollback plan.

# High impact: removes the local domain for the current user.
defaults delete com.apple.finder

That is closer to deleting a registry branch than changing one setting.

Inspecting plist files with plutil

The defaults command interacts with the preferences system. The plutil command inspects and converts property list files.

Pretty-print a plist:

plutil -p "$HOME/Library/Preferences/com.apple.finder.plist"

Check plist syntax:

plutil -lint "$HOME/Library/Preferences/com.apple.finder.plist"

Convert a copy to XML for review:

cp "$HOME/Library/Preferences/com.apple.finder.plist" /tmp/com.apple.finder.plist
plutil -convert xml1 /tmp/com.apple.finder.plist -o /tmp/com.apple.finder.xml.plist

Convert a plist to JSON output for tooling:

plutil -convert json -o - "$HOME/Library/Preferences/com.apple.finder.plist"

PowerShell can capture that JSON output.

$json = & /usr/bin/plutil -convert json -o - "$HOME/Library/Preferences/com.apple.finder.plist"
$finderPreferenceObject = $json | ConvertFrom-Json
$finderPreferenceObject | Get-Member

This is often safer than parsing the human-oriented output of defaults read.

Local preferences versus managed configuration

A local preference is a value the user or a local process can change. A managed preference is delivered through a management channel, usually as part of a configuration profile.

For Windows administrators, this is the difference between a user editing a registry value and an administrator enforcing a setting through policy.

ScenarioPrefer
Discovering a setting on a test Macdefaults read, plutil -p
Testing a local user preferencedefaults write
Inspecting the on-disk structureplutil
Enforcing settings across a fleetConfiguration profile through MDM
Preventing user changesConfiguration profile through MDM

A local script can set a value, but a configuration profile can enforce a value. If both exist, the managed path is the one that should define enterprise intent.

A safe lab workflow

Use a temporary domain for testing command behavior.

defaults export is useful as a lab inspection shortcut, but it is not documented in the defaults man page. Treat it as a convenience for interactive review, not as a critical production scripting dependency.

lab_domain="dev.admincrossover.preferences.lab"

defaults write "$lab_domain" ExampleString -string "Hello from zsh"
defaults write "$lab_domain" ExampleEnabled -bool true
defaults read "$lab_domain"
defaults export "$lab_domain" /tmp/admincrossover-preferences-lab.plist
plutil -p /tmp/admincrossover-preferences-lab.plist
defaults delete "$lab_domain"
rm -f /tmp/admincrossover-preferences-lab.plist

PowerShell version:

$LabDomain = "dev.admincrossover.preferences.lab"

& /usr/bin/defaults write $LabDomain ExampleString -string "Hello from PowerShell"
& /usr/bin/defaults write $LabDomain ExampleEnabled -bool true
& /usr/bin/defaults read $LabDomain
& /usr/bin/defaults export $LabDomain "/tmp/admincrossover-preferences-lab.plist"
& /usr/bin/plutil -p "/tmp/admincrossover-preferences-lab.plist"
& /usr/bin/defaults delete $LabDomain
Remove-Item -Path "/tmp/admincrossover-preferences-lab.plist" -Force

The operating rule

Use defaults to understand and test local preferences. Use plutil to inspect and convert plist data. Use configuration profiles when the setting represents managed state.

That boundary is the difference between changing a Mac and managing a Mac.