|
function New-SelfSignedRootCertificate { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string] $Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[string] $CertStoreLocation, |
|
|
|
[Parameter()] |
|
[datetime] $NotAfter = (Get-Date).AddYears(50) |
|
) |
|
|
|
$cert = New-SelfSignedCertificate ` |
|
-Subject "$Name Certificate Authority" ` |
|
-FriendlyName "$Name Certificate Authority" ` |
|
-CertStoreLocation $CertStoreLocation ` |
|
-KeyUsage KeyEncipherment, DataEncipherment, CertSign ` |
|
-KeyUsageProperty Sign ` |
|
-HashAlgorithm SHA256 ` |
|
-KeyLength 4096 ` |
|
-TextExtension @("2.5.29.19 ={critical}{text}CA=1&pathlength=3") ` |
|
-NotAfter $NotAfter |
|
|
|
Get-Item "Cert:\LocalMachine\CA\$($cert.Thumbprint)" | Move-Item -Destination Cert:\LocalMachine\Root -ErrorAction Stop | Out-Null |
|
|
|
Write-Output $cert |
|
} |
|
|
|
function New-SelfSignedIntermediateCertificate { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string] $Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[string] $CertStoreLocation, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[System.Security.Cryptography.X509Certificates.X509Certificate2] $SigningCertificate, |
|
|
|
[Parameter()] |
|
[datetime] $NotAfter = (Get-Date).AddYears(25) |
|
) |
|
|
|
$cert = New-SelfSignedCertificate ` |
|
-Subject "$Name Intermediate Authority" ` |
|
-FriendlyName "$Name Intermediate Authority" ` |
|
-CertStoreLocation $CertStoreLocation ` |
|
-Signer $SigningCertificate ` |
|
-KeyUsage KeyEncipherment, DataEncipherment, CertSign ` |
|
-KeyUsageProperty Sign ` |
|
-HashAlgorithm SHA256 ` |
|
-KeyLength 4096 ` |
|
-TextExtension @("2.5.29.19 ={critical}{text}CA=1&pathlength=0") ` |
|
-NotAfter $NotAfter |
|
|
|
Write-Output $cert |
|
} |
|
|
|
function Install-SelfSignedDevelopmentCertificateAuthority { |
|
[CmdletBinding()] |
|
param( |
|
[Parameter(Mandatory = $true)] |
|
[string]$Name, |
|
|
|
[Parameter(Mandatory = $true)] |
|
[securestring]$PrivateKeyPassword, |
|
|
|
[Parameter()] |
|
[switch]$NoEndEntityCertificate |
|
) |
|
|
|
$root = New-SelfSignedRootCertificate -Name $Name -CertStoreLocation Cert:\LocalMachine\My |
|
Write-Host "Root Certificate = Cert:\LocalMachine\Root\$($root.Thumbprint)" -ForegroundColor Cyan |
|
|
|
$intermediate = New-SelfSignedIntermediateCertificate -Name $Name -CertStoreLocation Cert:\LocalMachine\My -SigningCertificate $root |
|
Write-Host "Intermediate Certificate = Cert:\LocalMachine\CA\$($intermediate.Thumbprint)" -ForegroundColor Cyan |
|
|
|
if (-not $NoEndEntityCertificate) { |
|
$edge = New-SelfSignedCertificate ` |
|
-CertStoreLocation Cert:\LocalMachine\My ` |
|
-DnsName "localhost", $env:COMPUTERNAME ` |
|
-NotAfter (Get-Date).AddYears(5) ` |
|
-FriendlyName "Local Development Certificate" ` |
|
-Signer $intermediate |
|
|
|
Write-Host "End Entity Certificate = Cert:\LocalMachine\My\$($edge.Thumbprint)" -ForegroundColor Cyan |
|
} |
|
|
|
$keydir = "$env:USERPROFILE\.$($name.ToLower() -replace ' ')" |
|
if (-not (Test-Path $keydir)) { mkdir $keydir | Out-Null } |
|
|
|
|
|
Write-Host -NoNewline "Exporting key material to '$keydir'..." |
|
@($intermediate, $root) | ForEach-Object { |
|
Export-PfxCertificate -Cert $_ -FilePath "$keydir\$($_.Subject -replace 'CN=','').pfx" -Password $PrivateKeyPassword | Out-Null |
|
Remove-Item $_.PSPath -DeleteKey | Out-Null |
|
} |
|
Write-Host Done! |
|
} |
|
|
|
|
|
# WIP |
|
# function Uninstall-SelfSignedDevelopmentCertificateAuthority { |
|
# [CmdletBinding()] |
|
# param( |
|
# [Parameter(Mandatory = $true)] |
|
# [string]$Name |
|
# ) |
|
|
|
# $root = Get-ChildItem Cert:\LocalMachine\ -Recurse -DnsName "$Name Certificate Authority" |
|
|
|
# $intermediate = Get-ChildItem Cert:\LocalMachine -Recurse | Where-Object Issuer -eq $root[0].Subject |
|
|
|
# $edge = Get-ChildItem Cert:\LocalMachine\My, Cert:\CurrentUser\My ` |
|
# | Where-Object Issuer -eq $intermediate[0].Subject |
|
|
|
# $edge + $intermediate + $root | ForEach-Object { Write-Verbose "Removing $($_.PSPath)" | Remove-Item $_ } |
|
# } |
|
|
|
|
|
Export-ModuleMember -Function * |
Thanks for your response. I'm using windows 11 and, getting a blank screen when I run your .psm1 module with Powershell. Are you able to set up default values for everyone who wants to use it for iis, or apache, or any other platforms? My goal is to create one self-signed certificate for multiple localhost domains without OpenSSL, mkcert, or any other 3rd party.
ex: "localhost","dev.volkankaban","app.volkankaban","dev.leads","dev.members","127.0.0.1","::1"
I created another gist, and modified your current module. https://gist.github.com/volkankaban/16863cba8545eea6d2ec3b1f465e7f13