Strong certificate mapping enforcement is an upcoming requirement in many Windows environments. Before enabling it, administrators need visibility into any weakly mapped certificates to avoid authentication failures. This article walks through a complete PowerShell solution for auditing weak certificate mappings across all domain controllers.
If you wish to read the required updates and settings please see this article here
Step 1: Collecting Event Logs from Domain Controllers
This script queries every domain controller for the following Kerberos KDC-related event IDs: 9, 39, 40, 41. It filters events from the last 24 hours and exports them to a CSV for further analysis.
# Ensure AD module is loaded
Import-Module ActiveDirectory
# Get all domain controllers
$DomainControllers = (Get-ADDomainController -Filter *).Hostname
# Event filter settings
$LogName = 'System'
$EventIDs = 9,39,40,41
$StartTime = (Get-Date).AddHours(-24)
# Store results
$Results = @()
foreach ($DC in $DomainControllers) {
Write-Host "Checking ${DC}..." -ForegroundColor Cyan
try {
$Events = Get-WinEvent -ComputerName $DC -FilterHashtable @{LogName=$LogName; Id=$EventIDs; StartTime=$StartTime} -ErrorAction Stop
if ($Events) {
foreach ($Event in $Events) {
$Results += [PSCustomObject]@{
ComputerName = $DC
TimeCreated = $Event.TimeCreated
EventID = $Event.Id
Message = $Event.Message
}
}
} else {
Write-Host "No matching events found on ${DC} in last 24 hours." -ForegroundColor Yellow
}
}
catch {
Write-Host "Failed to query ${DC}: $($_.Exception.Message)" -ForegroundColor Red
}
}
# Export results to CSV
if ($Results) {
$Results | Export-Csv -Path ".\DC_Events_Last24Hours.csv" -NoTypeInformation
Write-Host "Results exported to DC_Events_Last24Hours.csv" -ForegroundColor Green
} else {
Write-Host "No events found on any Domain Controllers in the last 24 hours." -ForegroundColor Yellow
}
Step 2: Parsing the Exported CSV for Certificate Subjects
Once the events are exported, this second script extracts certificate subjects and displays them in a clean, readable format. It also saves the output to a text file in the same directory.
param(
[Parameter(Mandatory=$true)]
[string]$CSVFile
)
if (-not (Test-Path $CSVFile)) { Write-Error "CSV file not found: $CSVFile"; exit }
$ScriptDir = Split-Path -Parent $PSCommandPath
if (-not $ScriptDir) { $ScriptDir = (Get-Location).Path }
$OutFile = Join-Path $ScriptDir "Extracted_CertSubjects.txt"
$csvData = Import-Csv -Path $CSVFile
$matches = @()
foreach ($row in $csvData) {
$regex1 = [regex] "Certificate Subject:\s*@@@CN=(.+)"
$match1 = $regex1.Match($row.Message)
if ($match1.Success) { $matches += $match1.Groups[1].Value.Trim() }
else {
$row.Message -split "`r?`n" | ForEach-Object {
$line = $_
$regex2 = [regex] "Certificate Subject:\s*@@@CN=(.+)"
$match2 = $regex2.Match($line)
if ($match2.Success) { $matches += $match2.Groups[1].Value.Trim() }
}
}
}
$matches = $matches | Sort-Object -Unique
# Output to console
Write-Host "`nExtracted Certificate Subjects:" -ForegroundColor Cyan
$matches | ForEach-Object { Write-Host $_ }
# Save to text file
$matches | Out-File -FilePath $OutFile -Encoding UTF8
Write-Host "`nCertificate subjects saved to: $OutFile" -ForegroundColor Green
Step 3: Using the Scripts Together
- Run the event collection script first to gather the last 24 hours of relevant KDC events across all domain controllers.
- Use the exported CSV as input to the CSV parsing script.
- Review the extracted certificate subjects to identify any users or devices with weak mappings.
Conclusion
By combining these two scripts, administrators can proactively identify weak certificate mappings that would fail once strong certificate mapping enforcement is enabled. This approach ensures compliance and reduces the risk of unexpected authentication failures.