<# .SYNOPSIS Script uses certutil to read CA-dabase and send email with certificate expiring withing defined number of months. .DESCRIPTION Script uses certutil.exe to export certificates from CA as CSV and evaluates expiration time and sends email if expiration date is lower than defined number of months. Script runs on Certificate Authority (CA) or can be used on any other machine after specifying -Config "\" in CertUtil command line Tested on de-DE and en-US. For additional languages, please check the Certutil -View CSV output and adjust CSV-header as needed. .EXAMPLE .\CertificateExpiration.ps1 This Example will search for all issued certificates with expiration date lower than defined in $month and shows results on the screen. No email is sent if no expiring certificates are found. #> $Screenoutput=$true ### Display Messages when running script [Int]$Months = 3 ### Expiration-date (today+x months) $Mailrecipients = "administrator@mytld.tld" ### Mail recipients (Multiple: "No1@mytld.tld","No2@mytld.tld") $SMTPServer = 'mail.mytld.tld' ### SMTP-Server address $FromAddress = 'PKI-Reminder@mytld.tld' ### From E-Mail address $MessageSubject = "Certificate expiration reminder from $env:COMPUTERNAME.$env:USERDNSDOMAIN" ### Message subject #Define CSV-Header based on System locale if (([cultureInfo]::InstalledUICulture).Name -eq "de-DE") { $Parameter='Anforderungs-ID','Seriennummer','Antragstellername','Ablaufdatum des Zertifikats','Anforderung: Allgemeiner Name','Anforderung: Disposition','Zertifikatvorlage','Erneuert' } elseif (([cultureInfo]::InstalledUICulture).Name -eq "en-US") { $Parameter='Request ID','Serial Number','Requester Name','Certificate Expiration Date','Request Common Name','Request Disposition','Certificate Template','Renewed' } else { Write-Warning "Operating system locale not supported. Please check Certutil output and modify header if needed" Exit } #HTML Style $style = @" "@ #variables $table = @() #Read Database as CSV (local) $dump=certutil.exe -view csv | ConvertFrom-Csv #Read Database as CSV (remote) #$dump=certutil.exe -config "PKI-SubCA\SubCA" -view csv | ConvertFrom-Csv $certificates = $dump | Where-Object {($_."$($parameter[1])" -notcontains 'LEER') -and $_."$($parameter[1])" -notcontains 'EMPTY'} | Select-Object -Property $Parameter[0],$Parameter[1],$Parameter[2],$Parameter[3],$Parameter[4],$Parameter[5],$Parameter[6],$Parameter[7] #cycle through array and search for matching certificates for($i=0;$i -lt $certificates.Count;$i++) { if ((get-date).addmonths($months) -gt (get-date($certificates[$i]."$($Parameter[3])")) -and ((get-date) -lt (get-date($certificates[$i]."$($Parameter[3])")))) { # certificate expires in $months months for ($j=0; $j -lt $certificates.count; $j++) { if (([int]$certificates[$j]."$($Parameter[0])" -gt [int]$certificates[$i]."$($Parameter[0])") -and ($certificates[$j]."$($Parameter[2])" -eq $certificates[$i]."$($Parameter[2])") -and ($certificates[$j]."$($Parameter[6])" -eq $certificates[$i]."$($Parameter[6])")) { $certificates[$i]."$($Parameter[7])"=$true } } if ($Screenoutput) { Write-Host "Checking certificate:`t $($certificates[$i].'Anforderungs-ID')" Write-Host "Serial number:`t`t`t $($certificates[$i].$($Parameter[1])) expires in"((New-TimeSpan -Start (get-date) -End (get-date($certificates[$i].$($Parameter[3])))).days) "days!"-ForegroundColor Red Write-Host "Requester Name:`t`t`t $($certificates[$i].$($Parameter[2]))" Write-Host "Request Common Name:`t $($certificates[$i].$($Parameter[4]))" Write-Host "Certificate Template:`t $($certificates[$i].$($Parameter[6]))" Write-Host "Please renew certificate prior to: $($certificates[$i].$($Parameter[3]))" -ForegroundColor Red if ($certificates[$i].$($Parameter[7]) -eq $true) {Write-Host "Renewed" -BackgroundColor Green } Write-Host "`n" } if ($certificates[$i]."$($Parameter[6])" -like "1.3.6*") {$certificates[$i]."$($Parameter[6])" = $certificates[$i]."$($Parameter[6])".split(" ")[1]} $table += $certificates[$i] | Sort-Object $Parameter[3] | Select-Object -Property $Parameter[0],$Parameter[1],$Parameter[2],$Parameter[3],$Parameter[4],$Parameter[6],$Parameter[7] } } [string]$html= $table | Select-Object $parameter[0],$parameter[1],$parameter[2],$parameter[3],$parameter[4],$parameter[6],$parameter[7] | ConvertTo-Html -Head $style # | Set-Content c:\temp\test.html #Send Mail if Certificate expiration is within specified timeframe if ($table.Count -gt 0) { Send-MailMessage -Encoding UTF8 -From $FromAddress -To $Mailrecipients -Body $html -BodyAsHtml -Priority High -SmtpServer $SMTPServer -Subject $MessageSubject -ErrorAction SilentlyContinue }