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 PSCertificateEnrollmentThe 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-NDESOTPGet-SCEPCertificateGet-KeyStorageProviderGet-IssuedCertificateNew-CertificateRequestNew-SignedCertificateRequestInstall-IssuedCertificateUndo-CertificateArchivalGet-RemoteDesktopCertificateSet-RemoteDesktopCertificateInvoke-AutoEnrollmentTaskGet-ESTCertificateGet-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:
EnrollmentAgentClientAuthenticationCodeSigningLifeTimeSigningDocumentSigningDocumentEncryptionEncryptingFileSystemFileRecoveryIPSecEndSystemIPSecIKEIntermediateIPSecTunnelEndpointIPSecUserKeyRecoveryKDCAuthenticationSecureEmailServerAuthenticationSmartCardLogonTimeStampingOCSPSigningRemoteDesktopAuthenticationPrivateKeyArchival
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,$cExample: 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,SmartcardLogonExample: 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 asciiExample: 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 asciiNew-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 $eacertGet-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 12345Install-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-IssuedCertificateGet-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 8443Note 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-IssuedCertificateGet-KeyStorageProvider enumerates all Cryptographic Service Providers (CSP) and Key Storage Providers (KSP) installed on the local machine.
Get-KeyStorageProvider | Select-Object -Property NameUndo-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-RemoteDesktopCertificateSet-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