# Detect-CertificatesWithoutSubject.ps1 # Scans LocalMachine and CurrentUser certificate stores # for certificates with missing, empty, or placeholder Subject fields (e.g. "CN=", whitespace, or null) # and exports matching certificates to individual .cer files for further analysis. $stores = @( "Cert:\LocalMachine\My", "Cert:\LocalMachine\Root", "Cert:\LocalMachine\CA", "Cert:\LocalMachine\AuthRoot" # , # "Cert:\CurrentUser\My", # "Cert:\CurrentUser\Root", # "Cert:\CurrentUser\CA", # "Cert:\CurrentUser\AuthRoot" ) $exportDir = "C:\Temp\DetectedCerts" New-Item -ItemType Directory -Force -Path $exportDir | Out-Null Write-Host "`nScanning LocalMachine and CurrentUser certificate stores..." -ForegroundColor Cyan $results = @() foreach ($storePath in $stores) { if (Test-Path $storePath) { $certs = Get-ChildItem -Path $storePath foreach ($cert in $certs) { $subjectName = $cert.SubjectName.Name # detect missing / placeholder subject $isInvalidSubject = ( [string]::IsNullOrWhiteSpace($subjectName) -or $subjectName -match '^CN\s*=\s*$' ) if ($isInvalidSubject) { $hasSAN = $false try { $sanExt = $cert.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Subject Alternative Name" } if ($sanExt) { $hasSAN = $true } } catch { } # Add to results list $results += [PSCustomObject]@{ Store = $storePath FriendlyName = $cert.FriendlyName Subject = $cert.Subject SubjectName = $subjectName HasSAN = $hasSAN NotAfter = $cert.NotAfter Issuer = $cert.Issuer Thumbprint = $cert.Thumbprint } # Export each detected certificate to file $safeThumb = $cert.Thumbprint -replace '[^A-Za-z0-9]', '' $exportPath = Join-Path $exportDir ("DetectedCert_" + $safeThumb + ".cer") try { Export-Certificate -Cert $cert -FilePath $exportPath -Force | Out-Null Write-Host "Exported: $exportPath" -ForegroundColor Gray } catch { Write-Warning "Failed to export certificate $($cert.Thumbprint): $_" } } } } } if ($results.Count -gt 0) { Write-Host "" Write-Host "WARNING: Found certificates with missing, empty, or placeholder Subject." -ForegroundColor Yellow $results | Sort-Object Store | Format-Table -AutoSize Store, FriendlyName, SubjectName, Subject, HasSAN, NotAfter, Thumbprint Write-Host "`nExported certificates to: $exportDir" -ForegroundColor Cyan } else { Write-Host "" Write-Host "All certificates have valid Subject names." -ForegroundColor Green } # Optional: export CSV summary # $results | Export-Csv -Path (Join-Path $exportDir "DetectedCertsSummary.csv") -NoTypeInformation -Encoding UTF8