Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ the manifest key to edit — when something needs one.
[x] Free space OK 412 GB free of 476 GB
[x] TPM readiness OK TPM present and ready.
[x] Drive encryption OK Protected: C: FullyEncrypted.
[x] Windows Update OK No failed update in the last 50 entries
(30 days). | Restart pending: none.
[x] Network adapters OK
[x] Outlook OK
[!] VPN client WARNING No matching process running (PanGPA, PanGPS).
Expand Down Expand Up @@ -271,6 +273,15 @@ after enrolment will see the warning on a fresh machine, which is the correct
thing for a handover checklist to say. The tool only ever reports — it never
enables BitLocker and never touches a recovery key.

*Windows Update* is read twice and never searched: the recent update history
(the last 50 entries, and only the last 30 days) and the `RebootRequired` key.
An update that tried and failed is a warning naming the update and its HRESULT;
a restart Windows is waiting for is a warning too, folded into the single
`Restart required` row so one restart covers it and a rename both. Neither reads
the network. "Are updates pending" is deliberately not checked — that search goes
to Microsoft, takes minutes, can hang, and a freshly imaged machine always has
some, so it would warn on every run.

`Domain.Name` is the domain the machine-identity prompt offers to join, and
`Domain.OUPath` the optional organisational unit the machine account is created
in. Leave `Name` empty and the domain option disappears from the prompt entirely,
Expand Down Expand Up @@ -354,7 +365,7 @@ tests/

## Documentation

- **[The manual (PDF)](docs/manual.pdf)** — 27 pages: what the tool does, what
- **[The manual (PDF)](docs/manual.pdf)** — 28 pages: what the tool does, what
it leaves to you, the architecture in diagrams, PowerShell explained from
nothing, how to add your own module, and how to read the diagnostic when
something goes wrong.
Expand Down
Binary file modified docs/manual.pdf
Binary file not shown.
48 changes: 46 additions & 2 deletions docs/manual.typ
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ module, which is the view that tells you whether the run itself went well:
cline(" [x] Config-DeviceManager OK 1 step(s)", fill: cGreen),
cline(" [x] Config-Disk OK 2 step(s)", fill: cGreen),
cline(" [x] Config-BitLocker OK 2 step(s)", fill: cGreen),
cline(" [x] Config-WindowsUpdate OK 2 step(s)", fill: cGreen),
cline(" [x] Config-Network OK 3 step(s)", fill: cGreen),
)

Expand All @@ -443,6 +444,8 @@ thing that had to happen on this machine:
cline(" [x] Free space OK 412 GB free of 476 GB", fill: cGreen),
cline(" [x] TPM readiness OK TPM present and ready.", fill: cGreen),
cline(" [x] Drive encryption OK Protected: C: FullyEncrypted.", fill: cGreen),
cline(" [x] Windows Update OK No failed update in the last 50", fill: cGreen),
cline(" entries (30 days).", fill: cGreen),
cline(" [x] Network adapters OK", fill: cGreen),
cline(" [x] Software Center OK", fill: cGreen),
cline(" [!] VPN client WARNING No matching process running (PanGPA, PanGPS).", fill: cYellow),
Expand Down Expand Up @@ -483,6 +486,7 @@ Your answers change what each module *does*, never the order they run in.
("Config-DeviceManager", "devices Windows cannot configure"),
("Config-Disk", "disk health, free space on the system drive"),
("Config-BitLocker", "TPM readiness, encryption on the system drive"),
("Config-WindowsUpdate", "failed updates, a restart waiting to be applied"),
("Config-Network", "adapters, connectivity, network places"),
("Config-Printer", "shared print queues"),
)
Expand All @@ -508,7 +512,7 @@ Your answers change what each module *does*, never the order they run in.
if i == 0 { arrow((0, -3.34), (0, y + 0.33)) } else { arrow((0, y + 0.85 - 0.33), (0, y + 0.33)) }
}

let last = top - 10 * 0.85
let last = top - 11 * 0.85
dnode((0, last - 1.0), text(size: 8pt)[Final diagnostic: by module, then by step], w: 8.4, h: 0.68)
dnode((0, last - 2.0), text(size: 8pt)[Write the log, the history block and the JSON report], w: 8.4, h: 0.68)
dnode((0, last - 3.0), text(size: 8.5pt, weight: "bold", fill: white)[End],
Expand All @@ -520,7 +524,7 @@ Your answers change what each module *does*, never the order they run in.
// Brace over the module band
d.line((5.2, top + 0.33), (5.5, top + 0.33), (5.5, last - 0.33), (5.2, last - 0.33),
stroke: 0.8pt + grey)
dlabel((7.1, (top + last) / 2), align(left)[11 modules, \ run in \ this order], size: 8pt)
dlabel((7.1, (top + last) / 2), align(left)[12 modules, \ run in \ this order], size: 8pt)
})
]
#v(0.2cm)
Expand Down Expand Up @@ -754,6 +758,46 @@ to say.
edition does not support BitLocker, rather than crashing.
]

=== Config-WindowsUpdate — failed updates and a pending restart

A machine that failed an update during imaging, or that is sitting on an
unapplied reboot, looks completely fine at handover and is not. Neither shows up
anywhere else in the run.

Two steps, both reading state that is already on the machine. `Windows Update
history` reads the local update history through the Windows Update Agent and
warns about any recent entry that did not succeed, naming the update — the KB
number is part of the title Windows records — and its `HRESULT`. `Restart
pending` reads the `RebootRequired` key: absent passes, present warns.

Only recent history counts: the last 50 entries, and only the last 30 days. A
machine re-imaged over an older install carries history that has nothing to do
with this deployment, and warning about it would be noise a technician learns to
ignore.

#note[
A restart is asked for *once*. If the machine was also renamed or joined to a
domain, the same restart covers both, and the `Restart required` row says so
rather than reading as though two were needed.
]

#warn[
"Are updates pending" is deliberately not checked. That search asks Microsoft
over the network, takes anywhere from 30 seconds to several minutes in a tool
whose whole value is being fast, and can hang. Worse, a freshly imaged machine
*always* has updates pending, because the image is weeks old — the step would
warn on 100% of runs, which is exactly the alarm technicians learn to scroll
past. "An update tried and failed" is the actionable signal; "updates exist" is
not.
]

#note[
The Windows Update Agent is absent or disabled on some managed and stripped
images. Creating the COM object is wrapped: that reports one note saying the
history could not be read, rather than crashing the module. Neither step needs
Administrator.
]

=== Config-Network — adapters, connectivity and network places

Inventories the active adapters (the virtual ones — Bluetooth, loopback, VPN,
Expand Down
Loading
Loading