NPS Certificate Monitor

Microsoft.NetworkPolicyServer.CertificateExpired (UnitMonitor)

Monitors the certificate expiration date

Knowledge Base article:

Summary

Monitors the expiration date of the certificates in the personal computer store.

Configuration

Critical state if certificate has less than 7 days validity before expiring

Warning state if certificate has less than 21 days validity before expiring

Resolutions

Replace the certificate and remove expired certificate from the personal store.

Element properties:

TargetMicrosoft.NetworkPolicyServer.NPSServers
Parent MonitorSystem.Health.ConfigurationState
CategoryConfigurationHealth
EnabledTrue
Alert GenerateTrue
Alert SeverityMatchMonitorHealth
Alert PriorityNormal
Alert Auto ResolveTrue
Monitor TypeMicrosoft.NetworkPolicyServer.PowerShellThreeState.MT
RemotableTrue
AccessibilityPublic
Alert Message
NPS - Certificate Monitor
Please see the alert context for details.
RunAsDefault

Source Code:

<UnitMonitor ID="Microsoft.NetworkPolicyServer.CertificateExpired" Accessibility="Public" Enabled="true" Target="Microsoft.NetworkPolicyServer.NPSServers" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" TypeID="Microsoft.NetworkPolicyServer.PowerShellThreeState.MT" ConfirmDelivery="true">
<Category>ConfigurationHealth</Category>
<AlertSettings AlertMessage="Microsoft.NetworkPolicyServer.CertificateExpired_AlertMessageResourceID">
<AlertOnState>Warning</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>MatchMonitorHealth</AlertSeverity>
<AlertParameters>
<AlertParameter1>$Data/Context/Property[@Name='Certificate Subject']$</AlertParameter1>
<AlertParameter2>$Data/Context/Property[@Name='Certificate Expires']$</AlertParameter2>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="UIGeneratedOpStateId1a9c163f51f742299aaff363b2a0b7ec" MonitorTypeStateID="Healthy" HealthState="Success"/>
<OperationalState ID="UIGeneratedOpStateIdd47536c0b1c74bb299ea61e0a2e705d7" MonitorTypeStateID="Warning" HealthState="Warning"/>
<OperationalState ID="UIGeneratedOpStateIddad3d169a8024f0a8816671d58c060e2" MonitorTypeStateID="Critical" HealthState="Error"/>
</OperationalStates>
<Configuration>
<HealthyExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Healthy</Value>
</ValueExpression>
</SimpleExpression>
</HealthyExpression>
<WarningExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Warning</Value>
</ValueExpression>
</SimpleExpression>
</WarningExpression>
<CriticalExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Status']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">Critical</Value>
</ValueExpression>
</SimpleExpression>
</CriticalExpression>
<IntervalSeconds>14400</IntervalSeconds>
<TimeoutSeconds>300</TimeoutSeconds>
<ScriptName>NPS-CertificateMonitor.ps1</ScriptName>
<ScriptBody><Script><![CDATA[
$culture = [System.Globalization.CultureInfo] 'en-US'
[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
[System.Threading.Thread]::CurrentThread.CurrentCulture = $culture

$Script:API = new-object -comObject "MOM.ScriptAPI"
$Script:Bag = $Script:API.CreatePropertyBag()

$warning = $false
$store=new-object System.Security.Cryptography.X509Certificates.X509Store("My","LocalMachine")
$store.open("ReadOnly")
ForEach($cert in $store.certificates)
{
If($cert.NotAfter.subtract([datetime]::now).days -lt 7)
{
$Script:API.LogScriptEvent("NPS-CertificateMonitor.ps1", 0, 0, "Found expired certificate")
$Script:Bag.AddValue("Status","Critical")
$Script:Bag.AddValue("Certificate Expires", $cert.NotAfter)
$Script:Bag.AddValue("Certificate Subject", $cert.subject)
$Script:API.Return($Bag)
#$Script:Bag
exit
}

If($cert.NotAfter.subtract([datetime]::now).days -lt 21)
{
$Script:API.LogScriptEvent("NPS-CertificateMonitor.ps1", 0, 0, "Found soon to expire certificate")
$warning = $true
$WarningCert = $cert
}
}
If ($warning)
{
$Script:Bag.AddValue("Status","Warning")
$Script:Bag.AddValue("Certificate Expires", $cert.NotAfter)
$Script:Bag.AddValue("Certificate Subject", $WarningCert.subject)
$Script:API.Return($Bag)
#$Script:Bag
}
Else
{
$Script:API.LogScriptEvent("NPS-CertificateMonitor.ps1", 0, 0, "All certificates are up to date")
$Script:Bag.AddValue("Status","Healthy")
$Script:Bag.AddValue("Certificate Expires", $cert.NotAfter)
$Script:Bag.AddValue("Certificate Subject", $cert.subject)
$Script:API.Return($Bag)
#$Script:Bag
}
]]></Script></ScriptBody>
</Configuration>
</UnitMonitor>