Script to sync Domain Controller SSL Certificates to a specific host

We have an application that uses LDAP over SSL to authenticate users via Active Directory. The server running the application is a member of the domain and has the domains Root CA installed in it’s local certificate store.

Technically the Root CA should be good enough for the server and any applications on it to trust the SSL certificates on our domain controllers because they are signed by that Root CA. Not the case for this application.

We have four Domain Controllers each with a different SSL certificate that expires yearly and each with a different expiry date. Exporting and importing these certificates manually is going to be a huge annoyance.

I wrote a PowerShell script to handle doing it automatically for us. This script is being run against 2012 R2 Domain controllers which is why I use the PowerShell Module exporting the certificates and the target isĀ  2008 R2 which is why the import is handled via ‘certutil’. You could easily swap these out in the script to suite your needs.

# Domain Controller SSL Certificate syncing script
# Created by: Eric Schewe
# Created on: 2018-10-11
# Permission Requirements
# -----------------------------------------------------
# "Remote Management Users" in the domain that holds the DCs you're pulling the certificates from
# Local Admin on the destination server
# Login As Batch Job on what ever server you're running the script from unless you're running it as a local admin on the destination server
# Other requirepments
# -----------------------------------------------------
# A directory called C:\Temp must exist on all servers involved

# The domain we want to get DC certs from
$domainInfo = Get-ADDomain <FQDN OF YOUR DOMAIN>

# Server we're installing the certificates on
$destinationServer = "<FQDN OF THE DESTINATION SERVER>"

# For each Domain Controller in the domain do the following
foreach ($dc in $domainInfo.ReplicaDirectoryServers) {

    # Open a remote session to the DC
    Write-Host "Connecting to $($dc)"
    $sessionCertServer = New-PSSession -ComputerName $dc -EnableNetworkAccess

    # Find the certificates thumbprint that matches the DCs FQDN
    Write-Host "Getting cert list for $($dc)"
    $thumbPrint = Invoke-Command -Session $sessionCertServer -ScriptBlock {(Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "$($dc)"}).Thumbprint}

    # Debugging
    Write-Host "Dumping thumb prints from $($dc)"
    Write-Host $thumbPrint

    # Export the certificate on the remote DC, based on it's thumbprint
    Write-Host "Exporting $($thumbPrint) on $($dc)"
    Invoke-Command -Session $sessionCertServer -ScriptBlock {Get-ChildItem -Path Cert:\LocalMachine\My$thumbPrint | Export-Certificate -FilePath "C:\Temp$($args[0])-159969.crt" -Type CERT} -argumentlist $dc

    # Copy the exported certificate from the remote server to the local server
    Write-Host "Copying C:\Temp$($dc)-159969.crt from $dc to C:\Temp locally"
    Copy-Item -FromSession $sessionCertServer -Path "C:\Temp$($dc)-159969.crt" -Destination "C:\temp\"

    # Remove the exported certificate file on the remote server and close the session
    Write-Host "Cleaning up remote files and sessions"
    Invoke-Command -Session $sessionCertServer -ScriptBlock {Remove-Item -path "C:\Temp$($args[0])-159969.crt"} -argumentlist $dc
    Remove-PSSession -Session $sessionCertServer


# Open a session to the server we're putting the certs on
$sessionDestinationServer = New-PSSession -ComputerName $destinationServer -EnableNetworkAccess

# Copy each 
foreach ($dc in $domainInfo.ReplicaDirectoryServers) {

    # Import the exported certificate file on the local server and then delete it
    Write-Host "Moving C:\Temp$($dc)-159969.crt from local server to destination server"
    Copy-Item -ToSession $sessionDestinationServer -Path "C:\Temp$($dc)-159969.crt" -Destination "C:\temp\"

    Write-Host "Importing certificate for $($dc) into destination server"
    Invoke-Command -Session $sessionDestinationServer -ScriptBlock {certutil -enterprise -f -v -AddStore "Root" "C:\Temp$($args[0])-159969.crt"} -argumentlist $dc

    Write-Host "Deleting certificate files for $($dc)"
    Remove-Item -path "C:\Temp$($dc)-159969.crt"
    Invoke-Command -Session $sessionDestinationServer -ScriptBlock {Remove-Item -path "C:\Temp$($args[0])-159969.crt"} -argumentlist $dc


Remove-PSSession -Session $sessionDestinationServer