Private/Export-CertPfx.ps1
function Export-CertPfx { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [string]$CertFile, [Parameter(Mandatory,Position=1)] [string]$KeyFile, [Parameter(Mandatory,Position=2)] [string]$OutputFile, [string]$ChainFile, [string]$FriendlyName='', [string]$PfxPass='' ) $CertFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($CertFile) $KeyFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($KeyFile) $OutputFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFile) $ChainFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($ChainFile) # read in the files as native BouncyCastle objects $key = Import-Pem $KeyFile # [Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair] $cert = Import-Pem $CertFile # [Org.BouncyCastle.X509.X509Certificate] # create a new Pkcs12Store $store = New-Object Org.BouncyCastle.Pkcs.Pkcs12Store # add the private key $store.SetKeyEntry($FriendlyName, $key.Private, @($cert)) # add the chain certs if specified if ('ChainFile' -in $PSBoundParameters.Keys) { $pems = @(Split-PemChain $ChainFile) foreach ($pem in $pems) { $ca = Import-Pem -InputString ($pem -join '') # try to parse the subject to use as the alias if ($ca.SubjectDN -match "CN=([^,]+)") { $caName = $matches[1] } else { $caName = $ca.SerialNumber } $store.SetCertificateEntry($caName, $ca) } } # save it $sRandom = New-Object Org.BouncyCastle.Security.SecureRandom try { $fs = New-Object IO.FileStream($OutputFile,'Create') $store.Save($fs, $PfxPass, $sRandom) } finally { if ($fs -ne $null) { $fs.Close() } } } |