PowerShell Pipeline

Back Up Certificates Using PowerShell

Here's a couple different ways to get the job done.

Continuing on from my previous article that showed you how to find certificates on local and remote systems, I am going to show you how to export certificates from a local or remote certificate store either through PowerShell remoting or using .Net types to make this happen.

If you are running PowerShell V4 and are running Windows 8.1/Windows Server 2012 R2, then you can make use of the PKI module that has an Export-Certificate cmdlet to make exporting certificates easier to do.  If you do not have this yet, you can take advantage of the techniques that I showed you in the earlier article to get to the certificate and then export it out to a file.

Export-Certificate Cmdlet
The first thing I am going to show is a quick example of using the Export-Certificate cmdlet from the included PKI module in PowerShell V4.

Get-Item -Path Cert:\CurrentUser\My\43E6F2745D4DA26370F59FF0FE17415AE6829F76  | 
Export-Certificate -Type CERT -FilePath "C:\Users\proxb\Desktop\MyCert.cer" -Verbose
[Click on image for larger view.]  Figure 1. Exporting certificate to a .cer file

Here I am taking a certificate that I pulled from my local store and then piped the certificate object into Export-Certificate and specified what type of certificate it is (in this case , a Cert) and then specified the destination path that I wanted to save the certificate to as a file. Pretty simple and can easily be done using PowerShell remoting as long as you have remoting enabled and the remote system has PowerShell V4 installed and is a Windows 8.1/Windows Server 2012 R2 system.

Using .Net Types
We can still export certificates from remote systems but it will require a little more work using some .Net types to give us the remote connection that we will need.

The first thing that needs to be done is making the connection to the remote system and locating a certificate that we want to export to a file. I am not going to explain this portion as it was covered in my previous article, but the gist of it is that I am connecting the remote certificate store on the remote system and am then opening the store to view all of the certificates.

$Computername = "boe-pc"
$CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store  -ArgumentList "\\$($Computername)\My", "LocalMachine"
$CertStore.Open('ReadOnly')
$certificate  = $CertStore.Certificates[0]

I now have a certificate that I wish to export. Looking at the available methods, I can see that there is an Export() method.

$certificate | Get-Member -MemberType Method 
[Click on image for larger view.]  Figure 2. Looking at the members of the X509Certificate2 object

This should be exactly what I am looking for! Now we just need to check out the parameters that are required for this method to work properly.

$certificate.Export

OverloadDefinitions                                                                                                                                                                                       -------------------                                                                                                                                                                                       byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType)                                                                                                                  byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, string password)                                                                                                byte[] Export(System.Security.Cryptography.X509Certificates.X509ContentType contentType, securestring password)

Here we have three possible overloads to choose from. For this piece, I am going to look only at the first set which has the contentType parameter.

You will see that each of these share a common parameter: contentType which has an Enumeration called System.Security.Cryptography.X509Certificates.X509ContentType which is used to determine the format of the certificate when you perform the export. We can quickly view those values and see what is available to use.

[enum]::GetNames('System.Security.Cryptography.X509Certificates.X509ContentType')

Unknown
Cert
SerializedCert
Pfx
Pkcs12
SerializedStore
Pkcs7
Authenticode

What does this actually mean? Let's look at the table and find out.

Authenticode

An Authenticode X.509 certificate.

Cert

A single X.509 certificate.

Pfx

A PFX-formatted certificate. The Pfx value is identical to the Pkcs12 value.

Pkcs12

A PKCS #12–formatted certificate. The Pkcs12 value is identical to the Pfx value.

Pkcs7

A PKCS #7–formatted certificate.

SerializedCert

A single serialized X.509 certificate.

SerializedStore

A serialized store.

Unknown

An unknown X.509 certificate.

For this particular article, I will be using the CERT content type format.

Exporting a CER File
Exporting a certificate to a CER file only requires specifying the format of the exported certificate file. In this case, I am going to use the Cert format.

[byte[]]$Bytes  = $certificate.Export('Cert') 

All I have done now is exported the certificate which in turn gives me the data in bytes. This means that we still need to create the file using the information provided. We can use Set-Content for that.

Set-Content -Path 'C:\users\proxb\Desktop\BackupCert.Cer' -Value $Bytes -Encoding Byte 

Now if we were to open up the file, it will show us the certificate information for my BackupCert.Cer file.

As you can see, there are a couple of ways to export certificates to a file and depending on your environment, you can choose to go the cmdlet way or the .Net way using PowerShell.

About the Author

Boe Prox is a Microsoft MVP in Windows PowerShell and a Senior Windows System Administrator. He has worked in the IT field since 2003, and he supports a variety of different platforms. He is a contributing author in PowerShell Deep Dives with chapters about WSUS and TCP communication. He is a moderator on the Hey, Scripting Guy! forum, and he has been a judge for the Scripting Games. He has presented talks on the topics of WSUS and PowerShell as well as runspaces to PowerShell user groups. He is an Honorary Scripting Guy, and he has submitted a number of posts as a to Microsoft's Hey, Scripting Guy! He also has a number of open source projects available on Codeplex and GitHub. His personal blog is at http://learn-powershell.net.

comments powered by Disqus
Most   Popular