CERTIFICATE WORKSHOP / WINDOWS · 7 MIN READ
Create and Export Certificates with PowerShell.
Use Windows’ certificate store when the private key already belongs to Windows. Use the OpenSSL workflow when your inputs are separate PEM files.
Windows examples. These use the Windows PKI module and certreq.exe, not PowerShell alone on Linux or macOS. Use a protected working folder, replace example names with names you control, and check that output files do not already exist. No command here uploads your key or creates public trust.
Check the Required Commands
Get-Command New-SelfSignedCertificate, Export-PfxCertificate, Get-PfxDataThe examples use Cert:\CurrentUser\My so you do not need to alter the machine-wide store for a lab. Production services may need a machine-store certificate and explicit private-key permissions; follow that service’s deployment instructions.
Create a Short-lived Lab Certificate
$certOptions = @{
DnsName = 'lab.aboutssl.info'
CertStoreLocation = 'Cert:\CurrentUser\My'
Type = 'SSLServerAuthentication'
KeyAlgorithm = 'RSA'
KeyLength = 3072
HashAlgorithm = 'SHA256'
KeyExportPolicy = 'Exportable'
NotAfter = (Get-Date).AddDays(30)
}
$tlsCert = New-SelfSignedCertificate @certOptions
$tlsCert | Format-List Subject, Thumbprint, NotAfter, HasPrivateKeyThis creates a new exportable RSA key and a self-signed certificate for a lab. It does not make that name trusted or establish control of its DNS. Exportability is intentional for this PFX exercise; non-exportable production keys may be preferable when the service supports them.
Export the Lab Certificate
$pfxPassword = Read-Host 'Password for the PFX' -AsSecureString
$exportOptions = @{
Cert = $tlsCert
FilePath = '.\lab.aboutssl.info.pfx'
Password = $pfxPassword
ChainOption = 'BuildChain'
CryptoAlgorithmOption = 'AES256_SHA256'
NoClobber = $true
}
Export-PfxCertificate @exportOptionsThe password is entered as a SecureString, not as a literal in your history. -NoClobber prevents replacing an existing PFX. A self-signed leaf does not magically acquire a public CA chain when exported.
Request a CA-signed Certificate with certreq
The following creates a CSR and an associated key in the current user context. Keep the same user and machine for accepting the CA response. The CA must validate the request and issue the certificate; creating a CSR alone is not issuance.
$requestConfig = @'
[Version]
Signature="$Windows NT$"
[NewRequest]
Subject = "CN=aboutssl.info"
KeyAlgorithm = RSA
KeyLength = 3072
HashAlgorithm = SHA256
ProviderName = "Microsoft Software Key Storage Provider"
MachineKeySet = FALSE
Exportable = TRUE
RequestType = PKCS10
KeyUsage = 0xa0
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "DNS=aboutssl.info&"
_continue_ = "DNS=www.aboutssl.info"
[EnhancedKeyUsageExtension]
OID = 1.3.6.1.5.5.7.3.1
'@
Set-Content -LiteralPath .\aboutssl.inf -Value $requestConfig -Encoding ascii
certreq.exe -user -new .\aboutssl.inf .\aboutssl.csr
if ($LASTEXITCODE -ne 0) { throw 'CSR creation failed.' }Inspect the CSR and send only that request through your CA’s approved process. Do not send your private key. Save its signed response as aboutssl-issued.cer, then accept it under the same user:
certreq.exe -user -accept .\aboutssl-issued.cer
if ($LASTEXITCODE -ne 0) { throw 'Certificate acceptance failed.' }Ensure the correct intermediate certificates are available to Windows from an authenticated CA source. Do not solve chain errors by blindly placing unknown roots into a trusted root store.
Export One Existing Certificate and Its Chain
List the certificates and select the exact thumbprint. Do not export the entire personal store:
Get-ChildItem Cert:\CurrentUser\My |
Format-List Subject, Thumbprint, NotAfter, HasPrivateKey$thumbprint = (Read-Host 'Thumbprint of the one certificate to export').Replace(' ', '')
$tlsCert = Get-Item -LiteralPath ('Cert:\CurrentUser\My\' + $thumbprint)
if (-not $tlsCert.HasPrivateKey) { throw 'This certificate has no associated private key.' }
$pfxPassword = Read-Host 'Password for the PFX' -AsSecureString
$exportOptions = @{
Cert = $tlsCert
FilePath = '.\aboutssl.info.pfx'
Password = $pfxPassword
ChainOption = 'BuildChain'
CryptoAlgorithmOption = 'AES256_SHA256'
NoClobber = $true
}
Export-PfxCertificate @exportOptionsBuildChain includes the chain Windows can construct. Missing CA certificates, missing keys and non-exportable keys can prevent the intended export. A certificate file imported without its original key is not enough.
Read Back the PFX
$pfxPassword = Read-Host 'Password for the PFX' -AsSecureString
$pfxData = Get-PfxData -FilePath .\aboutssl.info.pfx -Password $pfxPassword
$pfxData.EndEntityCertificates | Format-List Subject, Issuer, NotAfter
$pfxData.OtherCertificates | Format-List Subject, Issuer, NotAfterReview the leaf and other certificates before deployment. An import-compatible file is not proof that your service is using it. Check the binding, service identity permissions and the public TLS result afterward.
For separate certificate, key and chain PEM files, follow Build the Complete PFX. Those OpenSSL commands can also be run from PowerShell; do not assume that Export-PfxCertificate merges arbitrary PEM files.