HowTo: Create self-signed certificates with PowerShell 4.0

Even though I have a lot of fun creating self-signed certificates with makecert, as described in my previous blogpost it’s not the most modern solution for automating the creation of self-signed certificates. Due to the fact that makecert does use popup windows to configure the passwords for the private key and certificate. So I looked for another way to create a self-signed certificate that could easily be integrated in automation tools and orchestration workflows …

With the release of PowerShell 4.0 and Windows 8 and up you can the use preinstalled PowerShell PKI Module to create a self-signed certificate.

 

So let’s have some PowerShell fun with certificates!

 

Working with the PKI Module

To create a self-signed certificate with PowerShell, you can use the Certificate Provider that is included with PowerShell 4.0. as part of the PKI Module. To check of the PKI Module is available on your system, you can use the following commands:

* Check which Modules are loaded in the session:

PS C:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest   3.0.0.0    Microsoft.PowerShell.Security       {ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Manifest   3.0.0.0    Microsoft.WSMan.Management          {Connect-WSMan, Disable-WSManCredSSP, Disconnect-WSMan, En...

The PKI Module is not loaded by default in a PowerShell session, so let’s ensure it is available on this system.

* Check which Modules are available:

PS C:\> Get-Module -ListAvailable

    Directory: C:\Windows\system32\WindowsPowerShell\v1.0\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0.0    DnsClient                           {Resolve-DnsName, Clear-DnsClientCache, Get-DnsClient, Get...
Manifest   3.0.0.0    Microsoft.PowerShell.Security       {Get-Acl, Set-Acl, Get-PfxCertificate, Get-Credential...}
Manifest   1.0.0.0    PKI                                 {Add-CertificateEnrollmentPolicyServer, Export-Certificate...
Script     1.0.0.0    PSDiagnostics                       {Disable-PSTrace, Disable-PSWSManCombinedTrace, Disable-WS...
Binary     1.1.0.0    PSScheduledJob                      {New-JobTrigger, Add-JobTrigger, Remove-JobTrigger, Get-Jo...

Which uses the following syntax:

  • ListAvailable: A switch to ensure all available powershell modules on the system are shown.

With Windows 8 and up, the PKI module is available on the system. You only need to load the PKI Module into your PowerShell session.

* Load the PKI Module:

PS C:\> Import-Module PKI

Now that the module is loaded, we can check the available cmdlets that are provided by the module.

* Check the available commands of the PKI Module:

PS C:\> Get-Command -Module PKI
CommandType     Name                                               ModuleName                                               
-----------     ----                                               ----------                                               
Cmdlet          Export-Certificate                                 PKI                                                      
Cmdlet          Export-PfxCertificate                              PKI                                                      
Cmdlet          Get-Certificate                                    PKI                                                      
Cmdlet          Get-PfxData                                        PKI                                                      
Cmdlet          Import-Certificate                                 PKI                                                      
Cmdlet          Import-PfxCertificate                              PKI                                                      
Cmdlet          New-SelfSignedCertificate                          PKI                                                      
Cmdlet          Switch-Certificate                                 PKI                                                      
Cmdlet          Test-Certificate                                   PKI                                                      

The PKI Module does not only provide cmdlets to create, edit and delete certificates, but it also offers a provider that can be used as a PowerShell Drive.

* Check available PowerShell Providers (useable as PowerShell Drive):

PS C:\> Get-PSProvider

Name                 Capabilities                                      Drives
----                 ------------                                      ------
Alias                ShouldProcess                                     {Alias}
Registry             ShouldProcess, Transactions                       {HKLM, HKCU}
Certificate          ShouldProcess                                     {Cert}

* Check whether the Certificate Provider is available:

PS C:\> Get-PSDrive -PSProvider Certificate

Name           Used (GB)     Free (GB) Provider      Root                           CurrentLocation
----           ---------     --------- --------      ----                           ---------------
Cert                                   Certificate   \

* Navigate to the certificate provider:

PS C:\> Set-Location Cert:
PS Cert:\>

* Browse certificate store root:

PS Cert:\> Get-ChildItem

Location   : CurrentUser
StoreNames : {TrustedPublisher, ClientAuthIssuer, Root, MSIEHistoryJournal...}

Location   : LocalMachine
StoreNames : {TrustedPublisher, ClientAuthIssuer, Remote Desktop, Root...}
PS Cert:\>

 

Creating the Self-Signed certificate

With the basic PowerShell commands available for the PKI module covered, it is time to create a self-signed certificate and be able to import it into a certificate store or export it to a file for future references. So let’s get into the required cmdlets.

* Create a self-signed certificate:

PS C:\> New-SelfSignedCertificate -DnsName "self.signed.cert" -CertStoreLocation Cert:\CurrentUser\My

    Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\My
Thumbprint                                Subject                                                                           
----------                                -------                                                                           
63B2A97053ADB57976DFA97004A44CC6A68F1BE2  CN=self.signed.cert                                                               

Which uses the following syntax:

  • DnsName: The Subject name of the certificate.
  • CertStoreLocation: The Certificate Store where the certificate is placed.

The New-SelfSignedCertificate cmdlet returns the Certificate Object, containing the certificate Thumbprint and Subject. A self-signed certificate is created with a expiration date of exactly 12 months from today.

* View the self-signed certificate in the Local Machine Personal store:

PS C> Get-ChildItem -Path Cert:\LocalMachine\My -DnsName "self.signed.cert"

    Directory: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject                                               
----------                                -------                                               
B64C45270EC271E8419D281C014FD4612AEF12B7  CN=self.signed.cert  

You can view all certificates in a certificate store if you do not specify the DnsName property.

 

Exporting the Self-Signed certificate

Creating the self-signed certificate is only the first step, as you probably need a certificate file to bind the certificate to a web server or push it to a client to put it to good use.

* Exporting a certificate from a certificate store as a single DER-encoded certificate:

PS C:\Windows\system32> Export-Certificate -Cert $SelfSignedCert -FilePath C:\Temp\SelfSignedCert.cer -Type CERT

    Directory: C:\Temp

Mode                LastWriteTime     Length Name                                               
----                -------------     ------ ----                                               
-a---         30-8-2015     19:01        817 SelfSignedCert.cer

Which uses the following syntax:

  • Cert: Specifies one or more certificates to be exported to a file.
  • FilePath: Specifies the location where the exported certificate will be stored.
  • Type: Specifies the type of output file for the certificate export. Valid options are CERT|P7B|SST.

The CER file does not contain the private key. It will be sufficient for certificate installations on client devices. To use the certificate with a web server a private key can be required. You can use the command below to export both the certificate and the key into a certificate archive kind of file, like the PFX format.

* Exporting a certificate from a certificate store as a Personal Information Exchange (PFX) file:

PS C:\> Export-PfxCertificate -Cert $SelfSignedCert -FilePath C:\Temp\SelfSignedCert.pfx -Password $certpwd

    Directory: C:\Temp

Mode                LastWriteTime     Length Name                                               
----                -------------     ------ ----                                               
-a---         30-8-2015     19:19       2709 SelfSignedCert.pfx  

Which uses the following syntax:

  • Cert: Specifies one or more certificates to be exported to a file.
  • FilePath: Specifies the location where the exported certificate will be stored.
  • Password: Specifies the password used to protect the exported PFX file.

 

A PFX file is usually protected with a password. To create the password string with PowerShell you can use the following command: ConvertTo-SecureString -String “password” -Force –AsPlainText

 

* Importing a certificate from a PFX file:

PS C:\> Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\My -FilePath C:\Temp\SelfSignedCert.pfx -Password $certpwd

 

Bonus: Bind the certificate to a website hosted by IIS

As mentioned before most SSL certificates are used with web sites and servers. You can use PowerShell to bind the certificate to a IIS website as well by using the WebAdministration module.

* Binding a certificate to the Default Web Site in IIS:

# Bind the certificate to IIS
Import-Module WebAdministration

# Go to the PowerShell Drive for IIS 
Push-Location IIS:\SslBindings

# Bind the HTTPS protocol to the Default Website (listening on all IP addresses)
New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https

# Look at the binding collection using the following command: 
Get-WebBinding 'Default Web Site'

# Bind the Self-Signed certificate to the WebBinding
$strThumb = $SelfSignedCert.Thumbprint
Get-Item Cert:\LocalMachine\MY\$strThumb | New-Item 0.0.0.0!443
Pop-Location

 

PoSHCerts02 PoSHCerts03

 

My Certificate creation script

For reference purposes I have included my script:

# Import the PKI PowerShell Module to work with Certificates
Import-Module PKI

# Add the current folder location to the Saved Locations Stack
Push-Location

#region Create Self-signed Certificate
# Create a Self-Signed certifcate in the Local Machine Personal Certificates Store
New-SelfSignedCertificate -DnsName "self.signed.cert" -CertStoreLocation Cert:\LocalMachine\My

# View all certificates in the Local Machine Personal Store
Get-ChildItem -Path Cert:\LocalMachine\My

# Retrieve the Certificate object from the certificate store
$SelfSignedCert = Get-ChildItem Cert:\LocalMachine\My -DnsName "self.signed.cert"
#endregion

#region Export a certificate to file
# Export the certificate as a CER file (no private key)
Export-Certificate -Cert $SelfSignedCert -FilePath C:\Temp\SelfSignedCert.cer -Type CERT

# Retrieve the Certificate object from the certificate store
$SelfSignedCert = Get-ChildItem Cert:\LocalMachine\My -DnsName "self.signed.cert"
# Create a password
$certpwd = ConvertTo-SecureString -String "password" -Force –AsPlainText
# Export certificate as PFX Certificate Archive (cert and key)
Export-PfxCertificate -Cert $SelfSignedCert -FilePath C:\Temp\SelfSignedCert.pfx -Password $certpwd
#endregion

#region Import a certificate from file
$mypwd = ConvertTo-SecureString -String "password" -Force –AsPlainText
Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\My -FilePath C:\Temp\SelfSignedCert.pfx -Password $certpwd

#Return to previous folder location
Pop-Location
#endregion

#region Bind a certificate to a IIS Website
# Bind the certificate to IIS
Import-Module WebAdministration

# Go to the PowerShell Drive for IIS 
Push-Location IIS:\SslBindings

# Bind the HTTPS protocol to the Default Website (listening on all IP addresses)
New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https

# Look at the binding collection using the following command: 
Get-WebBinding 'Default Web Site'

# Bind the Self-Signed certificate to the WebBinding
$strThumb = $SelfSignedCert.Thumbprint
Get-Item Cert:\LocalMachine\MY\$strThumb | New-Item 0.0.0.0!443

#Return to previous folder location
Pop-Location
#endregion

 

 

 

 

Esther Barthel
Solutions Architect at cognition IT

Esther has been working in different roles and functions as an IT consultant ever since she finished her Masters degree in Computer Science in 1997. She has worked as a web developer, database administrator, and server administrator until she discovered how Server-Based Computing ( SBC ) combined servers, desktops, and user experience in one solution. Esther has been specializing in virtualization solutions such as SBC, VDI, application, and server virtualization for over eight years now and is currently working as a Senior Consultant at PepperByte, where she designs and implements Citrix® solutions for both small-business and large-enterprise infrastructures scaling from 100 to 15,000 users.
In january 2014 her first book Citrix XenApp 6.5 Expert Cookbook was published by Packt Publishing.

Esther is awarded as a Citrix Technology Professional (CTP) from 2015 - 2017.
Esther is awarded as a Microsoft Most Valuable Professional (MVP) in 2017.

Esther is a Citrix Certified Expert – Virtualization (CCE-V), Citrix Certified Professional – Mobility (CCP-M), Citrix Certified Professional – Networking (CCP-N) and RES Software Certified Professional (RCP).