Deploy a PKI on Windows Server 2016 (Part 4)

This is the fourth part of a seven-part series explaining and setting up a two-tier PKI with Windows Server 2016 in an enterprise SMB setting.

Part 1 (Informational)
Part 2 (Getting Started & IIS Web Server Configuration)
Part 3 (Standalone Offline Root CA Configuration)
>>> Part 4 (Enterprise CA Configuration) <<<
Part 5 (Distributing Certificates & AutoEnrollment)
Part 6 (Additional Configuration)
Part 7 (Troubleshooting & Clean-up)

To help with the layout and navigation of these longer pages, use the Table of Contents below:

Subordinate “Enterprise” CA Setup (issuingCA)

In this part, we set up and configure the subordinate Enterprise CA server named issuingCA.  This server must be joined to the domain, and must have a reliable network connection.

Pre-install Steps

Before installing and configuring the AD CS role, there’s a few things that need to be done first.

Create CAPolicy.inf

Just like with the RootCA server, we also need to do this on the issuingCA server.  However, the configuration will be a little different, which I will explain below.

You need to again create this file in C:\Windows\CAPolicy.inf BEFORE you install the Certificate Services role.

  1. On the server issuingCA, copy and paste this into notepad, and save it as C:\Windows\CAPolicy.inf
    Signature=”$Windows NT$”

    1. It’s important to configure the RenewalValidityPeriodUnits to a number that is high enough to meet the needs of your environment.  Keep in mind that you will need to turn on the RootCA server every time you need to renew the certificate of this server (issuingCA).
      1. I configured the above parameter to 10 years, which is how long the certificate of this server will last until it must be renewed, unless for some reason it becomes compromised and needs revoked.
      2. Typically, you configure a Root CA to 20 years and tier 2 subordinate CAs 10 years, and so on.
    2. The additional parameters that we configured on the RootCA are not included in the CAPolicy.inf file on this server.
    3. You may exclude the PolicyStatementExtension and InternalPolicy sections.

Publish Root CA certificate to Active Directory

This next step is a good idea because it helps streamline distribution, and it will not negatively impact anything.  You may also choose to publish the Root CA cert via Group Policy.  This command will automatically push domain joined computers and servers to have the Root CA cert installed to their local certificate stores.  Doing this via below command and via Group Policy is fine.

  1. On the server: issuingCA, enter the following in an elevated command prompt:
    certutil.exe –dsPublish –f "C:\BEDROCK-ROOTBedrock Root Certificate Authority.crt" RootCA

Publish Root CA CRL to Active Directory

*Note:*  You can skip this step, and move on to “Add Root CA cert and CRL to local store

Don’t publish the CRL to Active Directory unless you need to.  I’m not doing so in this guide and not configuring the issued certificates to check LDAP for the CRL because it’s not a good idea.  Not all devices will have access to LDAP.  But here is the command to publish the Root CA CRL to AD.

  1. On the server: issuingCA, enter the following in an elevated command prompt:
    certutil.exe -dsPublish -f "C:\BEDROCK-ROOT.crl" RootCA
    1. Where “RootCA” above is the name of your root ca server.
  2. If you do publish the CRL to AD, and you decide you shouldn’t have, you can manually remove it in ADSI Edit shown below:

Add Root CA cert and CRL to local store

Finally, you need to add the Root CA cert and CRL to the local certificate stores.

  1. On the server: issuingCA, enter the following in an elevated command prompt:
    certutil.exe –addstore –f root "C:\BEDROCK-ROOTBedrock Root Certificate Authority.crt"
    certutil.exe –addstore –f root "C:\BEDROCK-ROOT.crl"

Install Certificate Services

On the server: issuingCA, install the Active Directory Certificate Services role.

  1. To install the AD CS role, in PowerShell, enter the following:
    Add-WindowsFeature Adcs-Cert-Authority -IncludeManagementTools
  2. After the role is finished installing, you must configure it.  Enter the following in PowerShell, changing the options as needed to fit your environment:
    Install-AdcsCertificationAuthority -CAType EnterpriseSubordinateCA -CACommonName "Bedrock Enterprise Certificate Authority" -KeyLength 4096 -HashAlgorithm SHA256 -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" -Force
  3. The result should look like below, and you should now have a certificate request .req file in your C:\ drive as highlighted.  The warning message just means we need to request, obtain, and install a certificate from the RootCA:

