Skip to content

Instantly share code, notes, and snippets.

@joshooaj
Last active July 8, 2025 22:55
Show Gist options
  • Save joshooaj/3ca6b5677104f36440185cdb9cb37486 to your computer and use it in GitHub Desktop.
Save joshooaj/3ca6b5677104f36440185cdb9cb37486 to your computer and use it in GitHub Desktop.
Example of generating self-signed certificates signed by a self-signed root certificate
# Generate a self-signed certificate to use as a root certificate
$rootParams = @{
# Subject can be any valid X.500 distinguished name
Subject = 'CN=MyRootCA'
# The key may only be used for signing certificates
KeyUsage = 'CertSign'
# FriendlyName is optional but useful for identifying the cert in a list
FriendlyName = 'My Root CA'
# Save certificate and private key in the "Local Computer\Personal" store
CertStoreLocation = 'Cert:\LocalMachine\My'
# Root certificates are often valid for 10-20 years
NotAfter = (Get-Date).AddYears(10)
# Options: 'NonExportable', 'ExportableEncrypted', or 'Exportable'
KeyExportPolicy = 'NonExportable'
}
$root = New-SelfSignedCertificate @rootParams
$certParams = @{
# Sign the certificate with the root CA generated above
Signer = $root
# Use the current machine hostname as the subject/DnsName
# Note: You may enter multiple DnsNames if needed.
DnsName = hostname
FriendlyName = 'vms-1 Self-signed Certificate'
CertStoreLocation = 'Cert:\LocalMachine\My\'
NotAfter = (Get-Date).AddYears(1)
# Options: 'NonExportable', 'ExportableEncrypted', or 'Exportable'
KeyExportPolicy = 'NonExportable'
}
$vms1Cert = New-SelfSignedCertificate @certParams
$certParams = @{
# Sign the certificate with the root CA generated above
Signer = $root
# Use the current machine hostname as the subject/DnsName
# Note: You may enter multiple DnsNames if needed.
DnsName = 'vms-2'
FriendlyName = 'vms-2 Self-signed Certificate'
NotAfter = (Get-Date).AddYears(1)
# Options: 'NonExportable', 'ExportableEncrypted', or 'Exportable'
KeyExportPolicy = 'ExportableEncrypted'
}
$vms2Cert = New-SelfSignedCertificate @certParams
# Export the root certificate (without the private key) to a file
$bytes = $root.Export('cert')
$path = Join-Path (Resolve-Path ~\Downloads) 'myrootca.cer'
[io.file]::WriteAllBytes($path, $bytes)
# Import the root certificate into the trusted root cert store
Import-Certificate -FilePath $path -CertStoreLocation Cert:\LocalMachine\Root\
# Export the certificate for vms-2 (with the private key) to a file
$bytes = $vms2Cert.Export('pfx', (Read-Host -Prompt 'Enter password to protect private key' -AsSecureString))
$path = Join-Path (Resolve-Path ~\Downloads) 'vms-2.pfx'
[io.file]::WriteAllBytes($path, $bytes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment