Create Self-Signed Certificate and Export

Yesterday, I found myself walking through the usage of a couple of the cmdlets in the PKIClient (or PKI) module. Due to a project I’m working on, I may soon find myself needing and creating a self-signed certificate. Because I’m not yet ready to implement this code, I thought it made sense to use my blog to store it, until I am. While it’s for me, this could be helpful for you too.

$NewCertCreateParameters = @{
	Subject = 'powershell.functiontemplate.mydomain.com'
	CertStoreLocation = 'Cert:\CurrentUser\My'
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
	OutVariable = 'Certificate'
} # End.
New-SelfSignedCertificate @NewCertCreateParameters | Out-Null

In this first code section seen above, I used splatting. This allows me to create a hash table full of parameters and parameter values — key-value pairs*. Once created, it can be used — or splatted — as a part of a command’s invocation. In this instance, we’re splatting the hash table we created and stored in the $NewCertCreateParameters variable on the New-SelfSignedCertificate cmdlet. Noticed that we’re piping our command to Out-Null to keep the default output of this command from displaying. There’s still a way to see it, however.

This bit of PowerShell creates a new self-signed certificate on the computer, which is associated with the current user. Since we included the OutVariable parameter in our hash table, we have the data returned by our cmdlet invocation stored in the $Certificate variable, even though we used Out-Null. While the below output only shows three properties by default, there’s plenty more that can be reviewed by piping $Certificate to Select-Object -Property *.

[PS7.1.0] C:\> $Certificate

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject              EnhancedKeyUsageList
----------                                -------              --------------------
56DA4F187DF396CCCB67B5C93F6F0CA7848C5E66  CN=powershell.funct… {Client Authentication, Server Authentication}

Using the code in the second section, we can view our self-signed certificate after it’s been created by the previous command.

Get-ChildItem -Path $NewCertCreateParameters.CertStoreLocation |
	Where-Object Thumbprint -eq $Certificate.Thumbprint |
	Select-Object -Property *

The final section, has a few things happening. First, we create a secure string that holds a password. This isn’t a real password, so don’t bother. You get the idea, though, and really, for me, this is just about storing some code I may, or may not, use. The reason for the password is because we’re about to export the certificate to a Personal Information Exchange file — a PFX file, and we want it to be secure.

Second, we create a second parameter hash table and splat it onto the Export-PfxCertifcate cmdlet. Just as we did before, we pipe this command to Out-Null to suppress its output. Lastly, I’ve included three commands. The first one shows the .pfx file in the file system, the second one removes the .pfx file from the file system, and the third one removes the self-signed certificate from the system completely.

$CertPassword = ConvertTo-SecureString -String 'canoN Beach 44$09' -Force -AsPlainText

$NewCertExportParameters = @{
	Cert = "Cert:\CurrentUser\My\$($Certificate.Thumbprint)"
	FilePath = "$env:USERPROFILE\Documents\PowerShellFunctionTemplate.pfx"
	Password = $CertPassword
} # End.
Export-PfxCertificate @NewCertExportParameters | Out-Null

Get-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.Cert

And finally, here’s all the code in a single code block.

$NewCertCreateParameters = @{
	Subject = 'powershell.functiontemplate.arizona.edu'
	CertStoreLocation = 'Cert:\CurrentUser\My'
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
	OutVariable = 'Certificate'
} # End.
New-SelfSignedCertificate @NewCertCreateParameters | Out-Null

Get-ChildItem -Path $NewCertCreateParameters.CertStoreLocation |
	Where-Object Thumbprint -eq $Certificate.Thumbprint |
	Select-Object -Property *

$CertPassword = ConvertTo-SecureString -String 'canoN Beach 44$09' -Force -AsPlainText

$NewCertExportParameters = @{
	Cert = "Cert:\CurrentUser\My\$($Certificate.Thumbprint)"
	FilePath = "$env:USERPROFILE\Documents\PowerShellFunctionTemplate.pfx"
	Password = $CertPassword
} # End.
Export-PfxCertificate @NewCertExportParameters | Out-Null

Get-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.FilePath
Remove-Item -Path $NewCertExportParameters.Cert

* Before closing, unless you got down here sooner, I wanted to mention a couple of the parameters I opted to use in the first command invocation. The New-SelfSignedCertificate cmdlet included the NotAfter and the KeyExportPolicy parameters, as shown below. The NotAfter parameter allowed us to include the preferred expiration of the self-signed certificate. Mine used March 3, 2031, as I added 10 years to my date value. If this parameter isn’t included, it will default to a one-year expiration. The KeyExportPolicy parameter allowed us to make the private key exportable. This is not a default, so it must be included if you suspect it’ll need to be exported, which is something we did.

...
	NotAfter = (Get-Date -Date 03/03/2021 -Hour 17).AddYears(10)
	KeyExportPolicy = 'Exportable'
...

Leave a Reply

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