Jump to page sections
Having a need to install PFX certificates on various 2008 R2 servers with PowerShell version 2, I couldn't use the new 2012 R2/Win 8.1 (PSv4) Import-PfxCertificate cmdlet. Using the code I found here in "mao47"'s answer as a base, I wrote up some code to remotely install PFX certificates - supporting specific certificate stores.

I copy to a temporary file in the remote \\computer\admin$ share and then use PowerShell remoting to run the code to import it remotely, so this requires that both administrative shares via SMB/CIFS and PSRemoting are configured and available in the environment.

Client operating systems starting from Vista(?), at least from Windows 7 on, do not by default expose the administrative shares, as far as I can remember from when I set up a GPO for Windows 7 clients and tested stuff. This can be enabled on clients via a GPO, but does represent a security risk. Servers should have them enabled by default unless it's overridden by a group policy (GPO) in your environment.

By default it installs with the flags ''PersistKeySet'' and ''MachineKeySet''. The flags are documented here. Send them in in a string separated by commas.

The X509Certificates class I use under System.Security.Cryptography is documented here.

This isn't a super polished product, but should be perfectly usable for various scenarios, and can be adapted as needed (editing the source code if the parameters aren't enough for you).

Example of successful import

The screenshot shows the verb ''Install''; this has been changed to ''Import''.


PS D:\> . .\scripts\Import-STPfxCertificate.ps1

PS D:\> Import-STPfxCertificate -Cn admin-01 -CertFilePath \\someserver\Cert\AD2023.pfx
ADMIN-01: Successfully added certificate.

Parameters

ComputerName Target computer(s). (alias: -Cn)
CertFilePath Path to the PFX certificate you want to install, as found in an accessible file system.
CertRootStore Certificate root store to install to. Default: 'localmachine'.
CertStore Certificate store within root store to install to. Default: 'my' ("Personal" when viewed in mmc.exe).
X509Flags X509 flags to pass to the import method. Default: 'PersistKeySet,MachineKeySet'. Documented here.
Password Leave empty to be prompted for the PFX certificate password. System.SecureString. You can store it beforehand with "$mypass = Read-Host -AsSecureString"

Download

Import-STPfxCertificate.ps1.txt - right-click and download, remember to unblock, rename to have the .ps1 extension only.

Earlier versions (if any):
Import-STPfxCertificate.ps1.txt.

Source code

Store in a file called Import-PfxCert.ps1 (or whatever you want, but use the .ps1 extension). Dot-source this file (see screenshot example) to get the function into your session, and then call it.
#requires -version 2
function Import-STPfxCertificate
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)][Alias('Cn')] [string[]] $ComputerName,
        [Parameter(Mandatory=$true)][string] $CertFilePath,
        [string] $CertRootStore = 'localmachine',
        [string] $CertStore = 'My',
        [string] $X509Flags = 'PersistKeySet,MachineKeySet',
        [System.Security.SecureString] $Password = $null)
    $ErrorActionPreference = 'Continue'
    $TempCertFileName = 'Svendsen.Tech.temporary.abcdefg.pfx'
    if ($Password -eq $null)
    {
        $Password = Read-Host -Prompt 'Enter PFX cert password' -AsSecureString
    }
    foreach ($Computer in $ComputerName)
    {
        $Destination = "\\$Computer\admin$\$TempCertFileName"
        try
        {
            Copy-Item -LiteralPath $CertFilePath -Destination $Destination -ErrorAction Stop
        }
        catch
        {
            Write-Error -Message "${Computer}: Unable to copy '$CertFilePath' to '$Destination'. Aborting further processing of this computer."
            continue
        }
        Invoke-Command -ComputerName $Computer -ScriptBlock {
            param(
                [string] $CertFileName,
                [string] $CertRootStore,
                [string] $CertStore,
                [string] $X509Flags,
                $PfxPass)
            $CertPath = "$Env:SystemRoot\$CertFileName"
            $Pfx = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
            # Flags to send in are documented here: https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags%28v=vs.110%29.aspx
            $Pfx.Import($CertPath, $PfxPass, $X509Flags) #"Exportable,PersistKeySet")
            $Store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $CertStore, $CertRootStore
            $Store.Open("MaxAllowed")
            $Store.Add($Pfx)
            if ($?)
            {
                "${Env:ComputerName}: Successfully added certificate."
            }
            else
            {
                "${Env:ComputerName}: Failed to add certificate! $($Error[0].ToString() -replace '[\r\n]+', ' ')"
            }
            $Store.Close()
            Remove-Item -LiteralPath $CertPath
        } -ArgumentList $TempCertFileName, $CertRootStore, $CertStore, $X509Flags, $Password
    }
}
Powershell      Windows      Cryptography          All Categories

Google custom search of this website only

Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.

If you want to reward my efforts