DEV Community

Adewale Azeez
Adewale Azeez

Posted on • Updated on

Managing Windows PFX certificates through PowerShell

The certificate is a container for the public key. It includes the public key, the server name, some extra information about the server, and a signature computed by a certification authority (CA).

Table of content

Prerequisites

  • Windows Vista, Windows Server 2008, or newer operating system. The examples shown use Windows 10 Pro version 1909
  • PowerShell 5.X and above
  • Familiarity with PowerShell

What is a PFX Certificate

A .pfx file which should not be confused with .cert is a PKCS#12 archive; this is a bag that can contain a lot of objects with optional password protection. It usually contains a certificate (possibly with its assorted set of CA certificates) and the corresponding private key. While PFX can contain more than one certificates a .cert file contains a single certificate alone with no password and no private key. Within Windows, all certificates exist in logical storage locations referred to as certificate stores.

The most common usage of a PFX certificate is code signing and creating a Software Publisher Certificate.

Logical stores

Logical stores are virtual locations that map to certificate physical paths. Powershell uses the Cert PSDrive to map certificates to the physical stores.

The Certificates Microsoft Management Console (MMC) logical store labeling is different from the Cert PSDrive store labeling. The table below shows the comparison between both:

CERT: CERTIFICATES MMC
My Personal
Remote Desktop Remote Desktop
Root Trusted Root Certification Authorities
CA Intermediate Certification Authorities
AuthRoot Third-Party Root Certification Authorities
TrustedPublisher Trusted Publishers
Trust Enterprise Trust
UserDS Active Directory User Object

PKI Module

MakeCert.exe utility, which is part of the Microsoft .NET Framework SDK and Microsoft Windows SDK is used to create a self-signed certificate. On a system with no Windows SDK installed, the cmdlets in Powershell PKI module are used to manage the certificates.

To list all the commands available in the PKI module, run the following command:

Get-Command -Module PKI
Enter fullscreen mode Exit fullscreen mode

The following commands are available from the PKI module.

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Add-CertificateEnrollmentPolicyServer              1.0.0.0    PKI
Cmdlet          Export-Certificate                                 1.0.0.0    PKI
Cmdlet          Export-PfxCertificate                              1.0.0.0    PKI
Cmdlet          Get-Certificate                                    1.0.0.0    PKI
Cmdlet          Get-CertificateAutoEnrollmentPolicy                1.0.0.0    PKI
Cmdlet          Get-CertificateEnrollmentPolicyServer              1.0.0.0    PKI
Cmdlet          Get-CertificateNotificationTask                    1.0.0.0    PKI
Cmdlet          Get-PfxData                                        1.0.0.0    PKI
Cmdlet          Import-Certificate                                 1.0.0.0    PKI
Cmdlet          Import-PfxCertificate                              1.0.0.0    PKI
Cmdlet          New-CertificateNotificationTask                    1.0.0.0    PKI
Cmdlet          New-SelfSignedCertificate                          1.0.0.0    PKI
Cmdlet          Remove-CertificateEnrollmentPolicyServer           1.0.0.0    PKI
Cmdlet          Remove-CertificateNotificationTask                 1.0.0.0    PKI
Cmdlet          Set-CertificateAutoEnrollmentPolicy                1.0.0.0    PKI
Cmdlet          Switch-Certificate                                 1.0.0.0    PKI
Cmdlet          Test-Certificate                                   1.0.0.0    PKI
Enter fullscreen mode Exit fullscreen mode

The cmdlets used in this article are explained below:

Export-PfxCertificate

The Export-PfxCertificate cmdlet exports a certificate or a PFXData object to a Personal Information Exchange (PFX) file. By default, extended properties and the entire chain are exported.

Get-Certificate

The Get-Certificate cmdlet can be used to submit a certificate request and install the resulting certificate, install a certificate from a pending certificate request, and enroll for the directory service protocol LDAP.

Get-PfxData

The Get-PfxData cmdlet extracts the contents of a Personal Information Exchange (PFX) file into a structure that contains the end entity certificate, any intermediate and root certificates.

Import-PfxCertificate

The Import-PfxCertificate cmdlet imports certificates and private keys from a PFX file to the destination store.

New-SelfSignedCertificate

The New-SelfSignedCertificate cmdlet creates a self-signed certificate for testing purposes. Using the CloneCert parameter, a test certificate can be created based on an existing certificate with all settings copied from the original certificate except for the public key.

Finding and Selecting a certificate

In Powershell, the Cert: PSDrive is used to list the certificates in a particular store. To list the two locations under the Cert: PSDrive, run the following command:

Get-ChildItem -Path Cert:
Enter fullscreen mode Exit fullscreen mode

The certificate locations for the CurrentUser and LocalMachine will be shown. To list the certificates under the LocalMachine Trusted Root Certification Authorities, run the following command:

Get-ChildItem -Path Cert:\LocalMachine\Root\
Enter fullscreen mode Exit fullscreen mode

The returned object will be the certificates that can be modified, delete or exported.

