The Problem
A Windows 8 machine has a certificate that is used by an application. Auto enrollment will renew the certificate when it is near its expiration period. However, applications that are bound to the old certificate do not "know" about the new certificate. These applications may fail if they continue to use the old certificate.
The Solution
A custom powershell script can be registered to execute at the time the renewal takes place. This custom script can re-configure the application to use the new certificate.
How Can I Do It? [Short Version]
To get you started with a very basic script to see how the feature works, do the following:
Create the following powershell script in c:\notification_scripts called ReplaceCertificate.ps1 which will run when a certificate gets renewed:
$FileName = "Replace_" + $OldCertHash + "_" + $NewCertHash
Set-Content -Path c:\notification_scripts\$FileName -Value "Replace $OldCertHash with $NewCertHash"
This script will create a file in the c:\notification_scripts folder whose name is the hash of the old certificate followed by an "_" followed by the hash of the new certificate.
Depending on the execution policy in your powershell environment this script may not run. For now, run the following from an elevated command prompt:
Later, you will see how to avoid this [see Fine Tuning section]
Run the following cmdlet to setup notifications for a user certificate:
Using certmgr, enroll for a certificate for the user. And then renew it.
In the c:\notification_scripts folder you should observe a file called Replace_<OldHash>_<NewHash>This indicates that the script from step 1 executed.
What Other Notifications Exist?
The New-CertificateNotificationTask cmdlet allows you to setup a notification for certificates that get renewed. You can also use this cmdlet to setup a notification for certificates that are expiring or are expired. Use the "-Type" parameter in the cmdlet to change between Replace [which covers renew] or Expire [which covers expiring or expired].
There are also other notifications such as:
How It Works?
Two new event logs were created:
The enrollment code was modified to write events into the Operation channel in these event logs. Some events are:
The task scheduler [type: taskschd.msc from command line to see it] can monitor the event log for these events and execute powershell on a particular script. The New-CertificateNotificationTask cmdlet creates a task in task scheduler. You can fine tune the task by editing it using the task scheduler interface. Alternatively, if you have other monitoring software you can invoke it using task scheduler as well based off these events. See the diagram below for a visual summary:
Fine Tuning Tasks
In some environments powershell scripts cannot be executed. For instance, the default execution policy is set to Restricted which means powershell scripts cannot run. You may want to run these notification scripts, but not change the environment execution policy. You can do this with a little fine tuning on the task scheduler. You will need to have a task already configured using the New-CertificateNotificationTask cmdlet :
Now, you can have your machine powershell environment still be Restricted, but this task will run in Unrestricted.
You can also fine tune the task to run something other than powershell.
What Is A Real World Example?
IIS SSL Bindings
You can run your default website using an ssl server certificate. IIS will maintain the binding between the website and the ssl server certificate. You can see your bindings in powershell:
If any certificate is renewed, IIS will not be notified to update its bindings. The SSL stack will do its best to find the latest renewed certificate based on what is configured in the IIS binding. Essentially, the SSL stack will "walk the renewal chain".
An alternative, is to configure a script that runs when a certificate is renewed. This script will see if there are any IIS bindings using the old certificate and update the bindings appropriately. Here is the script:
param([string]$OldCertHash, [string]$NewCertHash)
import-module webadministration
$bindings = dir IIS:\SslBindings | where {$_.Thumbprint -eq $oldCertHash} # String comparison is case-insensitive
$newCert = dir “cert:\LocalMachine\My\$newCertHash”
$bindings | ForEach-Object { del $_.PSPath; $newCert | new-item $_.PSPath;}
Save this to a file: c:\scripts\replace.ps1Then run this cmdlet:
Credit: Thanks to Alex Radutskiy and Haitao Li