Skip to content

Warn when a Windows update failed or a reboot is pending (#13) - #15

Merged
DireDoch merged 1 commit into
mainfrom
feature/windows-update-status
Sep 2, 2026
Merged

DireDoch merged 1 commit into
mainfrom
feature/windows-update-status

Conversation

@DireDoch

@DireDoch DireDoch commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Closes #13.

New src/Config-WindowsUpdate.ps1 with two Steps, both reading local state — no network call, no timeout path, nothing that can hang a run.

Step Source Result
WindowsUpdateHistory Microsoft.Update.Session -> QueryHistory(), entries with ResultCode != 2 OK when clean, WARNING naming the update(s) and their HRESULT
WindowsUpdateReboot ...\WindowsUpdate\Auto Update\RebootRequired OK when absent, WARNING when present
  • History bounded to the last 50 entries and the last 30 days, so a machine re-imaged over an older install does not warn about history that is not about this deployment.
  • COM creation is wrapped and reports Available = $false — a note, not a crash. It is a property rather than a $null return because an empty history and an unavailable agent are different answers, and PowerShell unrolls @() into $null.
  • "Are updates pending" is deliberately not checked, for the reasons in the issue (network, minutes, can hang, warns on 100% of freshly imaged machines).
  • One restart, one row: a pending reboot raises the same Restart required row a rename does, and the row's detail names whichever causes apply. Both Steps share one Windows Update checklist row, so nothing reads as though two restarts were needed.
  • Neither Step needs Administrator, so the Module reports normally on an unelevated run.
  • JSON report: the checklist row carries both Step keys ("step": "WindowsUpdateHistory,WindowsUpdateReboot") and both details, the same shape the existing multi-Step rows (Power, Network) already use.
  • README and manual updated, including the module flow diagram (12 modules) and both sample checklists; PDF rebuilt with typst 0.15.1 and is now 28 pages.

tests/Config-WindowsUpdate.Tests.ps1 covers clean history, one failure, several failures (naming the first three, counting the rest), history outside the window, the agent unavailable, the reboot key present and absent, and the summary formatter.

Locally with Pester 5.7.1: 9/9 in the new file, 106 passed overall with the 2 pre-existing Linux-only failures (New-WinUserLanguageList, Get-CimInstance) untouched. PSScriptAnalyzer clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TmnKA5z4astW8XswYipd7j

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 showed
up anywhere in the run.

Two Steps in a new Config-WindowsUpdate Module, both reading state already on
the machine. WindowsUpdateHistory reads the local history through the Windows
Update Agent and warns about any recent entry whose ResultCode is not
Succeeded, naming the update and its HRESULT - the KB number is already part of
the title Windows records, so the title carries it. WindowsUpdateReboot 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 is not about this
deployment, and warning about it is noise a technician learns to ignore.

"Are updates pending" is deliberately not here. That search goes to Microsoft
over the network, takes 30 seconds to several minutes in a tool whose whole
value is being fast, and can hang, so it would need a timeout and a "search
timed out" path. 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 that tried and
failed is the actionable signal.

The Windows Update Agent is absent or disabled on some managed images, so the
COM creation is wrapped and reports Available = $false. That is carried as a
property rather than by returning $null, because an empty history and an
unavailable agent are different answers and PowerShell unrolls an empty array
into $null. It reports a note, not a crash.

A pending reboot needs the same restart a rename does, so the checklist raises
its restart row once and names whichever causes apply, rather than printing two
rows that read as two restarts. Both update Steps share one checklist row, so
the restart is asked for in exactly one place.

Neither Step needs Administrator, so the Module runs unelevated like Config-Disk
rather than reporting elevation warnings.

README and manual document both Steps and the reasoning for what is not
checked. PDF rebuilt with typst 0.15.1, the version CI pins; it is 28 pages now,
so the README says so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmnKA5z4astW8XswYipd7j
@DireDoch
DireDoch force-pushed the feature/windows-update-status branch from 7d1ce32 to ac74e42 Compare September 1, 2026 23:59
@DireDoch
DireDoch merged commit 02ebeda into main Sep 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Warn when a Windows update failed or a reboot is pending

1 participant