Copy-CertificateToRemote.ps1
<#
.SYNOPSIS Copies a certificate with its chain to the store of a remote computer .DESCRIPTION Copies a certificate with its chain to the store of a remote computer .PARAMETER Certificate The certificate to copy .PARAMETER MoveChain The password to use when exporting certificates with private key .PARAMETER ComputerName Target computer .PARAMETER Credential Target Credential .PARAMETER Session Target session .EXAMPLE $certificate=New-DomainSignedCertificate -Hostname "example.com" -CertificateAuthority "" $pfxPassword=ConvertTo-SecureString “password” -AsPlainText -Force $certificate|Copy-CertificateToRemote -ComputerName EXAMPLE -PfxPassword $pfxPassword -MoveChain .LINK New-DomainSignedCertificate .LINK Move-CertificateToRemote #> function Copy-CertificateToRemote { [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName="Computer")] [Parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName="Session")] [System.Security.Cryptography.X509Certificates.X509Certificate2] $Certificate, [Parameter(Mandatory=$false,ParameterSetName="Computer")] [Parameter(Mandatory=$false,ParameterSetName="Session")] [securestring]$PfxPassword=$null, [Parameter(Mandatory=$false,ParameterSetName="Computer")] [Parameter(Mandatory=$false,ParameterSetName="Session")] [switch]$MoveChain=$false, [Parameter(Mandatory=$true,ParameterSetName="Computer")] [AllowNull()] $ComputerName=$null, [Parameter(Mandatory=$false,ParameterSetName="Computer")] [pscredential]$Credential=$null, [Parameter(Mandatory=$true,ParameterSetName="Session")] [AllowNull()] $Session ) try { if($Certificate.HasPrivateKey) { if(-not $PfxPassword) { throw "Parameter PfxPassword is required to move a certificate with private key" } } $identifier=$Certificate.Thumbprint #Export certificate to temp $exportPath=Join-Path $env:TEMP $identifier if(Test-Path $exportPath) { Remove-Item $exportPath -Recurse -Force } New-Item $exportPath -ItemType Directory|Out-Null [int]$iteration=1 if($Certificate.HasPrivateKey) { $pfxPath=Join-Path $exportPath "$("{0:00}" -f $iteration).$($Certificate.Thumbprint).pfx" $Certificate |Export-PfxCertificate -FilePath $pfxPath -ChainOption BuildChain -Password $PfxPassword|Out-Null } else { $cerPath=Join-Path $exportPath "$("{0:00}" -f $iteration).$($Certificate.Thumbprint).cer" $Certificate |Export-Certificate -FilePath $cerPath -ChainOption BuildChain -Password $pfxPassword|Out-Null } if($MoveChain) { $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain if($chain.Build($Certificate)) { $chain.ChainElements|Select-Object -ExpandProperty Certificate -Skip 1|ForEach-Object { $iteration++ $cerPath=Join-Path $exportPath "$("{0:00}" -f $iteration).$($_.Thumbprint).cer" $_|Export-Certificate -FilePath $cerPath|Out-Null } } } if($ComputerName) { if($Credential) { $Session=New-PSSession -ComputerName $ComputerName -Credential $Credential } else { $Session=New-PSSession -ComputerName $ComputerName } } #Copy certificate to remote temp directory $prepareDirectoryBlock = { $importPath=Join-Path $env:TEMP $Using:identifier if(Test-Path $importPath) { $null=Remove-Item $importPath -Recurse -Force } (New-Item $importPath -ItemType Directory).FullName } $importAbsolutePathOnRemote=Invoke-Command -Session $Session -ScriptBlock $prepareDirectoryBlock -HideComputerName Copy-Item -Path "$exportPath\*.*" -Destination $importAbsolutePathOnRemote -ToSession $session -Force|Out-Null #Import certificate on remote $importBlock= { $importPath=$Using:importAbsolutePathOnRemote try { Get-ChildItem -Path $importPath | Sort-Object -Property Name | ForEach-Object { $item=$_ switch ($item.Extension) { '.pfx' { Import-PfxCertificate -FilePath $item.FullName -CertStoreLocation "cert:\localMachine\my" -Password ($Using:PfxPassword) -Exportable | Out-Null } '.cer' { if($item.Name.StartsWith("01")) { Import-Certificate -FilePath $item.FullName -CertStoreLocation "cert:\localMachine\my" | Out-Null } else { Import-Certificate -FilePath $item.FullName -CertStoreLocation "cert:\localMachine\root" | Out-Null } } } } } finally { if(Test-Path $importPath) { Remove-Item $importPath -Recurse -Force } } } Invoke-Command -Session $session -ScriptBlock $importBlock } finally { if($exportPath -and (Test-Path $exportPath)) { Remove-Item $exportPath -Recurse -Force } if($ComputerName -and $Session) { $Session|Remove-PSSession } } } |