How to Manage Certificate Stores Using PowerShell

  1. Understanding the Certificate Store
  2. Managing Certificates Using PowerShell
How to Manage Certificate Stores Using PowerShell

We might have been forced to work with windows certificates if we were Windows system administrators. Unfortunately, working with certificates in Windows is typically one of the different hats a system administrator has to take on.

This article will discuss how to query certificates and manage certificate stores using PowerShell.

Understanding the Certificate Store

Certificate stores are “buckets” where the Windows OS keeps all presently installed certificates; a certificate can exist in multiple stores and are sometimes referred to as physical or logical stores. The registry keys and files are stored in physical stores that refer to the existing file system or registry location.

The Windows Registry and the file system contain each store. We interact with the logical store rather than the registry or file system when working with a certificate.

Dynamic references to one or more physical stores are logical stores, and physical stores are more challenging to manage than logical stores. Windows keeps certificates in two locations: a user context and a computer context.

Depending on whether the certificate should be used by a single user, several users, or the machine itself, a certificate is placed in one of these two contexts. A certificate in a user or computer context shall be referred to as user certificates and computer certificates for the rest of this article.

User Certificates

If we only want a single user to utilize a certificate, a user certificate stored in the Windows certificate manager is ideal. This is common for certificate-based authentication systems such as wired IEEE 802.1x.

User certificates are stored in the current user’s profile and can only be logically mapped to that user’s context. Even on the same systems, user certificates are “mapped” and are unique to each user.

Computer Certificates

If all users use a certificate on a computer or a system process, it should be placed inside a store in the computer context. For example, if a system uses a certificate on a webserver to encrypt communication for all clients, setting a certificate in a store in the computer context would be ideal.

We will see that a computer’s certificate store is logically mapped for all user contexts, and this concept allows for certificates in a computer certificate store to be used by all users. However, it still depends on the permissions configured for the private key.

The Program Data folder and the Local Machine Registry hives include computer certificates. In addition, we can find user certificates in the AppData folder and the Current User Registry hives.

Managing Certificates Using PowerShell

As with the MMC, we can also view and manage certificates with PowerShell. But, first, let us inspect certificates in their physical stores (the registry and file system).

Physical Store

We can enumerate all of the keys and values within the parent HKCU:\Software\Microsoft\SystemCertificates\CA\Certificates\ registry key path using the Get-ChildItem PowerShell cmdlet.

The command below will enumerate all the currently logged-in user’s certificates in the Intermediate Certification Authorities logical store.

Example Code:

Get-ChildItem -Path HKCU:\Software\Microsoft\SystemCertificate\CA\Certificates\

The certificate’s thumbprint for the trusted CA and its certificate in the corresponding property will correspond to each entry in the Registry hive we see.

Output:

Hive: HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\CA\Certificates

Name                           Property
----                           --------
070A726C6E4418DCF0213874F0C16D Blob : {3, 0, 0, 0...}
93B041E935
104C63D2546B8021DD105E9FBA5A8D Blob : {3, 0, 0, 0...}
78169F6B32
<SNIP>

The personal store is another standard store, and this store’s certificates are stored on the file system rather than the registry. The command below returns a directory containing files corresponding to certificates installed in the Personal current user store.

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificate\My\Certificates\

Each file returned in the below command refers to the object for a private key created by the Key Storage Provider (KSP). The filename corresponds to the Subject Key Identifier of the certificate.

Therefore, each private key we install will have a corresponding file added.

Get-ChildItem -Path $env:APPDATA\Microsoft\SystemCertificate\My\Keys\

Each file in the directory produced by the command below is a unique container for the KSP’s encrypted private key. The file name and the certificate have no direct link, but the file is the target of the pointer in the previous command.

Get-ChildItem -Path $env:APPDATA\Microsoft\Crypto\Keys

Logical Store

We’ll use the logical storage for the rest of the instances because working with certificates in their physical pathways is uncommon. PowerShell can access logical stores using the Cert:PSDrive, which maps certificates to physical stores.

When working with certificates, we will need a way to filter and select credentials to perform specific operations against. For example, we will screen and select certificates based on the value of a particular extension.

We need to start by listing all installed certificates in the root CA store for the following examples.

Get-ChildItem -Path Cert:\CurrentUser\Root\

The returned objects are certificate objects, which we can utilize in the examples below. The certificate objects already have common extensions as properties.

So we will use Get-Member to list all the properties of the returned objects in the example below.

Example Code:

# gci is an alias of Get-ChildItem
gci -Path Cert:\CurrentUser\Root | Get-Member -MemberType Properties

Output:

TypeName: System.Security.Cryptography.X509Certificates.X509Certificate2

Name                     MemberType     Definition
----                     ----------     ----------
PSChildName              NoteProperty   string PSChildName=EBE112F56D5FE0BA23289319C89D7784A10CEB61
PSDrive                  NoteProperty   PSDriveInfo PSDrive=Cert
PSIsContainer            NoteProperty   bool PSIsContainer=False
<SNIP>

As we can see from the output, various extensions assist us in locating the certificate we seek. Extensions include details about the certificate, such as who it was granted to, what it can be used for, etc.

We’ll need to look for certificates with other extensions, such as the certificate template, utilized in more complex use cases. The problem is that these extensions’ values are returned as an array of integers, and these integers represent ASN.1 encoded content.

We’ll manually fetch the Key Usage in the command below to see this relationship.

((gci -Path Cert:\CurrentUser\Root\ | select -First 1).Extensions | Where-Object { $_.Oid.FriendlyName -eq "Key Usage" }).format($true)

The format method, which does the ASN.1 decoding, is the new piece we introduce in the above instruction. We specify whether we want the returned object to be single-line or multi-line by passing a Boolean value (e.g., $true) above.

In the command below, we’ll utilize the certificate’s Thumbprint value. The thumbprint value is set as a Windows PowerShell variable and used to pick the appropriate certification in the next commands.

$thumb = "cdd4eeae6000ac7f40c3802c171e30148030c072"
Get-ChildItem -Path Cert:\CurrentUser\Root\ | Where-Object { $_.Thumbprint -eq $thumb }
Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn