9

I use a command like this:

 get-pfxcertificate C:\test.pfx Enter password: ******* 

The command ask me to fill the prompt. But I can't do that in my script (test.ps1 for ex)

What I need is like this:

 get-pfxcertificate C:\test.pfx -password "123456" 

or something similar so I can run my script without fill in the prompt each time

I'm very thankful for any reply

6 Answers 6

23

There's no Password parameter, you can try with a .NET class:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import('C:\test.pfx','123456','DefaultKeySet') 
Sign up to request clarification or add additional context in comments.

3 Comments

[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms") [System.Windows.Forms.SendKeys]::SendWait( "123456~" )
That would also solve the problem, but not good enough for me, since if get-pfxcertificate does not ask for the prompt, the above command will expose my password. Your solution is really good. Thanks very much
@ngubk, you can use Read-Host to prompt for the password. stackoverflow.com/a/30602978/124069
8

There is now a Get-PfxData command in PowerShell that gets the certificate and chain. The command includes a -Password parameter that takes a SecureString object so you can avoid being prompted.

The EndEntityCertificates property contains an array of certificates at the end of the certificate chain and will contain the same certificate object created by the Get-PfxCertificate command.

The following example converts a normal string to a SecureString object, loads the certificates from a file, then assigns the first/only end certificate to the $SigningCert variable:

$SecurePassword=ConvertTo-SecureString -String "MyPassword" -AsPlainText -Force $PfxData=Get-PfxData -FilePath ".\cert_filename.pfx" -Password $SecurePassword $SigningCert=$PfxData.EndEntityCertificates[0] 

You can now apply $SigningCert without being prompted for the password.

1 Comment

Shew, I was just struggling with this. Thanks! And I guess to make my comment not totally useless, here's a 1 line version. (Get-PfxData -FilePath "C:\yada\yada.pfx" -Password (ConvertTo-SecureString -String "MyPassword") -Force -AsPlainText ).EndEntityCertificates[0]
6

Another option is to extend the abilities of Get-PfxCertificate, essentially enabling the password to be passed in.

# create a backup of the original cmdlet if(Test-Path Function:\Get-PfxCertificate){ Copy Function:\Get-PfxCertificate Function:\Get-PfxCertificateOriginal } # create a new cmdlet with the same name (overwrites the original) function Get-PfxCertificate { [CmdletBinding(DefaultParameterSetName='ByPath')] param( [Parameter(Position=0, Mandatory=$true, ParameterSetName='ByPath')] [string[]] $filePath, [Parameter(Mandatory=$true, ParameterSetName='ByLiteralPath')] [string[]] $literalPath, [Parameter(Position=1, ParameterSetName='ByPath')] [Parameter(Position=1, ParameterSetName='ByLiteralPath')] [string] $password, [Parameter(Position=2, ParameterSetName='ByPath')] [Parameter(Position=2, ParameterSetName='ByLiteralPath')] [string] [ValidateSet('DefaultKeySet','Exportable','MachineKeySet','PersistKeySet','UserKeySet','UserProtected')] $x509KeyStorageFlag = 'DefaultKeySet' ) if($PsCmdlet.ParameterSetName -eq 'ByPath'){ $literalPath = Resolve-Path $filePath } if(!$password){ # if the password parameter isn't present, just use the original cmdlet $cert = Get-PfxCertificateOriginal -literalPath $literalPath } else { # otherwise use the .NET implementation $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import($literalPath, $password, $X509KeyStorageFlag) } return $cert } 

And now you can call it

# tada: extended cmdlet with `password` parameter Get-PfxCertificate 'C:\path\to\cert.pfx' 'password' 

Also, if you still need the prompt, you can do something like this.

$pwd = Read-Host 'Please enter your SSL Certificate password.' Get-PfxCertificate 'C:\path\to\cert.pfx' $pwd 

Comments

4

If you are forced to use Windows Powershell (v5.*), then previous solutions in the thread are for you.

However if you can use Powershell 7/Powershell Core, then its own Get-PfxCertificate command does have a -Password parameter.

After installing Powershell 7 and making sure to use pwsh and not powershell, you can load the certificate that way:

$certificate = (Get-PfxCertificate <certificate_path>.pfx -Password (ConvertTo-SecureString -String "<password>" -AsPlainText -Force)) 

Comments

2

Thanks to Shay for pointing me in the right direction. My need was getting the Thumbprint from the PFX file, so I used the non-persistent DefaultKeySet. Testing under 2012 PS3 fails unless the key set is fully qualified. Also, a blank space between Import and left parenthesis, i.e. "$cert.Import^^(Sys..." causes an error. Picky, picky parser.

My PFX password is encrypted in the source. I decrypt it at runtime so it is not visible in the souce.

Set-StrictMode -Version Latest [string] $strPW = '123456' [string] $strPFX = 'C:\MyCert.pfx' $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import($strPFX,$strPW,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"DefaultKeySet") $cert.Thumbprint 

Comments

-2

This also works using native PowerShell instead of .NET:

 $securePassword = ConvertTo-SecureString -String $strPW -Force -AsPlainText $cert = Import-PfxCertificate -FilePath $strPFX cert:\LocalMachine\My -Password $securePassword 

2 Comments

the OP isn't using Import, they're using get which doesn't have the password parameter by default.
Indeed, this answer is confusing. PowerShell 3.0's native Get-PfxCertificate Cmdlet provides a lot of functionality on the .pfx file, but doesn't allow a password to be passed in as SecureString. This answer is about the PKI module's Import-PfxCertificate CmdLet, which does accept a password parameter, but lacks functionality in comparison.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.