Skip to content

Sleepw4lker/PSCertificateEnrollment

Repository files navigation

PSCertificateEnrollment

PowerShell Module for various PKI-related tasks like:

  • Creating Certificate Signing requests

  • Creating Self-Signed Certificates or Certificates signed with a given Key

  • Signing a Certificate Request with an Enrollment Agent Certificate prior to Submission to a Certification Authority

  • Submitting Certificate Requests to a Certification Authority via DCOM and WSTEP Protocols and retrieving the response

  • Installing issued Certificates after the Certificate Request has been approved by a Certificartion Authority

  • Requesting or Renewing User or Machine Certificates via the Simple Certificate Enrollment Protocol (SCEP)

  • Identifying and configuring the Remote Desktop Session Host Certificate of a machine

The module can be obtained via the PowerShell Gallery.

It is intended for Client-Side Tasks inside the Microsoft PKI Ecosystem. For managing a Microsoft Certification Authority, take a look at the awesome PSPKI Module.

It is built out of pure PowerShell Script Code (using .NET and Win32 API). No wrapping of any certutil or openssl command. No additional binary Code (e.g. a DLL etc.) necessary to deploy. The Module and it’s files are digitally signed when obtaining it from the PowerShell Gallery.

Supported Operating Systems

  • Windows 10 / Windows Server 2016,2019,2022

  • Windows 8.1 / Windows Server 2012 R2 (Windows PowerShell 5.1 must be installed)

Earlier Windows Version since Windows Vista/Server 2008 may work, but are not supported.

Get-NDESCertificate will definitely not work on Windows Operating Systems below 8.1/Server 2012 R2.

PowerShell Core and therefore Linux are also not supported, as the Win32 API is not available on these.

Supported Commands

The following Commands are available:

  • Get-NDESOTP

  • Get-NDESCertificate

  • Get-IssuedCertificate

  • New-CertificateRequest

  • New-SignedCertificateRequest

  • Install-IssuedCertificate

  • Get-KeyStorageProvider

  • Undo-CertificateArchival

  • Get-RemoteDesktopCertificate

  • Set-RemoteDesktopCertificate

Get-NDESOTP

Get-NDESOTP retrieves an One-Time-Password (OTP) from the NDES Server.

Uses SSL by default. SSL can be disabled if required, but this is not recommended.

Uses your Windows Identity by default but can also be passed a PSCredential Object (Get-Credential).

The -PasswordLength Parameter must be adjusted if you do not use the default 8-Character Passwords on the NDES (as it’s only RegEx grabbing the HTML Output).

Example: Retrieving a NDES One-Time Password

Get-NDESOTP `
-ComputerName 'ndes01.intra.adcslabor.de' `
-Credential $(Get-Credential)

Get-NDESCertificate

Get-NDESCertificate creates and submits an NDES Certificate Request using the IX509SCEPEnrollment Interface available in Windows 8.1 and higher, and retrieves the issued Certificate. The issued Certificate directly gets installed into the respective Certificate store.

It supports Renewal Mode by passing an X509Certificate Object either via the Pipeline or the -SigningCertificate Argument. The Certificate must have a private Key, and be issued from the same CA as the new one.

It supports SSL, but doesnt use it by default (not necessary as sensitive Data is protected anyway).

It supports the following Server-side Implementations of the SCEP protocol:

  • Microsoft Network Device Enrollment Service (NDES)

Other SCEP Implementations should be easy to implement but I currently have none to test against.

Example: Performing a SCEP Certificate Request using a previously-obtained Challenge Request

Get-NDESCertificate `
-ComputerName "ndes01.intra.adcslabor.de" `
-Subject "CN=Test" `
-ChallengePassword "BDE00774A789610F"

Example: Performing a SCEP Renewal Request (renewing an existing Certificate via SCEP)

Get-ChildItem -Path Cert:\CurrentUser\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 |
Get-NDESCertificate -ComputerName "ndes01.intra.adcslabor.de"

New-CertificateRequest

New-CertificateRequest builds a Certificate Signing Request (CSR) based on the given Arguments. Can also create self-signed Certificates as well as directly sign the request with a Certificate (to be precise, it’s private Key). For example, you could specify a Certification Authority Certificate as the Signer.

You can specify the following Enhanced Key Usages (EKUs) by their friendly name:

  • EnrollmentAgent

  • ClientAuthentication

  • CodeSigning

  • LifeTimeSigning

  • DocumentSigning

  • DocumentEncryption

  • EncryptingFileSystem

  • FileRecovery

  • IPSecEndSystem

  • IPSecIKEIntermediate

  • IPSecTunnelEndpoint

  • IPSecUser

  • KeyRecovery

  • KDCAuthentication

  • SecureEmail

  • ServerAuthentication

  • SmartCardLogon

  • TimeStamping

  • OCSPSigning

  • RemoteDesktopAuthentication

  • PrivateKeyArchival

(Note that usually, it is not necessary to specify an EKU in a CSR, as this will be overwritten by the Microsoft Certification Authority due to Certificate Template Settings).

Example: Creating a PKI Hierarchy in a 3-Liner

$a = New-CertificateRequest -CA -Subject "CN=Root CA" -SelfSign
$b = New-CertificateRequest -CA -Subject "CN=Sub CA" -SigningCert $a -PathLength 0
$c = New-CertificateRequest -Eku "ServerAuthentication" -Subject "CN=www.demo.org" -Dns "www.demo.org" -SigningCert $b
$a,$b,$c

Example: Demonstrating a Path length Constraint violation

$a = New-CertificateRequest -CA -Subject "CN=Root CA" -SelfSign
$b = New-CertificateRequest -CA -Subject "CN=Sub CA" -SigningCert $a -PathLength 0
$c = New-CertificateRequest -CA -Subject "CN=Invalid Path Length CA" -SigningCert $b
$d = New-CertificateRequest -Eku "ServerAuthentication" -Subject "CN=Invalid Path Length Certificate" -Dns "www.demo.org" -SigningCert $c
$a,$b,$c,$d

Example: Demonstrating an EKU Constraint violation

$a = New-CertificateRequest -CA -Subject "CN=Root CA" -SelfSign
$b = New-CertificateRequest -CA -Eku "ClientAuthentication" -Subject "CN=Sub CA 1" -SigningCert $a
$c = New-CertificateRequest -Eku "ServerAuthentication" -Subject "CN=Invalid EKU Certificate" -Dns "www.demo.org" -SigningCert $b
$a,$b,$c

Example: Creating a Certificate Signing Request (CSR) for a Domain Controller Certificate using a 3072 Bit RSA Key

New-CertificateRequest `
-MachineContext `
-LeyLength 3072 `
-Subject "CN=dc01.intra.adcslabor.de" `
-Dns "dc01.intra.adcslabor.de","intra.adcslabor.de","INTRA" `
-Eku KDCAuthentication,ServerAuthentication,ClientAuthentication,SmartcardLogon

