Microsoft PKI: revoke expired certificates
Microsoft PKI: revoke expired certificates

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

Microsoft PKI: revoke expired certificates
Tagged on:

Leave a Reply

Your email address will not be published. Required fields are marked *