banshee is under active development: collectors will keep changing, and a version you publish will likely need adjustments. For stable use, wait for version 1.0.0.

Windows

banshee/windows-collection/windows/winrm/

updates

The updates waiting on a Windows, the critical ones, the restart required and the age of the last search, by WinRM and PowerShell

  • windows
  • winrm
  • powershell
  • updates
  • windows-update

by banshee1 installation2 versions

Keen 1.0.0 · 48 lines
// The updates of a Windows, by WinRM: the updates waiting to be installed, the critical ones among them, a
// restart asked for by an installed update, and the age of the last successful search for updates.
// Runs one PowerShell script that only reads, through the Windows Update agent (the COM objects
// Microsoft.Update.Session, Microsoft.Update.SystemInfo and Microsoft.Update.AutoUpdate). The search is made
// offline: Windows answers from the result of its own last search, without asking Windows Update or the
// WSUS server. That result may be old: the age of the last search says how much the count is worth.
// The script is the one of windows/ssh/updates, without the powershell -Command "..." that cmd.exe needs
// there.
need('protocol:winrm');

output('pending', 'number', array('label' => 'Updates waiting'));
output('critical', 'number', array('label' => 'Critical updates waiting'));
output('reboot', 'text', array('label' => 'Restart required'));
output('search-age', 'number', array('label' => 'Last successful search', 'unit' => 'd'));

watch.above('critical-pending', 'Critical updates waiting', 'critical', array('warning' => 0));
watch.above('pending', 'Updates waiting', 'pending', array('enabled' => false));
watch.state('reboot-required', 'Restart required', 'reboot', array('warning' => array('yes')));
watch.above('search-old', 'No search for updates', 'search-age', array('warning' => 7, 'critical' => 30));

// MsrcSeverity is the rating Microsoft gives a security update: "Critical", "Important"...; it is the same
// whatever the language of Windows. LastSearchSuccessDate is in UTC; it comes out in hours, an integer.
// With $ErrorActionPreference set to Stop, a failed search ends the script with no answer, rather than an
// answer of zero updates.
$read = winrm.run("$ErrorActionPreference = 'Stop'; "
    . "$searcher = (New-Object -ComObject Microsoft.Update.Session).CreateUpdateSearcher(); "
    . "$searcher.Online = $false; "
    . "$updates = @($searcher.Search('IsInstalled=0 and IsHidden=0').Updates); "
    . "ConvertTo-Json -Compress -InputObject @{"
    . "pending = $updates.Count; "
    . "critical = @($updates | Where-Object MsrcSeverity -eq 'Critical').Count; "
    . "reboot = (New-Object -ComObject Microsoft.Update.SystemInfo).RebootRequired; "
    . "hours = [long]((Get-Date).ToUniversalTime()"
    . " - (New-Object -ComObject Microsoft.Update.AutoUpdate).Results.LastSearchSuccessDate).TotalHours}");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\{')) == 0) {
    fail('misconfigured', 'PowerShell did not return the state of Windows Update', $answer . $read['errors']);
}
$update = json.read($answer);

value('pending', $update['pending']);
value('critical', $update['critical']);
if ($update['reboot']) {
    value('reboot', 'yes');
} else {
    value('reboot', 'no');
}
value('search-age', number.round($update['hours'] / 24, 1));