I'm glad to announce that another build of my PowerShell PKI module is released! This release introduces new vision of the module evolution. Since now, it is not only a set of PowerShell commands, but the set of .NET APIs that can be used to extend existing commands. Let's go with details.

Breaking changes

Due to the fact that Windows PKI team decided to name their own module in Windows Server 8 exactly as my module, I was forced to rename it. This is very disappointing thing. Now the module is named PSPKI. On the other side, PKI was too generic name and new name exposes usage area (PowerShell or simply PS).

Installation experience

Previously I've used a private signing certificate (issued by one of my internal CAs) to sign module files. Now I switched it to a certificate issued by common trusted CA (DigiCert).

During module packing, I've noticed very cool feature in Advanced Installer, that allows me to configure advanced product upgrade, so I can uninstall old PKI module and install new PSPKI one. So you can upgrade existing product with different name with new product name.

New commands

A time ago I promised to implement cmdlets that could be used to modify certificate template ACL. And here they are:

The scheme is very similar to other. At first you retrieve certificate template object and pipe it to the Get-CertificateTemplateAcl, which extracts template ACL. Output object is a wrapper for ActiveDirectorySecurity class:

PS C:\> Get-CertificateTemplate -Name webserver | Get-CertificateTemplateAcl

Path                                    Owner                                   Access
----                                    -----                                   ------
LDAP://CN=WebServer,CN=Certificate T... SYSADMINS\Enterprise Admins             {PKI.Security.AccessControlEntry, PK...

PS C:\> (Get-CertificateTemplate -Name webserver | Get-CertificateTemplateAcl).access

IdentityReference                                                    AccessType Permissions
-----------------                                                    ---------- -----------
NT AUTHORITY\Authenticated Users                                          Allow {Read}
SYSADMINS\Domain Admins                                                   Allow {Read, Write, Enroll}
SYSADMINS\Enterprise Admins                                               Allow {Read, Write, Enroll}
SYSADMINS\Web Servers-G                                                   Allow {Read, Enroll}

I've decided to remove unnecessary fields to provide only most used fields and improve user experience with a little subset of permissions. You can easily compare this output with the native .NET output by running the commands:

$template = Get-CertificateTemplate -Name webserver

Once existing ACL is retrieved you can modify it by using either Add-CertificateTemplateAcl  or Remove-CertificateTemplateAcl cmdlet. And finally, use Set-CertificateTemplateAcl to write modified ACL back to the original template object. I think, it is pretty easy.

Also I revisited Test-WebServerSSL script to integrate it with the module and added to the package.

Code redesign

While module covers only regular or common PKI tasks, I needed some non-standard features. For example, a year ago I wrote a PowerShell script that converts CRLs to a .NET like object (see: http://www.sysadmins.lv/PermaLink,guid,4ffce88a-e3f0-4dac-8e3f-4af7ba53f4f3.aspx). While it works as expected, it can be very slow on big CRL (and several common CAs have large CRLs, 100kb+). Also it misses really useful methods. For example, you may need to verify whether the CRL was signed by the particular CA certificate. Or to know, whether the particular certificate is listed in CRL and so on.

It is almost impossible to solve all these tasks with regular PowerShell scripts, because it will require too many commands and it breaks code re-use, because large code blocks needs to be used in the various commands and PowerShell native performance is not so fast. I've decided to learn C# programming language and present common objects as a .NET classes and wrap them to PowerShell scripts as necessary.

At first, I moved all CryptoAPI (unmanaged) stuff to C# code. Mainly this includes CRL objects, CSPs. You can view. In addition I developed a set of generic classes and methods. You can use Add-Type cmdlet to view exposed classes:

[↓] [vPodans] Add-Type -Path $PSHome\Modules\PSPKI\PKI.Core.dll -PassThru | sort name -Descending

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     X509EncodingType                         System.Enum
True     False    X509CRLEntryCollectionEnumerator         System.Object
True     False    X509CRLEntryCollection                   System.Object
True     False    X509CRLEntry                             System.Object
True     False    X509CRL2                                 System.Object
True     False    Wincrypt                                 System.Object
True     False    WebSSL                                   System.Object
True     True     TemplateRight                            System.Enum
False    False    SystemTime                               System.ValueType
True     False    Shift                                    System.Object
True     False    SecurityDescriptor                       System.Object
True     False    Schema                                   System.Object
True     False    RequestRow                               System.Object
False    False    PROV_ENUMALGS_EX                         System.ValueType
False    False    OSVersion                                System.Object
True     False    OCSPSingleResponseCollectionEnumerator   System.Object
True     False    OCSPSingleResponseCollection             System.Object
True     False    OCSPSingleResponse                       System.Object
True     True     OCSPResponseType                         System.Enum
True     True     OCSPResponseStatus                       System.Enum
True     True     OCSPResponseComplianceError              System.Enum
True     False    OCSPResponse                             System.Object
True     False    OCSPRequest                              System.Object
False    False    NCryptProviderName                       System.ValueType
False    False    NCryptAlgorithmName                      System.ValueType
True     False    nCrypt                                   System.Object
True     False    MessageSignature                         System.Object
True     False    KRAFlag                                  System.Object
True     False    KRA                                      System.Object
True     False    Kernel32                                 System.Object
True     False    InterfaceFlag                            System.Object
False    False    GenericArray                             System.Object
True     False    ExtensionList                            System.Object
True     False    Error                                    System.Object
True     False    EditFlag                                 System.Object

Note: library is compiled against .NET 2.0, so there are no additional requirements for module installation.

In next posts I'll talk about additional functionality that is available outside the PowerShell cmdlets/commands, but exist in the module package.

Extend your <whatever you want> with the power of Windows PowerShell!

Download PowerShell PKI Module v1.5 now!

Share this article:


Johann Zandanel


Post your comment:

Please, solve this little equation and enter result below. Captcha