# Certificate Auto Enrollment Prerequisites: You need an AD DC and a CA Domain Member (Windows Server 2025) ## On the AD DC ### Create a user for the CEP/CES service *(See https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/configure-certificate-enrollment-web-service#create-a-domain-user-account-to-act-as-the-service-account)* ``` $addc = Get-ADDomainController $realm = $addc.domain.ToUpper() $dnsdomain = $addc.domain $domain = $realm.split('\.')[0] $hostname = $addc.hostname $ces_username = "cepcessvc" $ces_username_lower = $ces_username.toLower() $ces_upn = "$ces_username_lower@$dnsdomain" $ces_domuser = "$domain\$ces_username" $ces_secpasswd = ConvertTo-SecureString -String "P@sSwOrd1" -AsPlainText -Force New-ADUser -Name $ces_username -GivenName $ces_username -Surname Service -DisplayName "CES Service" -UserPrincipalName $ces_upn -AccountPassword $ces_secpasswd -ChangePasswordAtLogon:$false -PasswordNeverExpires $true -Enabled $true ``` Set the SPN for the host running the CA: *(See https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/configure-certificate-enrollment-web-service#set-a-service-principal-name-for-the-service-account)* ``` $ca_hostname = "<REPLACE ME>" $ca_fqdn = "$ca_hostname.$dnsdomain" setspn -s http/$ca_hostname $ces_username setspn -s http/$ca_fqdn $ces_username ``` ### Configure the Certificate Enrollment Web Service user account for constrained delegation (AD DC) *(See https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/configure-certificate-enrollment-web-service#configure-the-certificate-enrollment-web-service-user-account-for-constrained-delegation)* ``` Get-ADUser -Identity $ces_username | Set-ADAccountControl -TrustedToAuthForDelegation $True Set-ADUser -Identity $ces_username -Add @{"msDS-AllowedToDelegateTo"=@("HOST/$ca_fqdn", "rpcss/$ca_fqdn")} ``` ## On the CA Server (Domain Member) ### Install Certificate Service Windows Features ``` Install-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature Add-WindowsFeature -Name @('ADCS-Enroll-Web-Pol','ADCS-Enroll-Web-Svc','ADCS-Web-Enrollment') -IncludeManagementTools ``` ### Add CES domain user to the local IIS_IUSRS group *(See https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/configure-certificate-enrollment-web-service#add-the-service-account-to-the-local-iis_iusers-group)* ``` $addom = Get-ADDomain -Current LocalComputer $realm = $addom.forest.ToUpper() $dnsdomain = $addom.dnsroot $domain = $addom.NetBIOSName $ces_username = "cepcessvc" $ces_domuser = "$domain\$ces_username" $ces_secpasswd = ConvertTo-SecureString -String "P@sSwOrd1" -AsPlainText -Force net localgroup IIS_IUSRS $ces_username /Add net localgroup IIS_IUSRS ``` ### Setup the Certificate Authority ``` $admin_creds = Get-Credential $domain\Administrator $params = @{ CAType = "EnterpriseRootCA" CACommonName = "$domain-ROOT-CA" CryptoProviderName = "RSA#Microsoft Software Key Storage Provider" KeyLength = 4096 HashAlgorithmName = "SHA512" OverwriteExistingCAinDS = $true OverwriteExistingKey = $true Credential = $admin_creds Force = $true } Add-WindowsFeature -Name @('ADCS-Cert-Authority') -IncludeManagementTools Install-AdcsCertificationAuthority @params ``` ### The CES service account needs have read permission on the CA These are manual steps: 1. Open the "Certification Authority" Console 2. Right Click on the CA -> Properties 3. On the Security tab click on "Add .." 4. Add the CEP/CES service account (cepcessvc). 5. For the CES account ensure that the "Allow" check box is selected for "Read". Clear the "Allow" check box for "Request Certificates" ## Request a Server Certificate for the Webserver from CA Follow the instructions at: https://social.technet.microsoft.com/wiki/contents/articles/12485.configure-ssltls-on-a-web-site-in-the-domain-with-an-enterprise-ca.aspx ## Restart IIS service ``` iisreset /restart ``` ### Configure the Certificate Enrollment Policy Web Service #### Get the SSL Certificate Thumbprint of the Web Server *(See https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/configure-certificate-enrollment-web-service#select-a-server-certificate)* ``` Import-Module WebAdministration $certs = Get-ChildItem IIS:SSLBindings | Foreach-Object { [PSCustomObject]@{ Site=$_.sites.value HostName=$_.Host Port=$_.Port Thumb=$_.thumbprint } } ``` If there are more than 2 certificates, use the Thumb linked with Port 443 in $certs. Use it as "SSLCertThumbprint" ``` $params = @{ AuthenticationType = "Kerberos" SSLCertThumbprint = $certs.thumb Credential = $admin_creds } Install-AdcsEnrollmentPolicyWebService @params -Force ``` ### Configure the Certificate Enrollment Web service This is using the CEP/CEP service account we created: ``` $caconfig_tmp = certutil | findstr "Config" $caconfig = $caconfig_tmp.split('"')[1] $params = @{ CAConfig = $caconfig AuthenticationType = "Kerberos" SSLCertThumbprint = $certs.thumb ServiceAccountName = $ces_domuser ServiceAccountPassword = $ces_secpasswd Credential = $admin_creds } Install-AdcsEnrollmentWebService @params -Force ``` ### Configure the Certification Authority Web Enrollment ``` Install-AdcsWebEnrollment -Credential $admin_creds -Force ``` ## On the Active Directory domain controller ### Set GPO for Auto Enrollment If you run: ``` Get-CertificateAutoEnrollmentPolicy -Scope Applied -context Machine ``` by default you should see: ``` PolicyState : NotConfigured EnableMyStoreManagement : False EnableTemplateCheck : False ExpirationPercentage : 0 StoreName : EnableBalloonNotifications : False ``` ### Set AutoEnrollment ``` Set-GPRegistryValue -Name "Default Domain Policy" -Key "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" -ValueName "AEPolicy" -Value 7 -Type "Dword" Set-GPRegistryValue -Name "Default Domain Policy" -Key "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" -ValueName "OfflineExpirationPercent" -Value 10 -Type "Dword" Set-GPRegistryValue -Name "Default Domain Policy" -Key "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" -ValueName "OfflineExpirationStoreNames" -Value "MY" -Type "String" gpupdate /force ``` AutoEnrollment should be successfully set up. You can verify it using: ``` Get-CertificateAutoEnrollmentPolicy -Scope Applied -context Machine ``` It should output: ``` PolicyState : Enabled EnableMyStoreManagement : True EnableTemplateCheck : True ExpirationPercentage : 10 StoreName : {MY} EnableBalloonNotifications : False ``` and ``` Get-GPRegistryValue -Name "Default Domain Policy" -Key "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" ``` ### Create Test Computer Certificate Template Needs to be done manually, see https://dmulder.github.io/group-policy-book/certautoenroll.html#certificate-templates