PowerShell public

Windows Server Update Audit

Share this script safely, inspect its metadata, and copy the exact command you need.

Dashboard

Ready to run

One-liner

Copy the command, then review before execution.
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

Slug
4JQETB4B35HR
Fetches
0
Size
4336 B · 139 lines
Expires
never
Last fetch
Created
2026-09-07 00:35:58.791
Description
Pending updates, reboot state, and recent hotfixes

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.

Restore revision