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.

Active Directory

banshee/active-directory-collection/active-directory/ssh/

adcs

The service of an Active Directory certification authority and the days before its certificate expires, by SSH and PowerShell

  • active-directory
  • adcs
  • pki
  • certificate
  • ssh
  • powershell

by banshee1 installation3 versions

Keen 1.0.0 · 46 lines
// The certification authority of Active Directory Certificate Services, by SSH: the state of its service,
// CertSvc, and the days left before its certificate expires. Once it expires, nothing it issued is trusted.
// Runs one PowerShell command that only reads: Win32_Service for the service CertSvc, and the certificates
// (.crt) the authority publishes in its folder CertEnroll (System32\CertSrv\CertEnroll), read by the class
// X509Certificate2 of .NET; the one that expires last is the current certificate of the authority, the
// former ones staying beside it after a renewal.
// The expiry of the certificate revocation list (CRL) is read by active-directory/https/crl, at its
// distribution point: the .NET Framework of Windows PowerShell has no class that reads a CRL.
need('protocol:ssh');

output('service', 'text', array('label' => 'Certificate Services'));
output('certificate', 'text', array('label' => 'Certificate of the authority'));
output('days-left', 'number', array('label' => 'Before the certificate expires', 'unit' => 'd'));

watch.expect('service-stopped', 'Certificate Services stopped', 'service', array('critical' => array('running')));
watch.below('expiring', 'Authority certificate expiring', 'days-left', array('warning' => 180, 'critical' => 60));

$read = ssh.run("powershell -NoProfile -NonInteractive -Command \""
    . "$ErrorActionPreference = 'Stop'; "
    . "[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding; "
    . "$state = [string](Get-CimInstance Win32_Service -Filter 'Name=''CertSvc''').State; "
    . "$folder = Join-Path $env:windir 'System32\\CertSrv\\CertEnroll'; "
    . "$subject = ''; $days = ''; "
    . "if (Test-Path $folder) {"
    . " $latest = Get-ChildItem $folder -Filter '*.crt'"
    . " | ForEach-Object { New-Object Security.Cryptography.X509Certificates.X509Certificate2($_.FullName) }"
    . " | Sort-Object NotAfter | Select-Object -Last 1;"
    . " if ($latest) { $subject = $latest.Subject;"
    . " $days = [long]($latest.NotAfter.ToUniversalTime() - [DateTime]::UtcNow).TotalDays } }; "
    . "ConvertTo-Json -Compress -InputObject @{service = $state; subject = $subject; days = $days}\"");
$answer = text.trim($read['output']);
if (list.count(text.match($answer, '^\{')) == 0) {
    fail('misconfigured', 'PowerShell did not return the certification authority', $answer . $read['errors']);
}
$authority = json.read($answer);
if ($authority['service'] == '') {
    fail('misconfigured', 'Active Directory Certificate Services is not installed', $answer);
}
if ($authority['days'] == '') {
    fail('misconfigured', 'No certificate of the authority in its CertEnroll folder', $answer);
}

// The state of the service is written by WMI in English: "Running", "Stopped", "Start Pending"...
value('service', text.lower(text.join(text.words($authority['service']), '-')));
value('certificate', $authority['subject']);
value('days-left', $authority['days']);