Popular Posts

Tuesday, August 1, 2023

Adding domain CA trusted certificates to workgroup servers for SCCM connection

Background

In certain enterprise scenarios, it is possible to have isolated servers, a.k.a workgroup servers, that are not joined to the main Active Directory domain due reasons such as security requirements (ex: internet facing servers).

Generally, Windows Server Clients should be part of the same domain as SCCM servers to be able to retrieve packages and security updates from SCCM Distribution Points (DPs). That is because SCCM needs to trust the client before it could push/pull packages and updates.

However, there is a workround to this problem that involves installing domain certificates in workgroup servers that are not part of the domain. To add on, this could be automated using PowerShell.


Steps

1. From a domain connected client server, copy the following types of certs over to the target workgroup client server:

    a. Root

    b. CertificateAuthority

    c. TrustedPublisher

2.  Run the following PowerShell script on the workgroup server with admin privileges. It uses .NET classes x509certificate2 and x509certificate. Make sure .NET 2.0 or above is installed on the target server.

#define script log file
$logfile = 'C:\Windows\Temp\Set-Certs.log'

#function to write into the log file
function writetolog([string] $txt) {
$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")

Add-content $logfile -value $Stamp':'$txt

}

#define list of certs
$certs = @(@("<corp root>.cer","Root"),@("<CA authority 1>.cer","CertificateAuthority"),@("<CA authority 2, if any>.cer","CertificateAuthority"),@("<Trusted publisher>.cer","TrustedPublisher"))

#define path to folder containing certs
$certFolder = "C:\Users\admin\Desktop\WorkgroupCerts"

#go through each cert
foreach ($certName in $certs) {
#start of the try/catch

try {

$cert = $certName[0]
Write-Host $cert

$storename = $certName[1]
write-host $storename

$certPath = "$certFolder\$cert"
Write-Host $certPath

#create a new certificate object using the x509certificate2 .NET class
$newCert = new-object system.security.cryptography.x509certificates.x509certificate2

#import the pfx file and use the x509KeyStorageFlag 'PersistKeySet' to set the certificate as persistent in our certificate store
$newCert.Import($certPath)

#get the thumbprint of the certificate going to be installed
$newCertThumbprint = $newCert.Thumbprint

#create a new object using the x509Store .NET class to manage the certificate catalog
$store = New-Object System.Security.Cryptography.X509Certificates.x509Store("\\localhost\$storename", "LocalMachine")

#open the certificate store with the 'ReadWrite' flag to be able to modify it
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags].ReadWrite)

#check if there is a certificate which match the new one's thumbprint present in the store
$certPresent = Get-ChildItem -Path CERT:\\LocalMachine -Recurse | Where-object {$_.Thumbprint -eq $newCertThumbprint}

#verify if the certificate is present. if not, install it
if(!$certPresent) {

Write-Host "Installing certificate on machine $machine"

$store.add($newCert)

}else{

Write-Host "Certificate already present on machine $machine"

}

#close the store
$store.Close()

}

catch {
throw
#update log
Write-Host "The installation has Failed on the machine $machine"

}


}