Since Microsoft discontinued root certificate updates via WSUS in January 2013 (KB931125), administrators face certificate validation issues on fresh Windows Server installations. The default certificate store in Windows Server 2012 contains only Microsoft's own CAs, causing HTTPS communication failures with most public endpoints.
For servers behind SSL termination points (like load balancers), we can bypass the 16KB SChannel limitation by manually installing certificates:
# PowerShell: Install certificate from file
$Cert = Get-PfxCertificate -FilePath "C:\certs\rootCA.cer"
Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath $Cert
For enterprise environments, consider these approaches:
Option 1: Microsoft's Certificate Update Tool
# Download from Microsoft Update Catalog
wget https://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB931125
Option 2: Mozilla's CA Bundle
# Convert Mozilla's PEM bundle to Windows format
openssl x509 -inform PEM -in cacert.pem -outform DER -out mozilla.cer
certutil -addstore -f "Root" mozilla.cer
Implement a scheduled task to keep certificates updated:
# PowerShell maintenance script
$UpdateURL = "https://curl.se/ca/cacert.pem"
$LocalPath = "$env:TEMP\cacert.pem"
Invoke-WebRequest -Uri $UpdateURL -OutFile $LocalPath
# Conversion and import logic here
After installation, verify with:
# Check installed root certificates
Get-ChildItem -Path Cert:\LocalMachine\Root |
Where-Object { $_.Subject -match "CA" } |
Select-Object Subject, Thumbprint
For specific website testing:
# Test HTTPS connection
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
try {
$Request = [System.Net.WebRequest]::Create("https://target.site")
$Request.GetResponse()
$Request.ServicePoint.Certificate
} finally {
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
}
Since Microsoft stopped pushing root certificate updates via WSUS in January 2013, many administrators face certificate validation issues - especially on fresh Windows Server 2012 installations. The default certificate store contains only Microsoft's own CAs, causing HTTPS connections to fail when accessing services secured by other certificate authorities.
Here are three reliable approaches to populate your server's certificate store:
Method 1: Using certmgr.msc
# PowerShell command to launch Certificate Manager Start-Process certmgr.msc
Navigate to "Trusted Root Certification Authorities" > "Certificates" and import needed certificates.
Method 2: PowerShell Automation
# Example: Importing DigiCert root certificate $certUrl = "https://cacerts.digicert.com/DigiCertGlobalRootCA.crt" $certPath = "$env:TEMP\DigiCertGlobalRootCA.crt" Invoke-WebRequest -Uri $certUrl -OutFile $certPath Import-Certificate -FilePath $certPath -CertStoreLocation Cert:\LocalMachine\Root
Method 3: Certificate Bundle from Mozilla
The Mozilla CA Certificate Store provides a comprehensive collection:
# Download and extract Mozilla's CA bundle $mozUrl = "https://curl.se/ca/cacert.pem" $output = "$env:TEMP\cacert.pem" Invoke-WebRequest -Uri $mozUrl -OutFile $output
For ongoing maintenance, consider these strategies:
- Create a scheduled task to periodically check for updates from major CAs
- Implement a Group Policy for enterprise environments
- Use configuration management tools like Ansible or Puppet
After installing certificates, verify with:
# Test SSL connectivity Test-NetConnection -ComputerName example.com -Port 443 # Check certificate chain openssl s_client -connect example.com:443 -showcerts
For large-scale deployments:
# Sample DSC configuration for certificate deployment Configuration DeployRootCerts { Import-DscResource -ModuleName PSDesiredStateConfiguration Node "WebServer*" { Script ImportRootCert { GetScript = { @{ Result = (Get-ChildItem Cert:\LocalMachine\Root | Measure-Object).Count } } SetScript = { $certUrl = "https://example.com/root.crt" $certPath = "$env:TEMP\root.crt" Invoke-WebRequest -Uri $certUrl -OutFile $certPath Import-Certificate -FilePath $certPath -CertStoreLocation Cert:\LocalMachine\Root } TestScript = { $cert = Get-ChildItem Cert:\LocalMachine\Root | Where-Object { $_.Thumbprint -eq "ABC123..." } return ($null -ne $cert) } } } }