The Plist Problem
In the macOS ecosystem, nearly every application’s preferences, system configurations, and launch daemon instructions are stored in files known as Property Lists (.plist). Historically, these were simple, human-readable XML files. You could open them in a standard text editor like nano, change a <false/> tag to a <true/> tag, save the file, and the application would instantly reflect the new setting.
However, as macOS evolved, Apple realized that parsing massive XML files during the boot sequence was inefficient. To optimize performance, Apple shifted entirely to Binary Plist files. If you open a modern macOS configuration file (like /Library/Preferences/SystemConfiguration/preferences.plist) in nano, you will only see unreadable, garbled characters (bplist00 followed by binary data).
Because you cannot edit binary files directly, system administrators are often paralyzed when trying to diagnose corrupt application settings or craft custom MDM payloads. To bridge this gap, macOS includes the plutil (Property List Utility) command. plutil allows administrators to mathematically validate, convert, and surgically edit binary plist files directly from the terminal without breaking their complex encoding structures.
Step 1: Validating Syntax (The Lint Check)
Before you even attempt to edit a plist, you should verify if it is structurally sound. A single missing XML bracket or a corrupted binary header can cause an application to crash instantly on launch.
Use the -lint flag to check the health of a file. Suppose a user’s Microsoft Word application refuses to open. You suspect their preference file is corrupted.
plutil -lint ~/Library/Preferences/com.microsoft.Word.plist
If the output is com.microsoft.Word.plist: OK, the file is structurally intact. If it returns an error like Unexpected character b at line 1, the file is catastrophically corrupted and must be deleted (forcing the application to generate a fresh one).
Step 2: Converting Binary to Human-Readable XML
To actually read the contents of a binary plist to see what settings are applied, you must convert it back to XML format.
You use the -convert xml1 flag. By default, this will overwrite the file in place. If you are inspecting a live system file, this is incredibly dangerous. You should always output the converted result to the terminal screen (Standard Out) or to a temporary file.
To print the readable XML directly to the terminal without modifying the original binary file, append -o - (output to stdout):
plutil -convert xml1 -o - ~/Library/Preferences/com.apple.finder.plist
The terminal will display a beautifully formatted XML tree containing all the user’s hidden Finder configurations.
If you want to create a readable copy on your Desktop to analyze in a code editor:
plutil -convert xml1 ~/Library/Preferences/com.apple.finder.plist -o ~/Desktop/finder_readable.plist
Step 3: Surgical Edits (Inserting Data into Binary)
While you could convert a file to XML, edit it in nano, and then use plutil -convert binary1 to compress it back, this is a highly inefficient workflow for automated bash scripts.
The true power of plutil is the -insert and -replace flags. You can inject new keys directly into a binary file without ever converting it to XML.
Suppose you are writing a deployment script for a proprietary corporate application (com.corp.agent). You need to forcefully enable the “DebugLogging” feature (a boolean value) before the application launches.
plutil -insert DebugLogging -bool YES /Library/Preferences/com.corp.agent.plist
This command reaches directly into the binary structure and injects the boolean key. If the key already exists and you simply want to change it from NO to YES, you use the replace flag:
plutil -replace DebugLogging -bool YES /Library/Preferences/com.corp.agent.plist
Step 4: Navigating Nested Dictionaries
In complex applications, settings are rarely at the root of the file. They are often buried deep within nested dictionaries (folders within folders).
plutil uses dot-notation to navigate these complex paths. Suppose the preference file contains a primary dictionary named NetworkSettings, and inside that, a string key named ProxyServer.
To surgically replace the ProxyServer string without touching anything else in the file:
plutil -replace NetworkSettings.ProxyServer -string "proxy.corp.local:8080" /Library/Preferences/com.corp.agent.plist
Step 5: Extracting Specific Values for Scripts
If you are writing an audit script to verify compliance, you don’t want to convert the whole file; you just want to extract a single piece of data.
You can use the -extract flag combined with the xml1 output format to pull a specific key.
plutil -extract NetworkSettings.ProxyServer xml1 -o - /Library/Preferences/com.corp.agent.plist
This will print the exact string value wrapped in <string> tags, which you can easily parse using grep or awk in your larger bash automation pipeline.
Conclusion
The transition to binary Property Lists optimized macOS performance, but it fundamentally broke the traditional text-editing workflows used by UNIX administrators. By mastering the plutil command, IT engineers regain absolute control over the core configuration framework of the Mac. The ability to instantly validate syntax, convert binary structures to readable XML, and surgically inject nested variables via script makes plutil an indispensable tool for advanced macOS deployment and MDM payload generation.