Filtering on the Certificate Provider

Tue, Jan 9, 2007 2-minute read

Well, after a long holiday break, the first thing on both of our minds, naturally, is filtering on the Certificate Provider.

A suggestion came up recently in an internal discussion list to add more dynamic parameters to Get-ChildItem when you’re in the certificate provider. For example, the –CodeSign parameter is extremely useful:

[cert:\]
PS:2 > dir -rec -codesign

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

Thumbprint                                Subject
----------                                -------
5D103CCDCFE0D96748A305DFACA9C942ABFD73E7  CN=PowerShell User

 

[cert:\]
PS:3 > $cert = dir -Recurse -CodeSign

[cert:\]
PS:4 > Set-AuthenticodeSignature c:\temp\MyScript.ps1 $cert

    Directory: C:\temp

SignerCertificate                         Status                                 Path
-----------------                         ------                                 ----
5D103CCDCFE0D96748A305DFACA9C942ABFD73E7  Valid                                  MyScript.ps1

But – what about other certificate types, such as “Encrypting File System” ? We don’t expose this as a dynamic parameter, although that would be a useful feature.

However, since the certificate provider returns certificates in all of the object-oriented glory, you can use the Get-Member cmdlet to explore what’s available to you. In this case, the “Intended purpose” of the certificate comes from a certificate extension. One of those certificate extensions is the “Enhanced Key Usage” (EKU) – which contains a list of identifiers such as “Client Authentication,” “Code Signing,” etc.

Here is a function that gets a certificate by its EKU:

## Get-CertificateByEku.ps1
param($ekuName = $(
    throw "Please specify the friendly name of an Enhanced Key Usage (such as 'Code Signing'"))
foreach($cert in Get-ChildItem cert:\CurrentUser\My) {
   foreach($extension in $cert.Extensions)
   {
       foreach($certEku in $extension.EnhancedKeyUsages)
       {
           if($certEku.FriendlyName -eq $ekuName)
           {
               $cert
           }
       }
   }
}

And some output:

[C:\Temp] PS:90 > C:\temp\Get-CertificateByEku.ps1 "Encrypting File System"

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

Thumbprint                                Subject
----------                                -------
22D5904D20754371582F72FA158625FEB85F1345  CN=Lee Holmes

If you do this a lot, you might think about adding this as a property to the certificate itself: http://www.leeholmes.com/blog/AddCustomMethodsAndPropertiesToTypesInPowerShell.aspx.