Creating a Domain SSL Certificate using PowerShell

Before I directly jump into the Domain SSL certificate creation using PowerShell, I assume that you have the basic understanding about security, certificates, SSL, encryption, etc. If required you can go through this wiki link for the basics.

I will take a use case – Secure Gateway Set-Up Automation where I have used SSL certificates. This use case can be outlined as below:
1. Install Secure Gateway and Web Interface on a W2KR8 server machine
2. Install a XenApp server on a W2K8R2 server machine (other than the machine in Step 1)
3. Install a SSL certificate on the Secure Gateway machine
4. Configure the Web Interface
5. Configure the Secure Gateway

In this post I am going to discuss how the Step 3 – installation of a SSL certificate, was implemented for the above use case.

So, to install a SSL certificate, we need a Certification Authority (CA) to which a certificate request has to be sent. This CA will then process the request and in turn return a .cer file which is used to complete the installation process.

Now, either an already existing CA can be used or a new CA can be created which will act as the Certification Authority. For this post I will be using an already existing CA. So as a part of the automation script, I will send a request to this already existing CA for a fresh SSL certificate.

So, for the installation of SSL certificate I have used a function which takes below parameters:
a. Fully Qualified Domain Name (FQDN) of the Certification Authority
b. Name of the Certification Authority
c. Friendly Name for the certificate which has to be created. (Keep it unique so that this can be later used to fetch the thumbprint of the certificate)

Below is the code snippet which installs a certificate using the WebServer template.

<strong>function support_networkConfiguration_createCertificate</strong>
{
       Param(  [Parameter(Position=0,Mandatory=$true)][string] $CA_HOSTFQDN,
               [Parameter(Position=1,Mandatory=$true)][string] $CA_NAME,
               [Parameter(Position=2,Mandatory=$true)][string] $CERT_NAME
               )

<strong>Write-Verbose "support_networkConfiguration_createCertificate: Preparing Web Server Certificate request..."</strong>
$myServer = $env:COMPUTERNAME + "." + $env:USERDNSDOMAIN
$TemplateName = "WebServer"

Remove-Item webcert.inf -ErrorAction silentlycontinue | Out-Null
Remove-Item webcert.req -ErrorAction silentlycontinue | Out-Null

Add-Content webcert.inf "[NewRequest]`r
Subject = `"CN=$myServer`"`r
Exportable = TRUE`r
RequestType = CMC`r
FriendlyName = `"$CERT_NAME`"`r  
[RequestAttributes]`r
CertificateTemplate = `"$TemplateName`"`r"

. certreq -new webcert.inf webcert.req | Out-Null
Write-Debug  "support_networkConfiguration_createCertificate: Sending Certificate Request..."
. certreq -submit -config "$CA_HOSTFQDN\$CA_NAME" webcert.req webcert.cer | Out-Null
Write-Debug "support_networkConfiguration_createCertificate: Installing Certificate for IIS SSL..."
. certreq -accept webcert.cer | Out-Null
Write-Verbose "support_networkConfiguration_createCertificate: Successfully installed the certificate."

<strong>#Cleanup Certificate Request Files</strong>
Remove-Item webcert.inf -ErrorAction silentlycontinue | Out-Null
Remove-Item webcert.req -ErrorAction silentlycontinue | Out-Null
Remove-Item webcert.cer -ErrorAction silentlycontinue | Out-Null
}

Above function, first clears any existing certificate request files (webcert.inf and webcert.req) and then creates a fresh certificate request (webcert.inf and webcert.req) to the domain Certification Authority (CA). Once the CA is done with processing of the request webcert.cer file is created, which is then used to install the certificate on the Web Server.

Note that, if you don’t want the Private Key of the certificate to be exportable, edit “Exportable = TRUE`r” to “Exportable = FALSE`r” in the above function.

After the completion of the certificate installation, this function will clear all the files created while installing the certificate.

Now how do I call this function in my automation? It’s pretty simple. Let say “example.domain.com” is the FQDN for my domain Certification Authority server, “DomainCA” is the name of Certification Authority and I want “My_Certificate” to be the friendly name for the certificate. The function can be called as below in the scripts:

support_networkConfiguration_createCertificate -CA_HOSTFQDN “example.domain.com” -CA_NAME “DomainCA” -CERT_NAME “My_Certificate”

PSTI library containing this function:
This function is available in one of the PSTI support functions. It is available with the name support_networkConfiguration_createCertificate in the file support_networkConfiguration.ps1.

This file can be found in Perforce under this location: //Automation/PowerShellTestInterface/Main/Support.Modules/

So, when you are using this function in your automation, you need to include the ps1 file which contains this function (i.e. support_networkConfiguration.ps1). This can be done using below line at the beginning of your script:


# Including other scripts
. "FullPath\support_networkConfiguration.ps1"

And to call this function use below command in your scripts:

support_networkConfiguration_createCertificate -CA_HOSTFQDN “example.domain.com” -CA_NAME “DomainCA” -CERT_NAME “My_Certificate”

Limitations of this function:
1. This function requires an already existing CA for a particular domain. If the domain does not have a CA, then this function won’t work.
2. This function installs the certificate using the “WebServer” template.
3. This function should work with a newly created CA as well, since it has been tested with our local BLR domain and also with FTL domain, but testing has not been done exhaustively in this regard.