Monday, January 21, 2013

Windows Certificate Expiration Email Reminders


Have a ton of windows servers and a ton of certificates on those servers?  Are those certificates expiring before you remember to renew them?  Schedule this powershell script to run daily and it will check the servers you specify and email you when the certificates on those servers are about to expire.

Modify the first four variables of the following powershell script to your environment's setup and schedule the it to run daily.  It should send you an email 14 days in advance of a certificate expiring on any of the machines listed in the $Computers variable.  It will also email about expired certificates.

# ******************** script starts here *************************
$Computers = "server1", "server2", "server3" #list of servers to check
$SmtpServer = "smtpserver.domain.com"
$MailFrom = "mailfrom@domain.com"
$MailTo = "mailto@domain.com"

# Change above settings.  No need to change anything below.
$DaysToExpire = 14  
# increase $DaysToExpire if you want more of a warning, decrease it if you would like less
$StoreName = "My"
# change $StoreName above to one of the valuse below if you wish to check a store other then the personal store, for example if you're worried about intermediate CA certs expiring
# "AddressBook", "AuthRoot", "CertificateAuthority", "Disallowed", "Root", TrustedPeople", "TrustedPublisher"

$deadline = (Get-Date).AddDays($DaysToExpire)

ForEach ($c in $Computers) {
    Try {

        $store=new-object System.Security.Cryptography.X509Certificates.X509Store("\\$c\$StoreName","LocalMachine")

        $store.open("ReadOnly")

        # all certs
        #$store.certificates | Select *
       
        # will expire certs
        $store.Certificates | ? {$_.NotAfter -le ($deadline) -and $_.NotAfter -ge (Get-Date)} | Select *, @{Label="ExpiresIn"; Expression={($_.NotAfter - (Get-Date)).Days}} | % {

            $ExpiresIn = $_.ExpiresIn
            $NotAfter = $_.NotAfter

            $emailBody = "The following certificate on $c will expire in $ExpiresIn days on $NotAfter" + [System.Environment]::NewLine
            $emailBody += $_ | select * | Out-String

            Send-MailMessage -SmtpServer $SmtpServer -From $MailFrom -To $MailTo -Subject "Certificate about to Expire on $c" -Body $emailBody

            Write-Host $emailBody
        }
         
        # expired certs
        $store.Certificates | ? {$_.NotAfter -lt (Get-Date)} | Select *, @{Label="ExpiredOn";Expression={$_.NotAfter}} | % {

            $ExpiredOn = $_.ExpiredOn

            $emailBody = "The following certificate on $c expired on $ExpiredOn" + [System.Environment]::NewLine
            $emailBody += $_ | select * | Out-String

            Send-MailMessage -SmtpServer $SmtpServer -From $MailFrom -To $MailTo -Subject "CERTIFICATE EXPIRED on $c" -Body $emailBody

            Write-Host $emailBody
        }

    }
    Catch {          
        $emailBody = "Errors detected during certification reminder powershell script execution. " + [System.Environment]::NewLine + [System.Environment]::NewLine + "$($c): $($error[0])"

        Send-MailMessage -SmtpServer $SmtpServer -From $MailFrom -To $MailTo -Subject "Certification Reminder Powershell Script Execution Error" -Body $emailBody

        Write-Host -foregroundcolor Yellow $emailBody #"$($c): $($error[0])"
    }

}