Private/Invoke-InfraPulsePatchAgeCheck.ps1

function Invoke-InfraPulsePatchAgeCheck {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [psobject]$Context,

        [Parameter(Mandatory)]
        [System.Collections.IDictionary]$Settings
    )

    $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
    $scriptBlock = {
        if ($env:OS -ne 'Windows_NT') {
            throw 'The PatchAge check requires a Windows target.'
        }

        if (Get-Command -Name Get-CimInstance -ErrorAction SilentlyContinue) {
            $hotfixes = @(Get-CimInstance -ClassName Win32_QuickFixEngineering -ErrorAction Stop)
        }
        else {
            $hotfixes = @(Get-WmiObject -Class Win32_QuickFixEngineering -ErrorAction Stop)
        }

        $patches = foreach ($hotfix in $hotfixes) {
            # InstalledOn arrives as DateTime through CIM but as a culture-bound
            # string through WMI, and can be absent entirely; only entries with
            # a resolvable date participate in the age evaluation.
            $installedOnProperty = $hotfix.PSObject.Properties['InstalledOn']
            if ($null -eq $installedOnProperty -or $null -eq $installedOnProperty.Value) {
                continue
            }

            $installedOn = $null
            if ($installedOnProperty.Value -is [datetime]) {
                $installedOn = [datetime]$installedOnProperty.Value
            }
            else {
                $parsed = [datetime]::MinValue
                $styles = [System.Globalization.DateTimeStyles]::None
                if ([datetime]::TryParse([string]$installedOnProperty.Value, [System.Globalization.CultureInfo]::InvariantCulture, $styles, [ref]$parsed)) {
                    $installedOn = $parsed
                }
                elseif ([datetime]::TryParse([string]$installedOnProperty.Value, [System.Globalization.CultureInfo]::CurrentCulture, $styles, [ref]$parsed)) {
                    $installedOn = $parsed
                }
            }
            if ($null -eq $installedOn) {
                continue
            }

            [pscustomobject]@{
                HotFixId    = [string]$hotfix.HotFixID
                Description = [string]$hotfix.Description
                InstalledOn = $installedOn
            }
        }

        $ordered = @($patches | Sort-Object -Property InstalledOn -Descending)
        $latest = if ($ordered.Count -gt 0) { $ordered[0] } else { $null }

        # The boot time decides whether the newest update is already active.
        $lastBootTime = $null
        try {
            if (Get-Command -Name Get-CimInstance -ErrorAction SilentlyContinue) {
                $operatingSystem = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
                $lastBootTime = [datetime]$operatingSystem.LastBootUpTime
            }
            else {
                $operatingSystem = Get-WmiObject -Class Win32_OperatingSystem -ErrorAction Stop
                $lastBootTime = $operatingSystem.ConvertToDateTime($operatingSystem.LastBootUpTime)
            }
        }
        catch {
            $lastBootTime = $null
        }

        [pscustomobject]@{
            TotalPatches  = $ordered.Count
            LastPatchDate = if ($null -ne $latest) { [datetime]$latest.InstalledOn } else { $null }
            LastPatchId   = if ($null -ne $latest) { [string]$latest.HotFixId } else { $null }
            LastBootTime  = $lastBootTime
            RecentPatches = @(
                $ordered |
                    Select-Object -First 5 |
                    ForEach-Object {
                        [pscustomobject]@{
                            HotFixId    = $_.HotFixId
                            Description = $_.Description
                            InstalledOn = $_.InstalledOn
                        }
                    }
            )
        }
    }

    $patchState = Invoke-InfraPulseCommand -Context $Context -ScriptBlock $scriptBlock
    $stopwatch.Stop()

    if ($null -eq $patchState.LastPatchDate) {
        return New-InfraPulseResult -Status 'Unknown' -CheckName 'PatchAge' -Category 'Lifecycle' -ComputerName $Context.ComputerName -Target 'Operating system' -Message 'No dated update installations could be determined.' -Recommendation 'Validate update history access on the target; Win32_QuickFixEngineering returned no entries with an installation date.' -Evidence ([ordered]@{ TotalPatches = [int]$patchState.TotalPatches }) -DurationMs $stopwatch.Elapsed.TotalMilliseconds
    }

    $daysSince = [math]::Round(((Get-Date).ToUniversalTime() - ([datetime]$patchState.LastPatchDate).ToUniversalTime()).TotalDays, 2)

    if ($daysSince -ge [double]$Settings.CriticalDays) {
        $status = 'Critical'
        $recommendation = 'Install pending updates through the approved patch process; the target has fallen far behind the expected cadence.'
    }
    elseif ($daysSince -ge [double]$Settings.WarningDays) {
        $status = 'Warning'
        $recommendation = 'Schedule the next patch window; the last update installation is older than the expected cadence.'
    }
    else {
        $status = 'Healthy'
        $recommendation = ''
    }

    $lastBootTime = $null
    $awaitingReboot = $false
    if ($null -ne $patchState.PSObject.Properties['LastBootTime'] -and $null -ne $patchState.LastBootTime) {
        $lastBootTime = [datetime]$patchState.LastBootTime
        $awaitingReboot = ([datetime]$patchState.LastPatchDate) -gt $lastBootTime
    }

    $message = "Last update ($($patchState.LastPatchId)) was installed $([math]::Round($daysSince, 0)) day(s) ago on $(([datetime]$patchState.LastPatchDate).ToString('yyyy-MM-dd'))"
    $message += if ($awaitingReboot) { '; installed after the last boot, a restart is required to activate it.' } else { '.' }

    $evidence = [ordered]@{
        LastPatchDate  = [datetime]$patchState.LastPatchDate
        LastPatchId    = [string]$patchState.LastPatchId
        DaysSince      = $daysSince
        LastBootTime   = $lastBootTime
        AwaitingReboot = $awaitingReboot
        TotalPatches   = [int]$patchState.TotalPatches
        RecentPatches  = @($patchState.RecentPatches)
    }

    return New-InfraPulseResult -Status $status -CheckName 'PatchAge' -Category 'Lifecycle' -ComputerName $Context.ComputerName -Target 'Operating system' -Message $message -ObservedValue ("{0:N2} days" -f $daysSince) -WarningThreshold (">= {0} days" -f $Settings.WarningDays) -CriticalThreshold (">= {0} days" -f $Settings.CriticalDays) -Recommendation $recommendation -Evidence $evidence -DurationMs $stopwatch.Elapsed.TotalMilliseconds
}