The Get-ChildItem cmdlet can be combined with Where-Object to find specific certificates. The command below will find certificate supposedly issued by Microsoft by checking the Subject property of the certificates:

Get-ChildItem -Path Cert:\LocalMachine\Root\ | Where-Object {$_.Subject.Contains("Microsoft")}
Enter fullscreen mode Exit fullscreen mode

The certificates listed will have part of it Subject value contains Microsoft.

Creating a certificate

To create a certificate the values of –DnsName (name of a DNS server) or the -Subject and -CertStoreLocation (the certificate store in which the generated certificate will be placed) will have to be specified.

To create a certificate for the DNS test.com and install it in the list of Personal certificate on a system, run the following command:

New-SelfSignedCertificate -DnsName test.com -CertStoreLocation cert:\LocalMachine\My
Enter fullscreen mode Exit fullscreen mode

The command creates a new certificate and installs it into the personal store location of the computer. On opening certlm.msc the certificate will appear in the Personal section. The output will show the details of the newly created certificate including its thumbprint:

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

Thumbprint                                Subject
----------                                -------
644F29EA276A639A28F82137F8132D6F49C1664A  CN=test.com
Enter fullscreen mode Exit fullscreen mode

A self-signed certificate is generated with the following settings by default:

  • Cryptographic algorithm: RSA;
  • Key length: 2048 bit;
  • Acceptable key usage: Client Authentication and Server Authentication;
  • The certificate can be used for Digital Signature, Key Encipherment;
  • Validity period: 1 year.

The validity of the generated certificate is limited to one year. To extend the certificate, a proper Date object with extended validity period should be specified with the -notafter switch. To issue a certificate for 5 years, run the command below:

$expiry_year = (Get-Date).AddYears(5)
New-SelfSignedCertificate -DnsName test.com -notafter $expiry_year -CertStoreLocation Cert:\LocalMachine\My
Enter fullscreen mode Exit fullscreen mode

The command below generates a certificate with value Test using the Subject property only and sets its expiry year to 3 years after the creation date:

$expiry_year = (Get-Date).AddYears(3)
New-SelfSignedCertificate -Subject Test -notafter $expiry_year -CertStoreLocation Cert:\LocalMachine\My
Enter fullscreen mode Exit fullscreen mode

New certificates can only be created in the personal store locations, Cert:\LocalMachine\My or Cert:\CurrentUser\My.

Execute the help command below to view all other parameters accepted by the New-SelfSignedCertificate cmdlet:

help New-SelfSignedCertificate -Full
Enter fullscreen mode Exit fullscreen mode

To export the certificate to pfx, read this section

Installing a pfx certificate

The certificate can be installed in a different store location, each store location has its specific purpose but in this article, we will install into four locations Cert:\CurrentUser\My, Cert:\LocalMachine\My, Cert:\CurrentUser\Root and Cert:\LocalMachine\Root. My location is the personal store for untrusted application and Root is the store for trusted certificates.

The command used to install a common certificate is different from the command to install a PFX certificate. The Powershell Cmdlet Import-PfxCertificate is used to install a pfx certificate.

To install a PFX certificate to the current user's personal store, use the command below:

Import-PfxCertificate -FilePath ./TestPFXCert.pfx -CertStoreLocation Cert:\CurrentUser\My -Password testpassword 
Enter fullscreen mode Exit fullscreen mode

To install into the system personal location change the store location in the command above from Cert:\CurrentUser\My to Cert:\LocalMachine\My

To install a PFX certificate the current user's trusted store, use the command below:

Import-PfxCertificate -FilePath ./TestPFXCert.pfx -CertStoreLocation Cert:\CurrentUser\Root -Password testpassword 
Enter fullscreen mode Exit fullscreen mode

Installing into the current user Root location will pop up a dialog to confirm the certificate installation but installing into the system Root location will not pop up any dialog.

To install into the system trusted location change the store location in the command above from Cert:\CurrentUser\Root to Cert:\LocalMachine\Root

Add a certificate as trusted

An untrusted certificate is pretty much as dangerous and suspicious than no certificate at all, therefore, it is important to add our certificate to the trusted path.

Alt Text

Certificates can only be generated in the Cert:\LocalMachine\My store location. Since any certificate in this location is marked as untrusted by default, to make it secure it has to be moved from Cert:\LocalMachine\My to Cert:\LocalMachine\Root.

Move-Item -Path $cert.PSPath -Destination "Cert:\LocalMachine\Root"
Enter fullscreen mode Exit fullscreen mode

Now the certificate will be marked as trusted. When used to sign a script or application the script will be marked secure for execution.

Alt Text

Check for duplicate certificate

To avoid re-adding an already existing certificate into the certificate store location, the already existing certificate should be checked and removed before adding a new certificate with the same subject. Powershell automatically creates a virtual drive path for the cert: label and behaves like a normal directory. The snippet below checks the cert:\LocalMachine\My path of the certificate store to find a certificate using its Subject value.

