Snapshots and drift
Every other tool tells you what a machine looks like now. The question an administrator actually has is what is different from when it worked - and nothing on a stock Windows answers it.
What a snapshot holds
The whole machine at one moment: every service and driver, with its start type, account, launch path and arguments, the hash and the signer of the file it runs, its dependencies and what depends on it, its triggers, its required privileges, its SID type and its security descriptor - plus the name of the machine, the account that took it, and whether that account was an administrator.
bws snapshot create before.json --note "before the patch"
It is JSON with one field per line. That is deliberate: it means a snapshot goes into a repository and git diff reads it, so the tool's own comparison is not the only way to look at one.
File it like what it is. A snapshot describes the whole machine, down to every launch path and security descriptor. It is written with whatever permissions its directory already has, and the tool narrows nothing - so a directory other people can read is one they can read all of that in.
Then ask what is different
$ bws snapshot diff before.json --live --exit-code
Changed (2):
Spooler Print Spooler
startType: Manual -> Automatic
status: Stopped -> Running (running state, not configuration)
wlidsvc Microsoft Account Sign-in Assistant
status: Stopped -> Running (running state, not configuration)
Added 0, removed 0, changed 2. Fields differing: 1 in configuration, 2 in running state.
- Configuration and running state are reported apart. Two snapshots taken a day apart differ in what happens to be running, and almost none of that is drift. Mixed together, the one line that matters - a start type somebody changed - is buried under forty that do not.
- What could not be compared is listed, not hidden. A field one of the two snapshots never read, because that session had no rights to it, comes out as not compared under its entry, and the summary counts those entries. So a diff that says nothing changed means nothing changed in what both sides could see.
- An elevated snapshot against an unelevated one would lie, reporting entries as removed that nobody removed. Each file records whether the account that took it was an administrator, and the comparison says so.
- Two files, not just a file and this machine. Take one on staging and one on production and diff them anywhere - the answer to why does staging differ does not need either machine present.
The window does the same under Audit.... Take snapshot... writes the same file, with a note if you type one, and Compare with this machine... or Compare two snapshots... shows what changed in place of the list, one row per field, with everything that makes the comparison less than exact said above the table. Show narrows it to the differences or to one field, and Export... writes it to a CSV file.
The exit code is the point
--exit-code ends with 5 when the configuration differs - an entry added or removed, or one set up differently. A service that only stopped or started by itself is reported and does not count, and neither do the per-user copies Windows makes for each signed-in session, which are left out and counted. Not a failure - drift is what this tool is for finding, and finding it is not a failure - which is why it has a number of its own rather than borrowing the one that means something went wrong.
# the day the machine goes into service
bws snapshot create C:\baselines\web01.json --note "after the build"
# every night, from a scheduled task
bws snapshot diff C:\baselines\web01.json --live --exit-code --json > C:\logs\drift.json
# 0 - no configuration drift
# 5 - the configuration drifted, and drift.json says what
# 3 - it ran and could not read everything, so the answer is partial
That is the whole mechanism: a baseline taken when the machine was known good, and a question asked every night. The first night it answers 5, somebody finds out on the first night rather than on the morning something breaks.