PowerShell
public
Windows Server Update Audit
Share this script safely, inspect its metadata, and copy the exact command you need.
Ready to run
One-liner
curl -fsSL https://runny.sh/r/4JQETB4B35HR | pwsh
Current version: 1.1 · Updated by Godmode · 2026-09-07 02:38:59.064
At a glance
Script metadata
Readable before runnable
Preview
# Windows Server Update Audit
# Read-only report of pending Windows Update software, reboot state,
# and the most recent installed hotfixes.
# Exit 0 if current, 1 if updates or a reboot are pending, 2 on error.
# Hosted on Runny.sh. Review the script page before you run it.
$ErrorActionPreference = 'Continue'
$status = 0
$pendingCount = 0
function Write-Line {
param([string]$Text)
Write-Output $Text
}
function Set-Warn {
if ($script:status -lt 1) {
$script:status = 1
}
}
function Set-Crit {
$script:status = 2
}
Write-Line '=== Windows Server update audit ==='
Write-Line ("Host: {0}" -f $env:COMPUTERNAME)
try {
$os = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
Write-Line ("OS: {0}" -f $os.Caption.Trim())
Write-Line ("Built: {0}" -f $os.Version)
if ($os.LastBootUpTime) {
$uptime = (Get-Date) - [datetime]$os.LastBootUpTime
Write-Line ("Uptime: {0}d {1}h {2}m" -f [int]$uptime.TotalDays, $uptime.Hours, $uptime.Minutes)
}
} catch {
Write-Line 'OS: could not read Win32_OperatingSystem'
Set-Warn
}
Write-Line ''
$reboot = $false
$rebootKeys = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending'
)
foreach ($key in $rebootKeys) {
if (Test-Path -LiteralPath $key) {
$reboot = $true
break
}
}
$sessionManager = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
if (Test-Path -LiteralPath $sessionManager) {
try {
$pendingRename = (Get-ItemProperty -LiteralPath $sessionManager -ErrorAction Stop).PendingFileRenameOperations
if ($pendingRename) {
$reboot = $true
}
} catch {
# Registry value is optional.
}
}
if ($reboot) {
Write-Line 'Reboot: PENDING'
Set-Warn
} else {
Write-Line 'Reboot: not required'
}
Write-Line ''
Write-Line 'Pending Windows Update software:'
try {
$session = New-Object -ComObject Microsoft.Update.Session
$session.ClientApplicationID = 'Runny.sh Windows Server Update Audit'
$searcher = $session.CreateUpdateSearcher()
$result = $searcher.Search("IsInstalled=0 and IsHidden=0 and Type='Software'")
$pendingCount = [int]$result.Updates.Count
if ($pendingCount -eq 0) {
Write-Line ' none'
} else {
Write-Line (" {0} update(s)" -f $pendingCount)
$shown = 0
foreach ($update in $result.Updates) {
if ($shown -ge 12) {
Write-Line (" ... {0} more" -f ($pendingCount - $shown))
break
}
$kb = @()
foreach ($id in $update.KBArticleIDs) {
$kb += "KB$id"
}
$label = if ($kb.Count -gt 0) { ($kb -join ', ') } else { 'no KB' }
Write-Line (" - {0} {1}" -f $label, $update.Title)
$shown++
}
Set-Warn
}
} catch {
Write-Line ' Windows Update search failed (COM API unavailable or access denied)'
Write-Line (" {0}" -f $_.Exception.Message)
Set-Crit
}
Write-Line ''
Write-Line 'Recent installed hotfixes:'
try {
$hotfixes = @(Get-HotFix | Sort-Object -Property InstalledOn -Descending)
if ($hotfixes.Count -eq 0) {
Write-Line ' none reported by Get-HotFix'
} else {
$hotfixes | Select-Object -First 8 | ForEach-Object {
$when = if ($_.InstalledOn) { $_.InstalledOn.ToString('yyyy-MM-dd') } else { 'unknown date' }
Write-Line (" - {0} {1} {2}" -f $_.HotFixID, $when, $_.Description)
}
}
} catch {
Write-Line ' Get-HotFix failed'
Set-Warn
}
Write-Line ''
if ($status -eq 0) {
Write-Line 'Result: CURRENT'
} elseif ($status -eq 1) {
if ($reboot -and $pendingCount -gt 0) {
Write-Line ("Result: ACTION NEEDED ({0} pending update(s), reboot required)" -f $pendingCount)
} elseif ($reboot) {
Write-Line 'Result: ACTION NEEDED (reboot required)'
} else {
Write-Line ("Result: ACTION NEEDED ({0} pending update(s))" -f $pendingCount)
}
} else {
Write-Line 'Result: ERROR'
}
exit $status
Raw endpointhttps://runny.sh/r/4JQETB4B35HR
See something unsafe?
Report this script
Tell us why it should come down. Anyone can also report a URL at /abuse.