$cert_name = "Test Cert"
ForEach ($cert in (ls cert:\LocalMachine\My)) {
    If ($cert.Subject -eq "CN=$cert_name") {
        //the certificate can be deleted or edited in here
    }
}
Enter fullscreen mode Exit fullscreen mode

Exporting and Importing certificate

The commands to import and export a pfx certificate are different from commands to export and import a regular certificate. The Import-PfxCertificate cmdlet is used for importing a passworded pfx certificate and Export-PfxCertificate cmdlet for exporting a certificate from its store location to a new file location.

Exporting pfx certificate

To export a pfx certificate a password is needed for encrypting the private key.

In the example below, we use the Subject property to find the certificate to be exported by selecting the certificate whose Subject value equals Test,

$certificate = Get-ChildItem -Path Cert:\LocalMachine\My\ | Where-Object {$_.Subject -match "Test"}
Enter fullscreen mode Exit fullscreen mode

After selecting the certificate it can be exported from its store location to a folder with the command below:

$password= "@OurPassword1" | ConvertTo-SecureString -AsPlainText -Force
Export-PfxCertificate -Cert $certificate -FilePath $env:USERPROFILE\Documents\TestCert.pfx -Password $password
Enter fullscreen mode Exit fullscreen mode

Importing pfx certificate

Downloaded or exported pfx certificates can be installed using the Import-PfxCertificate cmdlet. The password for the certificate and location are required for importing.

The command below imports the pfx certificate we exported earlier:

$password= "@OurPassword1" | ConvertTo-SecureString -AsPlainText -Force
Import-PfxCertificate -Exportable -Password $password -CertStoreLocation Cert:\LocalMachine\My -FilePath $env:USERPROFILE\Documents\TestCert.pfx
Enter fullscreen mode Exit fullscreen mode

The -Exportable switch marks the private key as exportable.

Export a Certificate from pfx

To export certificate from a pfx file, the combined cmdlet Get-PfxCertificate and Export-Certificate is used. Get-PfxCertificate is used to locate the pfx certificate and Export-Certificate is used to export the specified certificate to a FilePath.

This process is not seamless as it requires the user to input the password for the pfx certificate.

The following command exports a DER encoded (binary) certificate from a pfx file.

Get-PfxCertificate -FilePath $env:USERPROFILE\Documents\TestCert.pfx | 
Export-Certificate -FilePath $env:USERPROFILE\Documents\TestCert.cer -Type CERT
Enter fullscreen mode Exit fullscreen mode

Note the -Type switch which is used to indicates the type of certificate to be exported, in this example a DER encoded (binary) CERT certificate. There are other types that can be exported. They are listed below.

-Type <CertType>
    Specifies the type of output file for the certificate export as follows. 
     -- SST: A Microsoft serialized certificate store (.sst) file format which can contain one or more certificates. This is the default value for multiple certificates. 
     -- CERT: A .cer file format which contains a single DER-encoded certificate. This is the default value for one certificate. 
     -- P7B: A PKCS#7 file format which can contain one or more certificates.
Enter fullscreen mode Exit fullscreen mode

Deleting a certificate

To remove a certificate, the Remove-Item command in Powershell can be used. Before a certificate can be deleted its thumbprint id must be known or the certificate object itself identified. The certificate path can be iterated through, using the snippets above to find the object or thumbprint.

Deleting with thumbprint

The snippet below uses the certificate thumbprint for deletion...

Get-ChildItem Cert:\LocalMachine\My\D20159B7772E33A6A33E436C938C6FE764367396 | Remove-Item
Enter fullscreen mode Exit fullscreen mode

Get-ChildItem is a Powershell command to get file/folder information, one of its aliases is ls. It simply uses the thumbprint to get the certificate object and pipe it as input to the Remove-Item command.

Find and Delete a certificate using property match

A certificate can be searched in the store location using the Where-Object command that accepts a conditional statement that matches the certificate we are looking for.

Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -match 'Test' } |
Remove-Item
Enter fullscreen mode Exit fullscreen mode

Notice we use the Subject property of a certificate, the other properties are Thumbprint and SerialNumber.

Windows Certificate Manager

The Windows Certificate Manager (certmgr.msc) is a Windows essential GUI application to manage certificates. Search for certmgr in the Start menu to open the Windows Certificates MMC. The landing view provides an overview of all the logical stores.

Alt Text

Certificates can be installed, delete, import and export from the Windows Certificate Manager.

References

PKIClient
Digital Certificates
System Store Locations
Convert .pfx to .cer
How to Sign PowerShell Script with a Code Signing Certificate
Managing Certs with Windows Certificate Manager and PowerShell

Oldest comments (3)

Collapse
 
kegsta profile image
Keighley Williams

great stuff here

Collapse
 
ekhanad profile image
ekhanad

Very Good Article!

Collapse
 
eduardomozart profile image
Eduardo Mozart de Oliveira

When specifying the certificate password, you must convert the -Password switch with ConvertTo-SecureString cmdlet.
E.g. To install a PFX certificate to the current user's personal store, use the command below:
Import-PfxCertificate -FilePath ./TestPFXCert.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String 'testpassword' -AsPlainText -Force)