Recently, I have encountered an issue with Active Directory, LDAPS and multiple Server authentication certificates in the default computer certificate store of my domain controllers.
The LocalComputer certificate store contained one certificate for AD LDAPS and the other was dedicated to the WinRM HTTPS listener.
In that specific case, the only way to hard set and link a specific certificate to the AD LDAPS listener was to play with the Windows Service certificate store.
The following script will help you to understand where are located the Local computer certificates in the registry and how to copy them to the service of your choice.
It is required to run this script with administrative permissions on the required target system.
The script will guide you through interactive menu to choose :
- the certificate currently installed on the Local Computer cert store
- the Windows service that need the certificate
# Copy an existing certificate (in computer certificate store) to a specific service certificate store # Menu function function display_menu($array){ #$array $menu = @{} for ($i=1;$i -le $array.count; $i++) { Write-Host "$i. $($array[$i-1])" $menu.Add($i,($array[$i-1])) } [int]$ans = Read-Host 'Enter selection' $selection = $menu.Item($ans) return $selection } # List the folders of the selected certificate store $certstore_content = Get-ChildItem Cert:\LocalMachine | select-object Name write-host "Choose the source certificate store folder:" $choicefolder = display_menu($certstore_content.Name) # List the certificates in the selected certificate store $certlist = Get-ChildItem cert:\LocalMachine\$choicefolder | ` ForEach-Object { if ($_.Extensions.oid.FriendlyName -match "Certificate Template Information") { $templateName = $_.extensions.Format(1)[0].split('(')[0] -replace "template=" } else { $templateName = "No Template" } $_.Thumbprint+" (subject="+$_.Subject+", issuer="+$_.Issuer+", template=$templateName)" } write-host "Choose your certificate:" $choicecert = display_menu($certlist) $choicecert_thumbprint = $choicecert.split(" ")[0] # List destination service $service_list = get-service | ForEach-Object { $_.Name+" (Display Name="+$_.DisplayName+")"} write-host "Choose your Windows Service destination store:" $choiceservice = display_menu($service_list) $choiceservice_name = $choiceservice.split(" ")[0] $cert_LocalMachine_regpath = "HKLM:\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\$choicecert_thumbprint" $cert_Service_regpath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Services\$choiceservice_name\SystemCertificates\MY\Certificates\$choicecert_thumbprint" if (-not(Test-Path $cert_Service_regpath)) { New-Item $cert_Service_regpath -Force } if (-not(Get-ItemProperty -path $cert_Service_regpath -Name "Blob" -ErrorAction SilentlyContinue)) { New-ItemProperty -Path $cert_Service_regpath -Name "Blob" -Value (Get-ItemProperty "$cert_LocalMachine_regpath").Blob -PropertyType "Binary" }
My Powershell script categories
- Active Directory
- Cluster
- Database
- Exchange
- Files and folders
- Hardware
- Network
- Operating System
- PKI
- SCCM
- Service and process
- Tips
- VMWare
Sample of the cmdlets availables in the PSPKI module (full list here):
Add-AdCertificate
Add-AdCertificateRevocationList
Add-AuthorityInformationAccess (Alias: Add-AIA)
Add-CAAccessControlEntry (Alias: Add-CAACL)
Add-CATemplate
Add-CertificateEnrollmentPolicyService
Add-CertificateEnrollmentService
Add-CertificateTemplateAcl
Add-CRLDistributionPoint (Alias: Add-CDP)
Convert-PemToPfx
Convert-PfxToPem
Deny-CertificateRequest
Disable-PolicyModuleFlag
Get-CATemplate
Get-CertificateRequest
Get-CertificateRevocationList (Alias: Get-CRL)
Get-CertificateRevocationListFlag (Alias: Get-CRLFlag)
Get-CertificateTemplate
Get-CertificateTemplateAcl
Get-IssuedRequest
Get-PendingRequest
Publish-CRL
Remove-CATemplate
Remove-ExtensionList
Restart-CertificationAuthority
Revoke-Certificate
Start-CertificationAuthority
Test-WebServerSSL
Uninstall-CertificationAuthority