Install Certificate on issuingCA

Now that the Certificate Services role is installed on issuingCA as pictured above, we need a certificate for the server before we can start the Certificate Services, as showin in the yellow warning message.  This means you need to submit a certificate request to the RootCA, where we’ll then approve the request on the RootCA, get the certificate, and install it on issuingCA.  Then we can finally start the Certificate Service.

Submit Certificate Request to RootCA

To submit a certificate request to the server: RootCA, perform the following steps:

  1. Copy the file:  “C:\issuingCA.bedrock.domain_Bedrock Enterprise Certificate Authority.req” from the server: issuingCA, to the C:\ drive of the server: RootCA
  2. On the server: RootCA, open up the Certification Authority tool from the Tools menu in Server Manager.
  3. Right-click on Bedrock Root Certificate Authority, select All Tasks, and then click Submit new request.
  4. Browse to the “C:\issuingCA.bedrock.domain_Bedrock Enterprise Certificate Authority.req” file and click Open.
  5. In Certification Authority window, select Pending Requests.  If you don’t see the pending certificate request, hit refresh.
  6. Right-click on the request, select All Tasks, then click Issue.
  7. Highlight Issued Certificates, and make note of the Request ID.
  8. In an elevated command prompt on RootCA, enter the following, then click OK when the Certificate Authority List windows pops up:
    certreq -retrieve 2 "C:\issuingCACert.crt"
  9. You should now have a certificate .crt file in the C drive:
  10. Copy the “C:\issuingCACert.crt” file to the C drive of the server: issuingCA.

Install Certificate on issuingCA

Now that we have a certificate to install on the issuingCA server, which should have already been copied from the RootCA after the request was approved and the certificate issued, we need to install the certificate on issuingCA.

  1. Open the Certificate Authority tool from Server Manager.
  2. Right-click the Bedrock Enterprise Certificate Authority, select All Tasks, then click Install CA Certificate.
  3. Browse to the “C:\issuingCACert.crt” file and click Open.  It may take a few seconds to process.
  4. Do NOT start the service yet.  We want to perform some configurations first in the next step.

Configuring the CA

The issuingCA is now ready to go, but before we start the Certificate Authority service, you should set some configuration changes.

  1. Enter the following in an elevated PowerShell window.  You may copy and paste the contents in there to make it easier:
    $crllist = Get-CACrlDistributionPoint; foreach ($crl in $crllist) {Remove-CACrlDistributionPoint $crl.uri -Force};
    Add-CACRLDistributionPoint -Uri C:\Windows\System32\CertSrv\CertEnroll\BEDROCK-ECA%8%9.crl -PublishToServer -PublishDeltaToServer -Force
    Add-CACRLDistributionPoint -Uri file://\\webserv1.bedrock.domain\pki\BEDROCK-ECA%8%9.crl -PublishToServer -PublishDeltaToServer -Force
    Add-CACRLDistributionPoint -Uri http://pki.bedrock.domain/pki/BEDROCK-ECA%8%9.crl -AddToCertificateCDP -AddToFreshestCrl -Force
    Get-CAAuthorityInformationAccess | where {$_.Uri -like '*ldap*' -or $_.Uri -like '*http*' -or $_.Uri -like '*file*'} | Remove-CAAuthorityInformationAccess -Force
    Add-CAAuthorityInformationAccess -AddToCertificateAia http://pki.bedrock.domain/pki/BEDROCK-ECA%3%4.crt -Force
    certutil.exe -setreg CA\CRLPeriodUnits 2
    certutil.exe -setreg CA\CRLPeriod "Weeks"
    certutil.exe -setreg CA\CRLDeltaPeriodUnits 1
    certutil.exe -setreg CA\CRLDeltaPeriod "Days"
    certutil.exe -setreg CA\CRLOverlapPeriodUnits 12
    certutil.exe -setreg CA\CRLOverlapPeriod "Hours"
    certutil.exe -setreg CA\ValidityPeriodUnits 5
    certutil.exe -setreg CA\ValidityPeriod "Years"
    certutil.exe -setreg CA\AuditFilter 127
    restart-service certsvc
  2. The above will make the configuration changes, and then start the Certificate Authority services.  You may have to refresh the Certification Authority tool for it to show as running with a green checkmark.  Things should look similar to below:

