Active Directory
banshee/active-directory-collection/active-directory/ssh/
gpo
The Group Policy processing errors written to the System log since the previous run, by SSH and PowerShell
by banshee1 installation2 versions
// The errors of Group Policy processing written to the System log of a Windows since the previous run, by SSH:
// their number, and their event identifiers. Its watch is not checked by default: some of these errors are
// transient (a domain controller not reached at startup), and only the administrator knows which rate is not.
// Runs PowerShell commands that only read the log, by Get-WinEvent, as windows/ssh/eventlog of
// banshee/windows-collection does: the collector keeps in the cache of the probe the highest record number
// it has counted, and counts at the next run the errors (Level 2) of the provider Microsoft-Windows-GroupPolicy
// above it. The first run only notes the number where counting starts.
need('protocol:ssh');
output('errors', 'number', array('label' => 'Group Policy errors since the previous run'));
output('events', 'text', array('label' => 'Their event identifiers'));
watch.above('errors', 'Group Policy errors', 'errors', array('warning' => 0, 'enabled' => false));
// The number kept lasts a week: a probe stopped longer starts again as at its first run.
if (!cache.has('last-record')) {
$read = ssh.run("powershell -NoProfile -NonInteractive -Command \""
. "(Get-WinEvent -LogName System -MaxEvents 1).RecordId\"");
$newest = text.trim($read['output']);
if (!text.is_number($newest)) {
fail('misconfigured', 'PowerShell did not return the last record of the System log', $newest . $read['errors']);
}
// Kept as a number, to be compared with the numbers of the next run.
cache.set('last-record', $newest + 0, 604800);
skip('First reading: errors are counted from the next run');
}
$last = cache.get('last-record');
// newest: the record number of the latest event of the log, of any provider and level; last: the highest
// record number among the errors read, 0 when there is none. Get-WinEvent reports "no event found" as an
// error, silenced on the reading of the errors; with $ErrorActionPreference set to Stop, any other failure, an
// access to the log refused among them, ends the command on the reading of the newest event, with no answer,
// rather than an answer of zero errors.
$read = ssh.run("powershell -NoProfile -NonInteractive -Command \""
. "$ErrorActionPreference = 'Stop'; "
. "$events = @(Get-WinEvent -LogName System -ErrorAction SilentlyContinue"
. " -FilterXPath '*[System[Provider[@Name=''Microsoft-Windows-GroupPolicy''] and Level=2 and EventRecordID>" . $last . "]]'); "
. "ConvertTo-Json -Compress -InputObject @{"
. "newest = [long](Get-WinEvent -LogName System -MaxEvents 1).RecordId; "
. "last = [long]($events | Measure-Object RecordId -Maximum).Maximum; "
. "errors = $events.Count; "
. "ids = (@($events | Select-Object -ExpandProperty Id -Unique) -join ', ')}\"");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\{')) == 0) {
fail('misconfigured', 'PowerShell did not return the Group Policy errors of the System log', $answer . $read['errors']);
}
$log = json.read($answer);
// A log that was cleared numbers its events from 1 again: counting starts again from the start of the log.
if ($log['newest'] < $last) {
cache.set('last-record', 0, 604800);
skip('The System log was cleared: errors are counted again from the next run');
}
if ($log['last'] > $last) {
cache.set('last-record', $log['last'], 604800);
} else {
cache.set('last-record', $last, 604800);
}
value('errors', $log['errors']);
value('events', $log['ids']);