PowerShell Module for various PKI-related tasks like:
- Creating Certificate Signing requests
- Creating Self-Signed Certificates or Certificates signed with a given Key
- Requesting or Renewing User or Machine Certificates via one of the following protocols:
- Signing a Certificate Request with an Enrollment Agent Certificate prior to Submission to a Certification Authority
- Installing issued Certificates after the Certificate Request has been approved by a Certification Authority
- Identifying and configuring the Remote Desktop Session Host Certificate of a machine
It is (mainly) intended for Client-Side Tasks inside the Microsoft PKI Ecosystem and is built out of pure PowerShell Script Code (using .NET and Win32 API). No wrapping of any certutil
or openssl
commands. No additional binary Code (e.g. a DLL etc.) necessary to deploy. I mainly use the module for testing PKI protocol implementations as well as certificate authority deployments.
PSCertificateenrollment can also be used as a Penetration testing tool, e.g. for deployments using Microsoft Network Device Enrollment Service (NDES) or to directly sign certificates bypassing the certification authority service.
For securing a Microsoft Certification Authority, take a look at the Tame My Certs policy module for Active Directory Certificate Services.
For managing a Microsoft Certification Authority, take a look at the awesome PSPKI Module.
The module can easily be installed via the PowerShell Gallery.
Install-Module -Name PSCertificateEnrollment
The Module and it's files are digitally signed when obtaining it from the PowerShell Gallery.
- Windows 11 / Windows Server 2022,2025
- Windows 10 / Windows Server 2016,2019
- 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-SCEPCertificate
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.
The following Commands are available:
Get-NDESOTP
Get-SCEPCertificate
Get-KeyStorageProvider
Get-IssuedCertificate
New-CertificateRequest
New-SignedCertificateRequest
Install-IssuedCertificate
Undo-CertificateArchival
Get-RemoteDesktopCertificate
Set-RemoteDesktopCertificate
Invoke-AutoEnrollmentTask
Get-ESTCertificate
Get-ESTCACertificates
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).
$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
$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
$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.mydomain.local" -Dns "dc01.mydomain.local","mydomain.local", "MYDOMAIN" -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.mydomain.local","web2.mydomain.local","web3.mydomain.local" -IP "192.168.0.1" -KeyAlgorithm ECDSA_P256 | Out-File -Path 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
appends a Signature to a PKCS#10 Certificate Request. Can also append the RequesterName Attribute for Enroll on Behalf of (EOBO) processes.
$csr = New-CertificateRequest -Subject "CN=Test"
$eacert = Get-ChildItem -Path Cert:\CurrentUser\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2
$csr | New-SignedCertificateRequest -SigningCert $eacert
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.
$csr = New-CertificateRequest -Subject "CN=Test"
$csr | Get-IssuedCertificate -ConfigString "ca01.mydomain.local\My Enterprise CA" -CertificateTemplate "UserTemplate"
Example: Creating a Certificate Request and submitting it to a Certification Authority via MS-WSTEP using Kerberos Authentication
$csr = New-CertificateRequest -Subject "CN=Test"
$csr | Get-IssuedCertificate -ConfigString "https://wstep1ca01.wstep1.local/My%20Enterprise%20CA%201_CES_Kerberos/service.svc/CES" -CertificateTemplate "UserTemplate"
Example: Creating a Certificate Request and submitting it to a Certification Authority via WSTEP using Username and Password Authentication
$csr = New-CertificateRequest -Subject "CN=Test"
$csr | Get-IssuedCertificate -ConfigString "https://ces01.mydomain.local/My%20Enterprise%20CA%201_CES_UsernamePassword/service.svc/CES" -CertificateTemplate "UserTemplate" -Credential (Get-Credential)
Get-IssuedCertificate -ConfigString "ca01.mydomain.local\My Enterprise CA" -RequestId 12345
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 "ca01.mydomain.local\" -CertificateTemplate "UserTemplate"
$response.Certificate | Install-IssuedCertificate
Get-SCEPCertificate
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 on protocol-level).
It should work with any server-side SCEP implementation, but was explicitly tested with:
Get-SCEPCertificate -ComputerName "ndes01.mydomain.local" -Subject "CN=Test" -ChallengePassword "BDE00774A789610F"
Get-ChildItem -Path Cert:\CurrentUser\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 |
Get-SCEPCertificate -ComputerName "ndes01.mydomain.local"
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 server (as it’s only RegEx grabbing the HTML Output).
Get-NDESOTP -ComputerName "ndes01.mydomain.local" -Credential $(Get-Credential)
Note that for this service, it is necessary to establish trust relationship to the Root CA as described on their landing page. Use at your won risk.
Get-ESTCACertificates -ComputerName "testrfc7030.com" -Port 8443
Note that for this service, it is necessary to establish trust relationship to the Root CA as described on their landing page. Use at your won risk.
$csr = New-CertificateRequest -Subject "CN=Test"
$cert = $csr | Get-ESTCertificate -ComputerName "testrfc7030.com" -Port 8443 -Username "estuser" -Password "estpwd"
$cert | Install-IssuedCertificate
Get-KeyStorageProvider
enumerates all Cryptographic Service Providers (CSP) and Key Storage Providers (KSP) installed on the local machine.
Get-KeyStorageProvider | Select-Object -Property Name
Undo-CertificateArchival
allows for un-archiving a previously archived Certificate.
Undo-CertificateArchival -Thumbprint 85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 -CertStoreLocation Cert:\CurrentUser\My\
Get-RemoteDesktopCertificate
gets the currently configured Certificate for the Remote Desktop Session Host on the local System.
Get-RemoteDesktopCertificate
Set-RemoteDesktopCertificate
sets the Certificate for the Remote Desktop Session Host on the local System. Can be combined with Get-SCEPCertificate
, Get-ESTCertificate
or Install-IssuedCertificate
.
Get-ChildItem -Path Cert:\LocalMachine\My\85CF977C7E32CE808E9D92C61FDB9A43437DC4A2 |
Set-RemoteDesktopCertificate