Example: Creating a Certificate Signing Request (CSR) for a Web Server Certificate, using an ECDSA Key, containing multiple SANs of Type DnsName and IPAdress (and an empty Subject String)

New-CertificateRequest `
-Eku ServerAuth `
-Dns "web1.fabrikam.com","web2.fabrikam.com","web3.fabrikam.com" `
-IP "192.168.0.1" `
-KeyAlgorithm ECDSA_P256 |
Out-File CertificateRequestFile.csr -Encoding ascii

Example: Creating a Certificate Signing Request (CSR) for an OCSP Responder, specifying the signing CA Certificate to be used via Authority Key Identifier (AKI) and a Hardware Security Module (HSM) Key Storage Provider (KSP)

New-CertificateRequest `
-Subject "CN=My-Responder" `
-Ksp "nCipher Security World Key Storage Provider" `
-Eku "OCSPSigning" `
-Aki "060DDD83737C311EDA5E5B677D8C4D663ED5C5BF" `
-KeyLength 4096 |
Out-File CertificateRequestFile.csr -Encoding ascii

New-SignedCertificateRequest

New-SignedCertificateRequest appends a Signature to a PKCS#10 Certificate Request. Can also append the RequesterName Attribute for Enroll on Behalf of (EOBO) processes.

Example: Signing a previously created Certificate Signing Request

$csr = New-CertificateRequest -Subject "CN=Test"
$eacert = Get-ChildItem -Path Cert:\CurrentUser\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2
$csr | New-SignedCertificateRequest -SigningCert $eacert

Get-IssuedCertificate

Get-IssuedCertificate allows for Submission of a Certificate Request to a Certification Authority. It also allows for retrieval of a previously issued Certificate from a Certification Authority.

Example: Creating a Certificate Request and submitting it to a Certification Authority

$csr = New-CertificateRequest -Subject "CN=Test"
$csr | Get-IssuedCertificate `
-ConfigString "ca02.intra.adcslabor.de\ADCS Labor Issuing CA 1" `
-CertificateTemplate "ADCSLaborUser"

Example: Creating a Certificate Request and submitting it to a Certification Authority via WSTEP (aka Certificate Enrollment Web Service, CES) using Username and Password Authentication

$csr = New-CertificateRequest -Subject "CN=Test"
$csr | Get-IssuedCertificate `
-ConfigString "https://ces01.intra.adcslabor.de/ADCS%20Labor%20Issuing%&20CA%201_CES_UsernamePassword/service.svc/CES" `
-CertificateTemplate "ADCSLaborUser" `
-Credential (Get-Credential)

Example: Retrieving an issued Certificate for a previously submitted Certificate request

Get-IssuedCertificate `
-ConfigString "ca02.intra.adcslabor.de\ADCS Labor Issuing CA 1" `
-RequestId 12345

Install-IssuedCertificate

Install-IssuedCertificate allows for installing a Certificate onto the local Machine after the correspoiding certificate Request was approved by a Certification Authority.

Example: Creating a Certificate Request, submitting it to a Certification Authority and installing the response

$csr = New-CertificateRequest -Subject "CN=Test"
$response = $csr | Get-IssuedCertificate `
-ConfigString "ca02.intra.adcslabor.de\ADCS Labor Issuing CA 1" `
-CertificateTemplate "ADCSLaborUser"
$response.Certificate | Install-IssuedCertificate

Get-KeyStorageProvider

Get-KeyStorageProvider enumerates all Cryptographic Service Providers (CSP) and Key Storage Providers (KSP) installed on the local machine.

Example: List all CSPs and KSPs available on the machine

Get-KeyStorageProvider | Select-Object -Property Name

Undo-CertificateArchival

Undo-CertificateArchival allows for un-archiving a previously archived Certificate.

Example: Unarchive an archived Certificate, identified by it’s SHA-1 Thumbprint

Undo-CertificateArchival `
-Thumbprint 85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 `
-CertStoreLocation Cert:\CurrentUser\My\

Get-RemoteDesktopCertificate

Get-RemoteDesktopCertificate gets the currently configured Certificate for the Remote Desktop Session Host on the local System.

Example: Retrieving the currently configured Remote Desktop Certificate

Get-RemoteDesktopCertificate

Set-RemoteDesktopCertificate

Set-RemoteDesktopCertificate sets the Certificate for the Remote Desktop Session Host on the local System. Can be combined with Get-NDESCertificate or Install-IssuedCertificate.

Example: Choosing and setting a Remote Desktop Certificate

Get-ChildItem -Path Cert:\LocalMachine\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 |
Set-RemoteDesktopCertificate