Microsoft PKI: revoke expired certificates
Description
I have written the script below to cleanup the CA database by revoking the expired certificates. First, the script performs three checks and then revoke the expired certificates:
- a valid certificate for the same CommonName exists
- more than one valid certificate for the same CommonName exists
- no valid certificate for the same CommonName exists
Finally, the script creates three reports (csv files in the folder C:\Scripts) that will contain the details of the revoked certificates.
Regarding the revocation, the reason “Hold” is used to allow a quick rollback in case of error.
Cmdlet references
The following cmdlets have been used in the script:
- Get-CertificationAuthority : retrieves all Enterprise Certification Authorities from a current Active Directory forest
- Get-IssuedRequest : Retrieves issued certificate requests from Certification Authority (CA) database. Issued certificate requests contain only valid and unrevoked issued certificates.
- Revoke-Certificate : Revokes specified certificate request with a specified reason. A revoked certificate will appear in a subsequent certificate revocation lists (CRLs), provided the revocation date is effective at the time the CRL was published.
All of this cmdlets are member of the Powershell module PSPKI that can downloaded here
This useful module offers a lot of cmdlets to manage your Microsoft PKI. Some examples:
Add-AuthorityInformationAccess (Alias: Add-AIA) Add-CAAccessControlEntry (Alias: Add-CAACL) Add-CAKRACertificate Add-CATemplate Add-CertificateEnrollmentPolicyService Add-CertificateEnrollmentService Add-CertificateTemplateAcl Add-CRLDistributionPoint (Alias: Add-CDP) Add-ExtensionList Approve-CertificateRequest Connect-CertificationAuthority (Alias: Connect-CA) Convert-PemToPfx Convert-PfxToPem Deny-CertificateRequest Disable-CertificateRevocationListFlag (Alias: Disable-CRLFlag) Disable-InterfaceFlag Disable-KeyRecoveryAgentFlag (Alias: Disable-KRAFlag) Disable-PolicyModuleFlag Enable-CertificateRevocationListFlag (Alias: Enable-CRLFlag) Enable-InterfaceFlag Enable-KeyRecoveryAgentFlag (Alias: Enable-KRAFlag) Enable-PolicyModuleFlag Get-ADKRACertificate Get-AuthorityInformationAccess (Alias: Get-AIA) Get-CACryptographyConfig Get-CAExchangeCertificate Get-CAKRACertificate Get-CASchema Get-CASecurityDescriptor (Alias: Get-CAACL) Get-CATemplate Get-CertificateContextProperty Get-CertificateRequest
… and more here
The script has been successfully tested on a Microsoft PKI running on a Windows 2012R2 Server Standard edition
The script
cls # list CA $CAlist = Get-CertificationAuthority Write-Host "The following CA have been found:" $CAlist write-host "" # Array def $issuedcerts_arr = @() $duplicateValidCerts = @() $RevokeCerts = @() $NoNewCerts_ManualCheckRequired = @() # list expired certificates $CAlist | % { $CAName = $_.DisplayName write-host "Listing all issued certificates for $CAName..." $issuedcerts_arr += Get-CertificationAuthority -name $CAName | Get-IssuedRequest | select *,@{n='IssuingCAName';e={$CAName}} } $expiredCerts = $issuedcerts_arr | ? { $_.NotAfter -lt (get-date) } $expiredCerts | % { $ExpiredCert = $_ $ExpiredcertCN = $_.CommonName $ExpiredcertDate = $_.NotAfter $validCertFoundTag = 0 $ValidCert = @($issuedcerts_arr | ?{$_.CommonName -eq $ExpiredcertCN -and $_.NotAfter -gt (Get-Date)}) if ($ValidCert.count -eq 1) { write-host "You can revoke the certificate for $ExpiredcertCN that expires on $ExpiredcertDate (valid cert : "$ValidCert.RequestID" / "$ValidCert.NotAfter" / "$ValidCert.ConfigString")" -ForegroundColor DarkCyan $RevokeCerts += $ExpiredCert $ExpRequestID = $ExpiredCert.RequestID $ExpRequestCA = $ExpiredCert.IssuingCAName Get-CertificationAuthority -name $ExpRequestCA | Get-IssuedRequest -filter "RequestID -eq $ExpRequestID" | Revoke-Certificate -Reason "Hold" } elseif ($ValidCert.count -gt 1) { write-host "The expired certificate ($ExpiredcertCN valid to $ExpiredcertDate) can be revoked. However, please check the following certificates. More than one valid certificate has been found for the same CommonName" -ForegroundColor Yellow $duplicateValidCerts += $ValidCert $RevokeCerts += $ExpiredCert $ExpRequestID = $ExpiredCert.RequestID $ExpRequestCA = $ExpiredCert.IssuingCAName Get-CertificationAuthority -name $ExpRequestCA | Get-IssuedRequest -filter "RequestID -eq $ExpRequestID" | Revoke-Certificate -Reason "Hold" } else { write-host "No new valid cert exits for $ExpiredcertCN (expires on $ExpiredcertDate)" -ForegroundColor Magenta $ValidCert $NoNewCerts_ManualCheckRequired += $ExpiredCert $ExpRequestID = $ExpiredCert.RequestID $ExpRequestCA = $ExpiredCert.IssuingCAName Get-CertificationAuthority -name $ExpRequestCA | Get-IssuedRequest -filter "RequestID -eq $ExpRequestID" | Revoke-Certificate -Reason "Hold" } } # Create revocation reports $RevokeCerts_CSV = "C:\Scripts\Report_RevokedCerts_"+((get-date).ToString("yyyyMMdd-HHmmss"))+".csv" $RevokeCerts | ConvertTo-Csv -Delimiter ";" -NoTypeInformation | Out-File -Encoding utf8 $RevokeCerts_CSV $duplicateValidCerts_CSV = "C:\Scripts\Report_DuplicatedValidCerts_"+((get-date).ToString("yyyyMMdd-HHmmss"))+".csv" $duplicateValidCerts | ConvertTo-Csv -Delimiter ";" -NoTypeInformation | Out-File -Encoding utf8 $duplicateValidCerts_CSV $NoNewCerts_ManualCheckRequired_CSV = "C:\Scripts\Report_NoNewCerts_ManualCheckRequired_"+((get-date).ToString("yyyyMMdd-HHmmss"))+".csv" $NoNewCerts_ManualCheckRequired | ConvertTo-Csv -Delimiter ";" -NoTypeInformation | Out-File -Encoding utf8 $NoNewCerts_ManualCheckRequired_CSV
My Powershell script categories
- Active Directory
- Cluster
- Database
- Exchange
- Files and folders
- Hardware
- Network
- Operating System
- PKI
- SCCM
- Service and process
- Tips
- VMWare