Publish New CRLs

Normally at this point, you would publish the new CRLs.  But because we made the configurations first before turning on the CA services for the first time, they were automatically already published to the webserver, if you changed the CDP publication locations appropriately.

If you started the CA service first before you made the configuration changes, publish the new CRL and Delta CRL per below.

  • Enter the following in PowerShell:
    certutil -crl

Copy AIA .CRT file to WebServer

The last step is to copy the AIA (.crt) file to the location that all issued certificates will be looking for it.  You will find the AIA file at  “C:\Windows\System32\CertSrv\CertEnroll\issuingCA.bedrock.domain_Bedrock Enterprise Certificate Authority.crt”

That is not the file name issued certificates will be looking for in the AIA location, so we need to copy the file to WebServ1 and also rename the file.

So on issuingCA, use the following command to copy the file over to the web server and rename the file in the process:

  1. Enter the following command in an elevated Command Prompt:
    copy "C:\Windows\System32\CertSrv\CertEnroll\issuingCA.bedrock.domain_Bedrock Enterprise Certificate Authority.crt" "\\WebServ1.bedrock.domain\pki\BEDROCK-ECABedrock Enterprise Certificate Authority.crt"
  2. If you look in your pki share on the webserver, it should now be there.


On your webserver, whether it’s internal or external, you will need 5 very important files in there, all correctly named and highly-available.  All issued certificates will check for these files, and if not available, the certificate will be invalid until you correct the connectivity or name issues.

If the above web server is not accessible publicly, and you configured your CDP and AIA url’s to a public address, you will need to manually copy the above 5 files from your internal web server to your externally hosted web server.

If you have configured your CRL and Delta CRL publication times to two weeks and 2 days respectively, you’ll find yourself having to copy the Delta CRL file to your externally hosted web server every other day.  So you can either adjust that to be longer, or figure out a way to have it done automatically via scheduled task or script.  Or, simply, configure public HTTP access to this web server.

The CRL timing doesn’t become important until you start revoking certificates.  Depending on what you use your PKI for, you may not need to frequently revoke certs… or you may need to.

Next Steps

The Root CA and Subordinate Enterprise CA are both set up and services configured.  The next step would be to install OCSP, but I’m skipping that for now and moving on to setting up Certificate Templates and AutoEnrollment for distributing certificates to users and devices.  First with configuring key archival.  I’ll also show how to set up a template for SSL certs, and a template for providing the ability to distribute certificates to external users.  I define external users as those who are not on your domain.  They may be a vendor you may need to communicate with using encrypted emails or another party.


  1. Dmitriy Shtyrkov

    Very good instructions. Is there any chance to see part5, part 6, etc.?
    Thank you.

    • Timothy Gruber

      Yes, I am almost finished with Part 5… I have been for a while but I’ve been very busy lately.
      I could only manage to squeeze in a few quick posts here and there, but I do plan on releasing parts 5 and 6 soon.
      Part 5 is actually very long and involved. I hope to have it out this week.

  2. Excellent guide! Can’t wait for the next sections.

    I ended up with an extra cps.html in the pki share when comparing to the final wrap-up section in Part4.

    Also, if it saves someone else a night.. My ‘certutil -crl’ command on the IssuingCA was failing with access denied. The IssuingCA server should be rebooted after installing ADCS so it updates it’s group membership of ‘Cert Publishers’.

Leave a Reply

Your email address will not be published. Required fields are marked *