Author Posts

January 30, 2017 at 10:52 pm

Hi Everyone,

I'm trying to write a PowerShell script to export/import SSL certificates. I've two questions/issues around it :

Export :

 QUESTION IS--> Although it is exporting fine,how come i make sure to include password in it ?

CODE IS BELOW :
==========

Import-Module -Name WebAdministration

Get-ChildItem -Path IIS:SSLBindings | ForEach-Object -Process `
{
    if ($_.Sites)
    {
        $certificate = Get-ChildItem -Path CERT:LocalMachine/My |
            Where-Object -Property Thumbprint -EQ -Value $_.Thumbprint

        [PsCustomObject]@{
            Sites                        = $_.Sites.Value
            CertificateFriendlyName      = $certificate.FriendlyName
            CertificateDnsNameList       = $certificate.DnsNameList
            CertificateNotAfter          = $certificate.NotAfter
            CertificateIssuer            = $certificate.Issuer
        }
    }
    dir cert:\localmachine\my | Where-Object { $_.hasPrivateKey } |   Foreach-Object { [system.IO.file]::WriteAllBytes("c:\$($_.Subject).pfx",($_.Export('PFX', 'secret')) ) }
}

IMPORT :

Question2:  The code is below which is giving me this error :

Cannot find an overload for "Import" and the argument count: "2".
At line:11 char:1
+ $pfx.Import($CertPath,"Exportable,PersistKeySet")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest
 
Exception calling "Add" with "1" argument(s): "pCertContext is an invalid handle."
At line:14 char:1
+ $store.Add($pfx)
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CryptographicException

IMPORT CODE IS BELOW :

$CertPath = 'c:\Test.pfx'
$SiteName = "DefaultAPP"
$HostName = "localhost"
$SiteFolder = Join-Path -Path 'C:\inetpub\wwwroot' -ChildPath $SiteName


Write-Host 'Import pfx certificate' $certPath
$certRootStore = “LocalMachine”
$certStore = "My"
$pfx = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$pfx.Import($CertPath,"Exportable,PersistKeySet") 
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($certStore,$certRootStore) 
$store.Open('ReadWrite')
$store.Add($pfx) 
$store.Close() 
$certThumbprint = $pfx.Thumbprint


Write-Host 'Add website' $SiteName
New-WebSite -Name $SiteName -PhysicalPath $SiteFolder -Force
$IISSite = "IIS:\Sites\$SiteName"
Set-ItemProperty $IISSite -name  Bindings -value @{protocol="https";bindingInformation="*:443:$HostName"}
if($applicationPool) { Set-ItemProperty $IISSite -name  ApplicationPool -value $applicationPool}


Write-Host 'Bind certificate with Thumbprint' $certThumbprint
$obj = get-webconfiguration "//sites/site[@name='$SiteName']"
$binding = $obj.bindings.Collection[0]
$method = $binding.Methods["AddSslCertificate"]
$methodInstance = $method.CreateInstance()
$methodInstance.Input.SetAttributeValue("certificateHash", $certThumbprint)
$methodInstance.Input.SetAttributeValue("certificateStoreName", $certStore)
$methodInstance.Execute()

February 3, 2017 at 4:54 pm

On the first, I'm not sure there's an exposed way to specify a password. That's deliberate, as including one in a text file – which is what the script is – would be pointless.

On the second, looking at the docs at https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2(v=vs.110).aspx, the Import() method only accepts one argument, but you're passing two.

February 3, 2017 at 5:25 pm

A password for the import method can be specified using this overload – https://msdn.microsoft.com/en-us/library/ms148442(v=vs.110).aspx

$pfx.Import($CertPath, 'secret', 'Exportable,PersistKeySet')

If you're using Windows Server 2012 or later you can make your scripts simpler with the built-in Import-PfxCertificate and Export-PfxCertificate cmdlets that also support a secure string.