Powershell – Generate Microsoft CA signed SSL certificates with vSphere 5.1

Written by Sam McGeown
Published on 6/11/2012 - Read in about 4 min (725 words)

The process of requesting certificates for vSphere 5.1 is a fairly grim, manual process. It’s repetitive and easy to make a mistake on any step of the way. Since I’ve got to do this for quite a few VirtualCenter Servers, I thought I’d script the certificate generation if nothing else. I am following the excellent documentation provided in Implementing CA signed SSL certificates with vSphere 5.1 and more specifically in Creating certificate requests and certificates for vCenter Server 5.1 components.

The script assumes that:

  1. You have a working Certificate Authority
  2. You are in an Active Directory domain environment
  3. You have the relevant permissions to modify Certificate Templates, Request and Issue certificates.
  4. You have installed OpenSSL v1.0.1c or later.

You will need to modify the configuration section to suit your environment and the $WorkingDir folder should exist before you run the script.

Creating the Certificate Template

You need to modify the standard Microsoft Web Server template to allow the encryption of user data. Since you can’t edit these templates, you have to duplicate the  template and modify the settings.

Download the CA’s certificate as per the instructions in the linked KB above:

  • Navigate back to the home page of the certificate server and click on Download a CA certificate, certificate chain or CRL.

  • Click the Base 64 option.
  • Click the Download CA Certificate chain link.
  • Save the certificate chain as cachain.p7b. in the c:\certs folder.
  • Double-click on the cachain.p7b file and navigate to C:\certs\cachain.p7b > Certificates.
  • Right-click on the certificate listed and select All Actions > Export.
  • Click Next.
  • Select Base-64 encoded X.509 (.CER), and then click Next.
  • Save the export at C:\[Your $WorkingDir]\Root64.cer and click Next.

Running the script

The script itself is fairly simple, creating a folder structure for the individual certificates, wrestling with OpenSSL and handling the requests to the CA using CertReq. You can view the debug output by setting the $DebugPreference to ‘Continue’

 

# The "short" name of the Virtual Center Server
$vC_NETBIOS = "DefinIT-VC01"
# The DNS name of the Virtual Center Server
$vC_FQDN = "DefinIT-VC01.definit.co.uk"
# The IP address of the Virtual Center Server
$vC_IP = "192.168.1.10"
# The Certificate Authority Name
$CA_Name = "DefinIT-CA01\DefinIT-CA"
# The name of the template you defined earlier
$CA_Template = "CertificateTemplate:VirtualCenterWebServer"
# The CA certificate you exported earlier
$CA_Certificate = "Root64.cer"
# Administrative email to use in the certificate
$AdminEmail = "[email protected]"
# A working directory under which the certificates and folders will be created
$WorkingDir = "c:\Certificates\VMCertificates"
# An array of the services we will generate the certificates for
$Services = @("vCenterServer","vCenterInventoryService","vCenterSSO","VMwareUpdateManager","vCenterWebClient","vCenterLogBrowser","VMwareOrchestrator")# The path to the openssl executable
$OpenSSLExe =  "c:\OpenSSL-Win32\bin\openssl.exe"

if (!(Test-Path $OpenSSLExe)) {throw "$OpenSSLExe required"}
New-Alias -Name OpenSSL $OpenSSLExe

$RequestTemplate = "[ req ]
default_bits = 2048
default_keyfile = rui.key
distinguished_name = req_distinguished_name
encrypt_key = no
prompt = no
string_mask = nombstr
req_extensions = v3_req

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:ShortName,DNS:FQDN, DNS:IPADDRESS

[ req_distinguished_name ]
countryName = UK
stateOrProvinceName = West Sussex
localityName = Horsham
0.organizationName = DefinIT
organizationalUnitName = ORGREPLACE
commonName = FQDN
emailAddress = ADMINEMAIL

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true

[ req_attributes ]"

if(!(Test-Path $WorkingDir)) {
	New-Item $WorkingDir -Type Directory
}
Set-Location $WorkingDir
ForEach ($Service in $Services) {
	if(!(Test-Path $Service)) {
		New-Item $Service -Type Directory
	}
	Set-Location $Service
	write-debug "$Service: Writing Template"
	$Out = ((((($RequestTemplate -replace "FQDN", $vC_FQDN) -replace "ShortName", $vC_NETBIOS) -replace "ORGREPLACE", $Service) -replace "ADMINEMAIL", $AdminEmail) -replace "IPADDRESS", $vC_IP) | Out-File "$WorkingDir\$Service\$Service.cfg" -Encoding Default -Force
	write-debug "$Service: Generating CSR"
	OpenSSL req -new -nodes -out "$WorkingDir\$Service\$Service.csr" -keyout "$WorkingDir\$Service\rui-orig.key" -config "$WorkingDir\$Service\$Service.cfg"
	write-debug "$Service: Converting Private Key"
	OpenSSL rsa -in "$WorkingDir\$Service\rui-orig.key" -out "$WorkingDir\$Service\rui.key"
	write-debug "$Service: Submitting to $CA_Name"
	certreq -submit -attrib $CA_Template -config "$CA_Name" "$Service.csr" "$WorkingDir\$Service\rui.crt"
	write-debug "$Service: Generating PFX"
	OpenSSL pkcs12 -export -in "$WorkingDir\$Service\rui.crt" -inkey "$WorkingDir\$Service\rui.key" -certfile "$WorkingDir\$CA_Certificate" -name "rui" -passout pass:testpassword -out "$WorkingDir\$Service\rui.pfx"
	Set-Location $WorkingDir
}

 

 

 

 

Share this post