Invoke-IcingaCheckUpdates and time since last update

Hello,

i did not find some obvious in the documentation, but is it correct that we can just check if a found update is not installed? Its not possible to check the last update search or successfull install?

I ask because i had two systems that had a windows update issue and does not search for updates for month and i like to see that in the future.

Thanks.

Out of the box and not tested:

<#
.SYNOPSIS
Icinga2 plugin to check when the Windows Update Agent last searched for updates.

.DESCRIPTION
This script checks the timestamp of the last Windows Update search using the Windows Update COM API.
If that fails, it falls back to the WindowsUpdateClient event log (Event ID 41).
Returns Icinga/Nagios-compatible output and exit codes.

.PARAMETER WarningHours
The warning threshold (in hours). Default: 24

.PARAMETER CriticalHours
The critical threshold (in hours). Default: 48

.EXAMPLE
.\Check-WindowsUpdateSearch.ps1 -WarningHours 24 -CriticalHours 48
#>

param(
[int]$WarningHours = 24,
[int]$CriticalHours = 48
)

— Function to get last update search date from COM API —

function Get-LastUpdateSearchDate {
try {
$session = New-Object -ComObject “Microsoft.Update.Session”
$searcher = $session.CreateUpdateSearcher()
$count = $searcher.GetTotalHistoryCount()
if ($count -eq 0) { return $null }

    $history = $searcher.QueryHistory(0, $count)
    $lastSearch = $history | Where-Object { $_.Operation -eq 1 } | Sort-Object Date -Descending | Select-Object -First 1
    return $lastSearch.Date
}
catch {
    return $null
}

}

— Function to get last update search date from Event Log —

function Get-LastUpdateSearchFromEventLog {
try {
$event = Get-WinEvent -LogName “Microsoft-Windows-WindowsUpdateClient/Operational” -MaxEvents 200 |
Where-Object { $_.Id -eq 41 } | Select-Object -First 1
return $event.TimeCreated
}
catch {
return $null
}
}

— MAIN LOGIC —

$lastSearchDate = Get-LastUpdateSearchDate
if (-not $lastSearchDate) {
$lastSearchDate = Get-LastUpdateSearchFromEventLog
}

if (-not $lastSearchDate) {
Write-Host “UNKNOWN - Could not determine last Windows Update search time”
exit 3
}

$now = Get-Date
$diffHours = ($now - $lastSearchDate).TotalHours
$rounded = [math]::Round($diffHours, 1)

— Determine status —

if ($diffHours -ge $CriticalHours) {
Write-Host “CRITICAL - Last update search was $rounded hours ago ($lastSearchDate) | last_search_hours=$rounded;$WarningHours;$CriticalHours”
exit 2
}
elseif ($diffHours -ge $WarningHours) {
Write-Host “WARNING - Last update search was $rounded hours ago ($lastSearchDate) | last_search_hours=$rounded;$WarningHours;$CriticalHours”
exit 1
}
else {
Write-Host “OK - Last update search was $rounded hours ago ($lastSearchDate) | last_search_hours=$rounded;$WarningHours;$CriticalHours”
exit 0
}

Regards
Peer-Mario