Right now, I'm doing the following to request a cert from a CEP server:

  • Open gpedit.msc
  • Under Computer Configuration > Windows Settings > Security Settings > Public Key Policies, double click "Certificate Services Client - Certificate Enrollment Policy"
  • Enable
  • Enter the CEP URI
  • Switch to Username/Password authentication
  • Validate (Provide Creds)
  • Open MMC, and import Certificates snap in
  • Go to Certificates > Personal
  • Right-Click > Request New Certificate
  • Enter "more information" (CN, DNS Name, etc.)
  • Provide Creds

After this I have a cert from the CEP; however, this is a painful process to do manually. Is there any way to automate this in Server 2008 (and 2012)? All information that I can find about this tells how to install the CEP services to make a server an enrollment policy server (nothing about actually requesting a new cert, or enabling it on the client side). Is it possible to automate this?

It looks like this process adds a lot of data under HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography. Can I manually add this (and spoof a GUID/ServiceID)?

  • 1
    Not to discourage your enthusiasm, as I also like to POWERSHELL ALL THE THINGS!!!!!! but the group policy cmdlets are still absolutely horrid, and the PKI cmdlets are much improved in v4 over v3, so... :( However, I do find this 3rd party PKI module for PowerShell module useful, and it may take some of the manual pain out what you're trying to do. Dec 16 '14 at 1:29

I presume your certificate requests are made using a template. If that's the case then use the Public Key Policies/Certificate Services Client - Auto-Enrollment Settings GPO to enforce auto enrollment. You'll also want to ensure the template ACL has Enroll and AutoEnroll marked for either domain computers or domain users (or whatever acl object, depending on the intended audience) There's a user config and computer config policy to leverage depending on whether or not it's a machine cert or user cert you're trying to push. Enrollment begins as soon as when the policy is pushed (usually about 15 minutes) after the GPO is linked and enforced.

  • 2
    Well, duh. I got so hung up on the PowerShell part, I totally blanked on the fact that I've set up many, many GPOs to automate certificate enrollment for many years. D'oh! Good catch. Dec 17 '14 at 22:40
  • This is definitely an option (probably the best option), but I would prefer to set a local group policy setting.. is this possible?
    – EGr
    Dec 18 '14 at 20:35
  • 2
    @EGr why in the world would you want to do that?
    – MDMoore313
    Dec 18 '14 at 20:50
  • @HopelessN00b I did the same thing, however it would be cool to have a powershell way to do it for troubleshooting purposes at the very least, so it's still a pretty good question.
    – MDMoore313
    Dec 18 '14 at 20:51

This is the process I have used on Windows 2012 R2 and higher. All PowerShell code was run from an elevated PowerShell prompt. Complete automation is left as an exercise for the user.


Ensure that you have a Template on your Certificate Server that has the "Supply in the request" radio button selected in the Subject tab. Because this is not an AD machine, the certificate server cannot adequately query Active Directory for the information.

Export the Root

Export the Trusted Root Certification Authority Certificate on your Certificate Server and then copy that certificate file to your Target Server

certutil --% -ca.cert <name of certificate file>

Trust the Root

Import that certificate to the Trusted Root Certification Authority on your Target Server

$PathToCertificate=<name of certificate file>
$RootCertificate=Get-PfxCertificate -FilePath $PathToCertificate
$AlreadyExists=Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object { $_.Thumbprint -eq $RootCertificate.Thumbprint }
if ($AlreadyExists -eq $null) { Import-Certificate -CertStoreLocation "Cert:\LocalMachine\Root" -FilePath $PathToCertificate }
else { Write-Warning "Root certificate already installed" }

Active Directory Policy Provider

Determine the URL for the Active Directory Policy Provider

# Get AD Configuration Context
$ConfigContext="CN=Enrollment Services,CN=Public Key Services,CN=Services,"+$RootDSE.configurationNamingContext
# Get name of Enterprise Root Certificate Autority server
$Server=Get-ADObject -SearchBase $ConfigContext -Filter "*"
if ($Server.Count -eq 1) { throw "No Enterprise Root Certificate Autority server exists" }
else { $Server=$Server[1].Name }
# Get Enrollment URL
$EnrollmentURL=(Get-ADObject -SearchBase $ConfigContext -Filter "*" -Properties "msPKI-Enrollment-Servers" | Select-Object -ExpandProperty "msPKI-Enrollment-Servers").Split("`n") | Where-Object { $_ -like "http*" }
if ($EnrollmentURL -eq $null) { $EnrollmentURL="" }
# Get AD Enrollment Policy URL
$WMI=Get-WmiObject -ComputerName $Server -Namespace "root\WebAdministration" -Class Application | Where-Object { $_.Path -eq "/ADPolicyProvider_CEP_UsernamePassword" }
if ($WMI -ne $null) { $PolicyURL="https://"+$Server+$WMI.Path+"/service.svc/CEP" }
else { $PolicyURL="" }
Write-Output "Enrollment URL = $EnrollmentURL"
Write-Output "Policy URL = $PolicyURL"

Enrollment Policy

Add the Enrollment Policy to the Target Server (This only works on Windows 2012 and higher. For GUI instructions, see below). Make sure that the Policy is added after you create the non-domain template, otherwise it will not appear as it the policy does not get refreshed.

$User="<your domain name>\<your domain user name>"
$Pass="<Your domain password>"
$SecPass=ConvertTo-SecureString -String $Pass -AsPlainText -Force
Add-CertificateEnrollmentPolicyServer -Url $PolicyURL -context Machine -NoClobber -AutoEnrollmentEnabled -Credential $Cred

Get the certificate

You should now be able to enroll for a certificate using the desired template

$DNS="<FQDN of your server>"
$URL=Get-CertificateEnrollmentPolicyServer -Scope All -Context Machine | Select-Object -ExpandProperty Url | Select-Object -ExpandProperty AbsoluteUri
$Enrollment=Get-Certificate -Url $URL -Template "<Template name (not display name)>" -SubjectName "CN=$DNS" -DnsName $DNS -Credential $Cred -CertStoreLocation cert:\LocalMachine\My

Enrollment Policy Pre-Windows 2012 R2

  1. Open the certificates MMC
  2. Drill down to the Personal Certificate Store
  3. Right click "Certificates" and selet All Tasks/Advanced Operations/Manage
  4. Enrollment Policies from the context menu
  5. Click the "Add" button
  6. Paste the URL for the enrollment policy
  7. Select Username/password as the Authentication type
  8. Click the "Validate Server" button and enter your domain credentials, including the domain
  9. Assuming you have been able to successfully validate, click the "Add" button
  10. Select the enrollment policy and click the "Properties" button
  11. Make sure that the "Enable for automatic enrollment and renewal" box is checked
  12. I have never checked the "Require strong validation during enrollment" so I don't know what it does

I don't have a complete solution, however, I can advice start points. My PowerShell PKI module has an ability to register enrollment service endpoint starting with Windows 7/Windows Server 2008 R2 (note that Windows Server 2008 do not support enrollment services). Here is an example how to register a policy: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=101

regarding enrollment. This blog post series may give you some insight about how to utilize CertEnroll COM interfaces to perform certificate enrollment in PowerShell. There is nothing about enrollment web services (unfortunately), but the techniques are the same. You will need to start with this interface: IX509CertificateRequestPkcs10V2


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.