Monitoring windows certificate expiration checks

Hi,
I’m not sure if topic is valid but here you have a part of the code which i wrote some time ago for cover similar thing. Hope i will help a bit someone:

##################################################################################################

VERSION: 1.3

CHANGES:

2022.09.19: 1.0 Initial pre-release version (test)

2022.10.25: 1.1 Implementation of blackout list

2022.10.26: 1.2 Extend functionality of blackout list

2022.10.28: 1.3 Add printing Excluded Certificates with status OK + few cosmetic output string

##################################################################################################

########################
#Thresholds declaration#
########################

Param(
[int]$critical = 10,
[int]$warning = 30
)

#########################
#All necessary variables#
#########################

$CERTDIR = “Cert:\LocalMachine\My”
$bReturnOK = $TRUE
$bReturnCritical = $FALSE
$bReturnWarning = $FALSE
$bReturnUnknown = $FALSE
$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3
$nWarning = $warning
$nCritical = $critical
$dtCurrent = Get-Date
$strCritical = “”
$strWarning = “”
$strUnknown = “Error in plugin - please check manually!”
$strOK = “All Personal Certificates are valid!”
$excludedCRT = “”

###########################
#Blackout list declaration#
###########################

$blackout=@(
“CN=MS-Organization-P2P-Access [2021]”,
“CN=MS-Organization-P2P-Access [2022]”,
“CN=MS-Organization-P2P-Access [2023]”,
“CN=MS-Organization-P2P-Access [2024]”,
“CN=MS-Organization-P2P-Access [2025]”,
“CN=MS-Organization-P2P-Access [2026]”,
“CN=MS-Organization-P2P-Access [2027]”,
“_NotMonitored”
)

############################################################
#Blackout list definition + collecting blacout Certificat #
############################################################

$exclude=Get-ChildItem -Path Cert:\LocalMachine\My -Recurse | ? {
($blackout -notcontains $.Issuer -and $blackout -notcontains $.FriendlyName -and $blackout -notcontains $_.SerialNumber)} | select SerialNumber
$excludedCRT=$exclude
[string]$excludedCRT=$exclude -replace’@{’
[string]$excludedCRT=$excludedCRT -replace’}‘,’,’
[string]$excludedCRT="Excluded Certificates from monitoring are: " + $excludedCRT

$objCertificates=Get-ChildItem -Path Cert:\LocalMachine\My -Recurse | ? {
($blackout -notcontains $.Issuer -and $blackout -notcontains $.FriendlyName -and $blackout -notcontains $_.SerialNumber)}

###################################################################################################################################
#Exit loop - exit from plugin with status OK if Personal certificate Store is Empty or is empty and handling excluded certificates#
###################################################################################################################################

if (-Not $objCertificates)
{
write-host 0 “Certificates” - “Personal Certificate Store is empty.”
exit $bReturnOK
}

#######################################
#Main loop Expiration Date calculation#
#######################################

foreach ($objCertificate in $objCertificates)
{
$dtRemain = $objCertificate.NotAfter - $dtCurrent
$nRemainDays = $dtRemain.Days

###################################################################################
#Sub loop for check criteria OK/Warning/Critical/UNKNOWN and feed output variables#
###################################################################################

if ($nRemainDays -lt 0)
{
$strCritical = $strCritical + $objCertificate.SubjectName.Name.ToString() + " EXPIRED! " + $objCertificate.NotAfter.ToString() + " "
$bReturnCritical = $TRUE

} Elseif ( $nRemainDays -lt $nCritical)
{
$strCritical = $strCritical + $objCertificate.SubjectName.Name.ToString() + " WILL EXPIRE: " + $objCertificate.NotAfter.ToString() + " "
$bReturnCritical = $TRUE

} Elseif ( $nRemainDays -lt $nWarning)
{
$strWarning = $strWarning + $objCertificate.SubjectName.Name.ToString() + " WILL EXPIRE: " + $objCertificate.NotAfter.ToString() + " "
$bReturnWarning = $TRUE

} Elseif ($nRemainDays -gt $nWarning -or $nRemainDays -gt $nCritical)
{
$strOK = $strOK
$bReturnOK = $TRUE
} Else
{
$strUnknown = $strUnknown
$returnStateUnknown = $TRUE

}

##############################################################################
#Print loop ServiceName, ReturnCode and Description output in check_mk format#
##############################################################################

if ($bReturnCritical)
{
write-host 2 “Certificates” - ($strCritical + $strWarning)
exit
}
elseif ($bReturnWarning)
{
write-host 1 “Certificates” - $strWarning
exit
}
elseif ($bReturnOK)
{
write-host 0 “Certificates” - $strOK $excludedCRT
exit
}
else
{
write-host 3 “Certificates” - $strUnknown
exit
}
}

###########
#Few hints#
###########

Put “write-host $objCertificates” in line 70 to check which certificates will be analyzed

By modifying line 69 you can change functionality of blackout list using format: “-and $blackout -notcontains $_.”

Thresholds are defined in days

You can extend fuctionality of that plugin by adding another loop. Example: check Certification from Stores like Root, CA, AuthRoot, SharePoint etc. :slight_smile:

And here you have an example of implementation of it: