New-SelfSignedCertificate: Creating Certificates with PowerShell

Published:14 May 2021 - 7 min. read

Azure Cloud Labs: these FREE, on‑demand Azure Cloud Labs will get you into a real‑world environment and account, walking you through step‑by‑step how to best protect, secure, and recover Azure data.

Do you need an SSL certificate for website development or testing applications? Instead of buying expensive digital certificates from third-party providers, why not create a self-signed certificate yourself? Don’t worry; PowerShell got you covered with the New-SelfSignedCertificate cmdlet.

Not a reader? Watch this related video tutorial!
Not seeing the video? Make sure your ad blocker is disabled.

In this tutorial, you will learn how to create new self-signed certificates in PowerShell using various examples. By the end, you’ll have created self-signed certificates with different properties and for different purposes. Let’s get started!

Prerequisites

If you’d like to follow this tutorial hand-on, make sure you have the following requirements.

  • A Windows computer with Windows PowerShell 5.1 or the latest PowerShell 7 (v7.1.3 as of this writing). This tutorial will be using Windows 10 version 2004 and Windows PowerShell 5.1.
  • Your user account must have administrator rights on the local machine.
  • Throughout this article, you will be using an elevated PowerShell session (run as admin) and assumes that you already have one opened.

Creating A Certificate With a Single Subject

When you need to create self-signed certificates in PowerShell, the New-SelfSignedCertificate cmdlet is your friend. This cmdlet will help you create certificates for different purposes, such as code-signing, server authentication, and document encryption, to name a few.

To create a self-signed certificate with only one subject, like a single website URL or one server FQDN, the New-SelfSignedCertificate cmdlet only requires the Subject parameter. You can think of the subject as a unique label for the certificate that differentiates it from other certificates.

For example, run the command below in PowerShell to create a self-signed certificate for a website called LocalSite.com. This example will create the certificate in the local machine personal certificate store for server authentication. For web services, it’s common to use the URL of the website a certificate will be protecting as the subject name.

The certificates in the local machine certificate store are globally available to all users on the local computer. In comparison, the certificates in the current user certificate store are only available to the current user.

# Create a self-signed certificate in the local machine personal certificate store and store the result in the $cert variable.
$cert = New-SelfSignedCertificate -Subject localsite.com
# Display the new certificate properties
$cert | Format-List -Property *

To create the new certificate in the current user personal certificate store (Cert:\CurrentUser\My), add the -Certstorelocation Cert:\CurrentUser\My parameter or in the trusted root certification authority store use Cert:\LocalMachine\Root.

The screenshot below shows the expected result after creating the certificate and displaying all of its properties. You can see that the selfsignedcertificate cmdlet automatically adds the CN= prefix to the subject name.

Creating a self-signed certificate with a single subject name
Creating a self-signed certificate with a single subject name

Creating A Subject Alternative Name (SAN) Certificate

You’ve created a certificate with a single subject name, which is good if you’re deploying it to one website. But what if you have multiple websites like localsite.com, content.localsite.com, and apps.localsite.com.

Instead of creating a self-signed certificate for each website, you can create one certificate with multiple subject alternative names (SAN). This type of certificate is called a SAN certificate.

To create a SAN certificate, run the New-SelfSignedCertificate with the DnsName parameter. The DnsName parameter accepts one or more subject names that you want to include in the certificate.

When you provide multiple values to the DnsName parameter, the first string in the DnsName parameter will appear as the certificate’s primary subject name. The other names will be the alternative names. Whichever subject name is primary does not affect the certificate’s usability and will function the same.

For example, to create the SAN certificate for localsite.com, content.localsite.com, and apps.localsite.com, run the command below in PowerShell.

# Create a self-signed SAN certificate in the local machine personal certificate store and store the result in the $cert variable.
$cert = New-SelfSignedCertificate -DnsName localsite.com,content.localsite.com,apps.localsite.com
# Display the new certificate properties
$cert | Format-List -Property *

As you can see below, the cmdlet created a new certificate with multiple subject names, as shown in the DnsNameList property.

Creating a self-signed SAN certificate
Creating a self-signed SAN certificate

Creating A Certificate With A Specific Validity Period

By default, self-signed certificates are valid for one year, which could be enough for most use cases. But if you need to specify a specific validity period when creating a self-signed certificate, you can add the NotBefore and NotAfter parameters.

For example, to create a self-signed certificate valid NotBefore today and NotAfter 24 months from now, run the command below in PowerShell.

# Create a self-signed certificate in the local machine personal certificate store valid for 24 months and store the result in the $cert variable.
$cert = New-SelfSignedCertificate -DnsName localsite.com -NotAfter (Get-Date).AddMonths(24)

To confirm the new certificate, run the command below to display the certificate’s select properties, including the start and expiration dates.

$cert | Select-Object -Property Subject,Thumbprint,NotBefore,NotAfter

You can see from the result that you now have a self-signed certificate with a 24-month validity.

Getting the self-signed certificate's validity period
Getting the self-signed certificate’s validity period

Cloning An Existing Self-Signed Certificate

Suppose your self-signed certificate is about to expire. If you still need the certificate, then the logical action is to renew it. But there’s no direct way to renew the certificate. What do you do? Either create a new self-signed certificate from scratch or clone the existing certificate.

Cloning the old certificate makes the new certificate inherit the old certificate’s properties, excluding the public key, thumbprint, serial number, and expiration date. For this reason, cloning the old certificate is the quicker option.

To clone a certificate, add the CloneCert parameter to the New-SelfSignedCertificate command. Follow the steps below:

1. First, find the certificate you want to clone. To do that, run the Get-ChildItem command to list the existing certificates in the certificate store. In the below snippet, PowerShell is searching the local machine’s certificate store looking for all certificates with a subject ending with the string localsite.com and returning a few certificate attributes.

# Get all certificates whose Subject name is like localsite.com.
 Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*localsite.com"} | Select-Object Subject,DnsNameList,Thumbprint,NotBefore,NotAfter

As you can see below, there could be more than one certificate matching the subject name you search for. In which case, inspect the list of certificates to determine which certificate to clone. After you’ve decided, copy the certificate’s thumbprint.

Getting the list of existing certificates
Getting the list of existing certificates

2. Now that you’ve determined the certificate to clone and copied its thumbprint, run the command below to retrieve the old certificate. Make sure to change the Thumbprint value to the thumbprint you copied in the previous step.

# Get the certificate and store it in the $certToClone variable
 $certToClone = Get-Item Cert:\LocalMachine\My\

3. Next, create a new certificate by cloning the original by running New-SelfSignedCertificate with the CloneCert parameter.

# Create cloned self-signed certificate
 $cert = New-SelfSignedCertificate -CloneCert $certToClone

Without specifying the NotBefore and NotAfter parameters, the new certificate will have the same validity period as the old certificate (i.e., two years). The NotBefore value will be the current date and time minus ten minutes.

Alternatively, to give the new certificate a different validity period, run the same command but add the NotAfter parameter. For example, to make the certificate valid for four years, run the command below.

# Create cloned self-signed certificate valid for four years
 $cert = New-SelfSignedCertificate -CloneCert $certToClone -NotAfter (Get-Date).AddYears(4)

4. Finally, run the command below to verify the new certificate you’ve created.

# Display the cloned certificate properties
 $cert | Select-Object Subject,DnsNameList,Thumbprint,NotBefore,NotAfter

As you can see below, you have now cloned the self-signed certificate with the same subject and alternative names as the original. The thumbprint, start date, and expiration date are new.

Viewing the self-signed certificate clone properties
Viewing the self-signed certificate clone properties

Creating A Code-Signing Certificate

To ensure that your script or code bears a digital signature, you must sign your scripts using a code-signing certificate. The New-SelfSignedCertificate cmdlet is capable of creating code-signing certificates, too.

To create a self-signed code-signing certificate, run the New-SelfSignedCertificate command below in PowerShell. The Type parameter specifies to create a CodeSigningCert certificate type. The certificate will be valid for 24 months. Note that assigning a specific validity period is optional with the NotAfter parameter.

# Create a self-signed code signing certificate valid for 24 months.
$cert = New-SelfSignedCertificate -Subject CodeSigningCert -NotAfter (Get-Date).AddMonths(24) -Type CodeSigningCert

After generating the code-signing certificate, run the command below to confirm that the EnhancedKeyUsageList value shows the certificate’s valid key usage is Code Signing.

$cert | Select-Object Subject,EnhancedKeyUsageList
Verifying the certificate is valid for code signing
Verifying the certificate is valid for code signing

Creating A Document Encryption Certificate

When you have contents you want to protect from prying eyes like documents or emails, encryption is one way of protecting them. But first, you need a type of certificate for document encryption, which you can also create using the New-SelfSignedCertificate cmdlet.

To create a document encryption certificate, the New-SelfSignedCertificate cmdlet requires a specific set of KeyUsage values. These values are:

  • DataEncipherment – The certificate will be valid for encrypting data.
  • KeyEncipherment – The certificate will be valid for encrypting secret/private keys.
  • KeyAgreement – The certificate will be valid for deriving cryptographic keys, such as in Elliptic Curve Cryptography.

Also, the Type parameter value must be DocumentEncryptionCert.

Run the command below to create a self-signed certificate for document encryption. The certificate will be valid for two years. To keep the command more readable, the code below uses splatting to define the parameter values.

Because encrypting content is typically for personal use, creating the document encryption certificate in the current user personal certificate store is appropriate. Doing so restricts the certificate to the current user (you) to encrypt and decrypt contents.

# Define the certificate parameter values
$certSplat = @{
	DnsName = 'DocEncCert'
	KeyUsage = @('KeyEncipherment','DataEncipherment','KeyAgreement')
	Type = 'DocumentEncryptionCert'
	CertStoreLocation = 'Cert:\\CurrentUser\\My'
	NotAfter = (Get-Date).AddYears(2)
}
# Create the self-signed document encryption certificate
$cert = New-SelfSignedCertificate @certSplat

Next, to verify the self-signed certificate is valid for code signing, run the command below to get the certificate’s EnhancedKeyUsageList value.

$cert | Select-Object Subject,EnhancedKeyUsageList

As you can see from the result below, the certificate lists Document Encryption, which means that the certificate is valid to use for document encryption.

Verifying the certificate is valid for document encryption
Verifying the certificate is valid for document encryption

Now that you have a document encryption certificate, you can encrypt and decrypt contents using the Protect-CmsMessage and Unprotect-CmsMessage cmdlets.

Conclusion

This article aimed to teach you how you can quickly acquire self-signed certificates for your testing and development needs. You learned how to create self-signed certificates using different parameters and for different purposes.

There are more parameters that you can explore that this article did not cover. How about creating a S/MIME certificate for securing emails or certificates with stronger algorithms? You’d probably want to learn how to export and import those certificates too. Good luck!

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!