How to Set Up Certificate Services (AD CS) on Windows Server 2019
Active Directory Certificate Services (AD CS) provides a Public Key Infrastructure (PKI) for issuing and managing digital certificates within an organization. These certificates enable TLS/SSL for websites, smart card authentication, email encryption (S/MIME), code signing, encrypted file systems (EFS), and IPsec. Windows Server 2019 AD CS supports a two-tier hierarchy with an offline root CA and an online issuing CA, which is the recommended architecture for enterprise deployments.
Planning a Two-Tier PKI Hierarchy
A two-tier PKI hierarchy consists of a Root CA (the trust anchor, kept offline and highly secured) and one or more Subordinate/Issuing CAs (online, issue certificates to users and computers). The Root CA’s certificate is distributed to all clients via Group Policy and is trusted implicitly. The Root CA is used only to sign the Subordinate CA certificate and Certificate Revocation Lists (CRLs). After the initial setup, the Root CA server is powered off and stored securely.
Installing the Root CA (Standalone, Offline)
Install the Root CA on an isolated server that is not domain-joined (standalone CA). This server will not have permanent network access:
# Install AD CS on the standalone root CA server (not domain joined)
Install-WindowsFeature -Name AD-Certificate, ADCS-Cert-Authority -IncludeManagementTools
# Install and configure the standalone root CA
Install-AdcsCertificationAuthority `
-CAType StandaloneRootCA `
-CACommonName "Example Corp Root CA" `
-CADistinguishedNameSuffix "DC=example,DC=com" `
-KeyLength 4096 `
-HashAlgorithmName SHA256 `
-ValidityPeriod Years `
-ValidityPeriodUnits 20 `
-CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
-Force
# Verify installation
Get-Service certsvc
certutil -CAInfo
Configuring Root CA CRL Distribution Points
Configure CRL Distribution Points (CDPs) and Authority Information Access (AIA) extensions. These tell certificate consumers where to check if a certificate has been revoked:
# Configure CDP locations (HTTP path where CRL files will be published)
# Remove default LDAP CDP (root CA is offline, LDAP won't work)
$CdpOld = Get-CACrlDistributionPoint
foreach ($cdp in $CdpOld) {
Remove-CACrlDistributionPoint -Uri $cdp.Uri -Force
}
# Add HTTP CDP
Add-CACrlDistributionPoint `
-Uri "http://pki.corp.example.com/pki/.crl" `
-AddToCertificateCdp `
-AddToFreshestCrl
# Add file path for CRL publication
Add-CACrlDistributionPoint `
-Uri "C:WindowsSystem32CertSrvCertEnroll.crl" `
-PublishToServer
# Configure AIA extensions
$AiaOld = Get-CAAuthorityInformationAccess
foreach ($aia in $AiaOld) {
Remove-CAAuthorityInformationAccess -Uri $aia.Uri -Force
}
Add-CAAuthorityInformationAccess `
-Uri "http://pki.corp.example.com/pki/_.crt" `
-AddToCertificateAia
# Set root CA validity periods (CRL valid for 6 months, delta CRL 0 = no delta)
certutil -setreg CACRLPeriodUnits 6
certutil -setreg CACRLPeriod "Months"
certutil -setreg CACRLDeltaPeriodUnits 0
# Restart Certificate Services to apply changes
Restart-Service certsvc
# Publish the Root CA CRL
certutil -crl
Configuring the Subordinate (Issuing) CA
Install the Subordinate CA on a domain-joined server. This CA will be permanently online and issue certificates to users and computers:
# On the Subordinate CA server (domain-joined)
Install-WindowsFeature -Name AD-Certificate, ADCS-Cert-Authority, ADCS-Web-Enrollment, ADCS-Online-Cert -IncludeManagementTools
# Install as Enterprise Subordinate CA (requires domain join and enterprise admin rights)
Install-AdcsCertificationAuthority `
-CAType EnterpriseSubordinateCA `
-CACommonName "Example Corp Issuing CA 01" `
-CADistinguishedNameSuffix "DC=corp,DC=example,DC=com" `
-KeyLength 2048 `
-HashAlgorithmName SHA256 `
-CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
-OutputCertRequestFile "C:CARequestSubCA-Request.req" `
-Force
Transfer the request file (SubCA-Request.req) to the Root CA and sign it:
# On the Root CA: Submit and sign the subordinate CA request
certreq -submit -attrib "CertificateTemplate:SubCA" C:SubCA-Request.req
# Check pending requests
certutil -view queue
# Issue the subordinate CA certificate (use the Request ID from the submit output)
certutil -resubmit 2 # Replace 2 with actual Request ID
# Retrieve the signed certificate
certutil -retrieve 2 C:SubCA-Signed.cer
# Also export the Root CA certificate
certutil -ca.cert C:RootCA.cer
Transfer SubCA-Signed.cer and RootCA.cer back to the Subordinate CA and complete the installation:
# On the Subordinate CA: Install the signed certificate
certutil -installcert "C:SubCA-Signed.cer"
# Start the Certificate Services
Start-Service certsvc
# Publish the Root CA certificate and CRL to Active Directory
certutil -dspublish -f "C:RootCA.cer" RootCA
certutil -dspublish -f "C:RootCRL.crl" RootCA
Creating Certificate Templates
Certificate templates define the purpose, validity period, key usage, and enrollment settings for certificates issued by an Enterprise CA. Templates must be duplicated from built-in templates before modification:
# View available certificate templates
certutil -template | findstr "Template Name"
# Create a custom Web Server template via PowerShell
# Duplicate the built-in WebServer template using ADSI
$domainDN = ([adsi]"LDAP://RootDSE").defaultNamingContext
$templateContainer = [adsi]"LDAP://CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$domainDN"
# More commonly, use the Certificate Templates console (certtmpl.msc)
# Right-click "Web Server" > Duplicate Template
# Set version, validity period, and enrollment permissions
# After creating the template in the console, publish it to the CA:
Add-CATemplate -Name "WebServer-2Year" -Force
# List templates published on the CA
Get-CATemplate
Enrolling Certificates
Computers and users can auto-enroll for certificates based on Group Policy settings. Configure auto-enrollment for computer and user certificates:
# Configure certificate auto-enrollment via Group Policy
# Computer Configuration > Windows Settings > Security Settings > Public Key Policies
# "Certificate Services Client - Auto-Enrollment Settings"
# Set: Enabled, check "Renew expired certificates, update pending..."
# Or using PowerShell to request a certificate manually
$cert = Get-Certificate `
-Template "WebServer-2Year" `
-SubjectName "CN=webserver01.corp.example.com" `
-DnsName "webserver01.corp.example.com","www.corp.example.com" `
-CertStoreLocation "Cert:LocalMachineMy"
$cert.Certificate.Thumbprint
# View certificates in the machine store
Get-ChildItem Cert:LocalMachineMy | Select-Object Subject, Thumbprint, NotAfter
# Export a certificate with private key
$password = ConvertTo-SecureString -String "ExportP@ssword!" -AsPlainText -Force
Export-PfxCertificate `
-Cert "Cert:LocalMachineMy" `
-FilePath "C:Certswebserver01.pfx" `
-Password $password
Configuring Online Responder (OCSP)
The Online Certificate Status Protocol (OCSP) provides real-time certificate revocation status, which is faster and more bandwidth-efficient than downloading full CRL files:
# Install the Online Responder role service
Install-WindowsFeature -Name ADCS-Online-Cert -IncludeManagementTools
# Configure the Online Responder
Install-AdcsOnlineResponder -Force
# Add the OCSP entry to CDP and AIA on the issuing CA
Add-CAAuthorityInformationAccess `
-Uri "http://pki.corp.example.com/ocsp" `
-AddToCertificateOcsp
# Verify OCSP is working
certutil -URL "http://pki.corp.example.com/ocsp"
Monitoring the PKI
# Verify CA health
certutil -ping
certutil -cainfo
certutil -CRL
# Check for expiring certificates
Get-ChildItem Cert:LocalMachineMy | `
Where-Object {$_.NotAfter -lt (Get-Date).AddDays(30)} | `
Select-Object Subject, NotAfter, Thumbprint
# View issued certificates
certutil -view -restrict "Disposition=20" -out "CommonName,NotAfter,RevocationDate"
# Check CA event log
Get-WinEvent -LogName "Application" -Source "Microsoft-Windows-CertificationAuthority" -MaxEvents 50
A properly deployed PKI using AD CS provides the cryptographic foundation for many security services in your organization. Protect the Root CA private key as your organization’s highest-value cryptographic asset, maintain current CRLs, monitor certificate expiration, and document your PKI architecture for recovery scenarios.