Enable Certificate Enrollment Policy and Request a Cert using PowerShell

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.


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.

Prerequisite

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
$RootDSE=[System.DirectoryServices.DirectoryEntry]::new("LDAP://RootDSE")
$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
$ConfigContext="CN=$Server,"+$ConfigContext
$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
$Server=$Server+$RootDSE.configurationNamingContext.Value.Replace("CN=Configuration","").Replace(",DC=",".")
$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
$Cred=[System.Management.Automation.PSCredential]::new($User,$SecPass)
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.Certificate.FriendlyName=$DNS

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