Migrate ADCS from Windows core to another core


Not often documented as the “standard GUI” migration that consists of a backup and a restore, migrating from a core server to a newer core server (I’m a fan) is also pretty easy… But you’ll need the command line!

Here we will explain to migrate from Windows core 2016 to 2019.

Let’s get started!

My lab infrastructure is not as complex as it “should” be. Best practices use an offline root CA and your windows server will be the issuing server.
Mine is the root CA and the issuing.

As spoken, I’m a big fan of core versions of Windows, most of my servers are set up that way (DCs, Exchange, SQL, WSUS, etc…) as all environement, all the overhead you can spare will have a significant impact on performances and on hardware investment (especially memory in my lab!)

Step 1: backup the current ADCS server:

All my ADCS files are located on a second partition D, For the backup, I created an extra subfolder.

Launch the command : certutil -backup “D:\Servers\Certification Authority\Backup” KeepLog

Keeplog parameter is optional, but it’s good to keep all logs for tracability.

Important: Your backup password should be a strong as possible so nobody will be able to figure it out!

If backup is succesful, you get such:


Step 2: backup the registry of current server:

Launch the command : reg export “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc” “D:\Servers\Certification Authority\Backup\ADCSBackup.reg


Step 4: backup your template list:

This will export all the templates that habe published on the CA, removing the role will not remove the templates from AD but you’ll need this list to bring all the necessary back.

Launch certutil -catemplates > D:\Servers\Certification Authority\Backup\ADCSTemplatesBackup.txt”


Step 5: backup your CAPolicy.inf file:

In most migration tutorials, it is mentionned to copy you C:\Windows\CAPolicy.inf file.
I didn’t had any to copy so I’ll skip this step

Step 5: Uninstall ADCS role from server:

Launch Powershell, it is easier that way:

If you had Web Enrolment role, this has to be uninstalled prior uninstalling ADCS role.

Launch this command : Uninstall-WindowsFeature ADCS-Web-Enrollment (For me Uninstall-AdcsWebEnrollment didn’t work)

Then uninstall ADCS with this command: Uninstall-WindowsFeature ADCS-Cert-Authority

At this point, copy your whole ADCS folder (including backup and registry key of course) to a safe place.


Step 6: Redeploy your new server:

In my case the server will have the exact same name (recommended if you don’t want to edit the registry backup file)


Step 7: Install ADCS role again (with Powershell)

Start Add-WindowsFeature ADCS-Cert-Authority 


Step 8: Restore ADCS:

First, restore CA certificate:

Launch Install-AdcsCertificationAuthority -CAType EnterpriseRootCa -CertFile “D:\Servers\Certification Authority\Backup\YourCACertificate.p12” -CertFilePassword (Read-Host “Enter password” -AsSecureString)

If this step is successful ErrorID 0 is your return code.

Right after, you need to restore the database and the logs but for this step, you need to stop the ADCS service first with net stop certsvc.

Then launch certutil -f -restore “D:\Servers\Certification Authority\Backup”

Then to finish the restore, reimport the registry keys with reg import “ADCSBackup.reg”

Don’t forget to copy your CAPolicy.inf file back to your C:\Windows folder if you had one.


Step 9: Reinstall the web enrollment feature if you required:

Launch Install-WindowsFeature ADCS-Web-Enrollment

And if you need/want to remotely administrate the IIS server for your ADCS : Install-WindowsFeature Web-Mgmt-Service

Do not forget to put the Web Management service in automatic startup: sc.exe config wmsvc start=auto and start it with net start wmsvc

For some reason, the certsrv folder was not created in IIS, so in order to get web enrolment working, I had to launch certutil -vroot and to recover file C:\Windows\System32\CertSrv\certdat.inc from my previous server, what a nightmare!

Just in case, this is the content of the file, you can recreate it manually I guess :

<%’ CODEPAGE=65001 ‘UTF-8%>
<%’ certdat.inc – (CERT)srv web – global (DAT)a
‘ Copyright (C) Microsoft Corporation, 1998 – 1999 %>
‘ default values for the certificate request

‘ global state
sServerType=”Enterprise” ‘vs StandAlone


Edit: after some ressearch, there was a Microsoft KB to solve migration issues…

Thanks for reading!