We’ve recently migrated (side-by-side) to a new Active-Directory (AD) integrated root Certificate Authority (offline) with an intermediate issuing CA. Now while AD should take care of things like distribution of the CA certificates to the clients so they know who to trust, there still remains the issue of the certificates of the clients themselves.
Specifically, certificates issued to the machine account, which, if you have not modified the default template, renew every 365 days. However, you probably don’t want to wait that long 🙂

The method that I’ve used leverages the SCCM 2012 R2 Application deployment model and a custom detection rule using Powershell.
As such, there will be two main components:

  1. A command-line to request (enroll) a new machine certificate
  2. A Powershell script to detect whether a machine already has a machine certificate from the new CA.

As such, Powershell execution needs to be enabled on the clients to make this work.
In my environment I’ve used Group Policy to configure clients to an execution policy of RemoteSigned. I’ve also generated a Code Signing certificate from the new CA using the default template, and this is securely stored for use by the IT team to sign our automation Powershell scripts.

Signing Powershell scripts is very simple. First you’ll need to import the certificate to the machine where you want to execute the signing process (I recommend a secure management server as the certificate will stay there for a while). How secure you want to make the actual certificate is up to you but be aware that you can additionally secure it with a password (very good idea) and also mark it as non-exportable such that once it’s initially imported it cannot be copied out.

Signing Scripts

Import the certificate to the Personal store of the User account.
Then use the following command to sign your scripts:

Set-AuthenticodeSignature c:tempGet-Certificate-Where-Issuer.ps1 @(Get-ChildItem cert:CurrentUserMy -codesign)[0]

If you now open up the script in an editor you will see the certificate information is now added.

Detecting presence of certificates

The script we have in this case is a nice one-liner (thanks Powershell!):

The command uses a standard LDAP path and the example above assumes that your new CA is: CAUK01.contoso.local

Now that our detection-script is ready and signed we can think about our command to enroll a new certificate.

Enrolling certificates

This can be done without Powershell, which is fortuitous if you are having to deploy using GPO, for example. In a worst-case scenario you can just deploy the command indiscriminately insofar that, typically, having multiple machine certificates does no harm so long as they are all valid. In my case I wanted to be precise and target only those that needed it.

The syntax is very simple. “-enroll” should be obvious, and -machine specifies the certificate we want to target. It does look like it’s a mistake but the parameter for the “-machine” switch is indeed “machine”.

Now you could use this as-is and it’s also obviously capable of being used on a manual sneaker-net basis. However, I decided to write up a very basic batch-file to do a little bit more:

@echo off
REM v1.0. Luis Johnstone, 2016. Basic batch file to request a new machine certificate
REM and restart the IP Helper service so that Direct Access will use the new certificate.
certreq -enroll -q -machine machine >> C:WindowsTempCert-Enroll.log
net stop iphlpsvc >> C:WindowsTempCert-Enroll.log
net start iphlpsvc >> C:WindowsTempCert-Enroll.log

The first requirement for anything that I deploy via SCCM is to have some form of logging hence why each line pipes the standard output to a .log file.
We also have a great many Direct Access (DA) enabled clients and DA uses machine certificates to authenticate with DA Entry Points. To make the DA client aware of the new certificate requires only a restart of the IP Helper service.

So now that we have all the scripting bits let’s have a look at how to deploy this.


Since we’re using SCCM, the first question to ask is how to target/scope the deployment.

The answer to this depends on how thorough you want to be. Here is the ideal way, in my opinion.
Since we have a dependency of Powershell for this SCCM application we probably don’t want to target machines where the Powershell is going to fail. This is not essential but it will screw up your deployment results when clients return back that they failed to detect the application due to Powershell not being enabled; and hey, who wants red in their reports, eh? 🙂

So you could create Configuration Baseline to look for whether Powershell is set to the execution policy that you need, and then you can create collections off that baseline.

Either way go ahead and dump the batch file into an SCCM content location and create your application. There aren’t non-standard settings for this application and so I won’t illustrate it.
Just make sure to set the Detection Rule:

the enrol machine certificates job properties

From there just click:
Edit > Open

And point it to your Powershell script.

After that (and distributing your content) you are ready to deploy. It’s probably a good idea to use a Simulate Deployment option first since that will test if your detection script functions as expected.

Enjoy 🙂

Leave a Reply

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