Functions/Get-Certificate.ps1
# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Get-CCertificate { <# .SYNOPSIS Gets a certificate from a file on the file system or from a Windows certificate store by thumbprint or friendly name. Beginning in Carbon 2.7, the returned object will have a `Path` property that is the full path to either the file or certificate in the certificate store. .DESCRIPTION Certificates can be files or they can be in a Windows certificate store. This function returns an `X509Certificate2` object for a script that's a file on the file system or a cert stored in Microsoft's certificate store. You can get a certificate from a certificate store with its unique thumbprint or its friendly name. Friendly names are *not* required to be unique, so you may get multiple certificates when using that search method. Certificates loaded from a file are imported with default key storage values, which means if you try to add the certifiate returned by this function to a certificate store it will get persisted in the user's key store and *not* persisted. .OUTPUTS System.Security.Cryptography.x509Certificates.X509Certificate2. The X509Certificate2 certificates that were found, or `$null`. .EXAMPLE Get-CCertificate -Path C:\Certificates\certificate.cer -Password MySuperSecurePassword Gets an X509Certificate2 object representing the certificate.cer file. Wildcards *not* supported when using a file system path. .EXAMPLE Get-CCertificate -Thumbprint a909502dd82ae41433e6f83886b00d4277a32a7b -StoreName My -StoreLocation LocalMachine Gets an X509Certificate2 object for the certificate in the Personal store with a specific thumbprint under the Local Machine. .EXAMPLE Get-CCertificate -FriendlyName 'Development Certificate' -StoreLocation CurrentUser -StoreName TrustedPeople Gets the X509Certificate2 whose friendly name is Development Certificate from the Current User's Trusted People certificate store. .EXAMPLE Get-CCertificate -Thumbprint a909502dd82ae41433e6f83886b00d4277a32a7b -CustomStoreName 'SharePoint' -StoreLocation LocalMachine Demonstrates how to get a certificate from a custom store, i.e. one that is not part of the standard `StoreName` enumeration. .EXAMPLE Get-CCertificate -Path 'cert:\CurrentUser\a909502dd82ae41433e6f83886b00d4277a32a7b' Demonstrates how to get a certificate out of a Windows certificate store with its certificate path. Wildcards supported. #> [CmdletBinding(DefaultParameterSetName='ByFriendlyName')] [OutputType([Security.Cryptography.X509Certificates.X509Certificate2])] param( [Parameter(Mandatory=$true,ParameterSetName='ByPath')] [string] # The path to the certificate. Can be a file system path or a certificate path, e.g. `cert:\`. Wildcards supported. $Path, [Parameter(ParameterSetName='ByPath')] # The password to the certificate. Can be plaintext or a [SecureString](http://msdn.microsoft.com/en-us/library/system.securestring.aspx). $Password, [Parameter(ParameterSetName='ByPath')] [Security.Cryptography.X509Certificates.X509KeyStorageFlags] # The storage flags to use when loading a certificate file. This controls where/how you can store the certificate in the certificate stores later. Use the `-bor` operator to combine flags. $KeyStorageFlags, [Parameter(Mandatory=$true,ParameterSetName='ByThumbprint')] [Parameter(Mandatory=$true,ParameterSetName='ByThumbprintCustomStoreName')] [string] # The certificate's thumbprint. $Thumbprint, [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyName')] [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyNameCustomStoreName')] [string] # The friendly name of the certificate. $FriendlyName, [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyName')] [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyNameCustomStoreName')] [Parameter(Mandatory=$true,ParameterSetName='ByThumbprint')] [Parameter(Mandatory=$true,ParameterSetName='ByThumbprintCustomStoreName')] [Security.Cryptography.X509Certificates.StoreLocation] # The location of the certificate's store. $StoreLocation, [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyName')] [Parameter(Mandatory=$true,ParameterSetName='ByThumbprint')] [Security.Cryptography.X509Certificates.StoreName] # The name of the certificate's store. $StoreName, [Parameter(Mandatory=$true,ParameterSetName='ByFriendlyNameCustomStoreName')] [Parameter(Mandatory=$true,ParameterSetName='ByThumbprintCustomStoreName')] [string] # The name of the non-standard, custom store. $CustomStoreName ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState function Add-PathMember { param( [Parameter(Mandatory,VAlueFromPipeline=$true)] [Security.Cryptography.X509Certificates.X509Certificate2] $Certificate, [Parameter(Mandatory)] [string] $Path ) process { $Certificate | Add-Member -MemberType NoteProperty -Name 'Path' -Value $Path -PassThru } } function Resolve-CertificateProviderFriendlyPath { param( [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string] $PSPath, [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Management.Automation.PSDriveInfo] $PSDrive ) process { $qualifier = '{0}:' -f $PSDrive.Name $path = $PSPath | Split-Path -NoQualifier Join-Path -Path $qualifier -ChildPath $path } } if( $PSCmdlet.ParameterSetName -eq 'ByPath' ) { if( -not (Test-Path -Path $Path -PathType Leaf) ) { Write-Error ('Certificate ''{0}'' not found.' -f $Path) return } Get-Item -Path $Path | ForEach-Object { $item = $_ if( $item -is [Security.Cryptography.X509Certificates.X509Certificate2] ) { $certFriendlyPath = $item | Resolve-CertificateProviderFriendlyPath return $item | Add-PathMember -Path $certFriendlyPath } elseif( $item -is [IO.FileInfo] ) { try { $ctorParams = @( $item.FullName, $Password ) if( $KeyStorageFlags ) { $ctorParams += $KeyStorageFlags } return New-Object 'Security.Cryptography.X509Certificates.X509Certificate2' $ctorParams | Add-PathMember -Path $item.FullName } catch { $ex = $_.Exception while( $ex.InnerException ) { $ex = $ex.InnerException } Write-Error -Message ('Failed to create X509Certificate2 object from file ''{0}'': {1}' -f $item.FullName,$ex.Message) } } } } else { $storeLocationPath = '*' if( $StoreLocation ) { $storeLocationPath = $StoreLocation } $storeNamePath = '*' if( $PSCmdlet.ParameterSetName -like '*CustomStoreName' ) { $storeNamePath = $CustomStoreName } else { $storeNamePath = $StoreName if( $StoreName -eq [Security.Cryptography.X509Certificates.StoreName]::CertificateAuthority ) { $storeNamePath = 'CA' } } if( $pscmdlet.ParameterSetName -like 'ByThumbprint*' ) { $certPath = 'cert:\{0}\{1}\{2}' -f $storeLocationPath,$storeNamePath,$Thumbprint if( (Test-Path -Path $certPath) ) { foreach( $certPathItem in (Get-ChildItem -Path $certPath) ) { $path = $certPathItem | Resolve-CertificateProviderFriendlyPath $certPathItem | Add-PathMember -Path $path } } return } elseif( $PSCmdlet.ParameterSetName -like 'ByFriendlyName*' ) { $certPath = Join-Path -Path 'cert:' -ChildPath $storeLocationPath $certPath = Join-Path -Path $certPath -ChildPath $storeNamePath $certPath = Join-Path -Path $certPath -ChildPath '*' return Get-ChildItem -Path $certPath | Where-Object { $_.FriendlyName -eq $FriendlyName } | ForEach-Object { $friendlyPath = $_ | Resolve-CertificateProviderFriendlyPath $_ | Add-PathMember -Path $friendlyPath } } Write-Error "Unknown parameter set '$($pscmdlet.ParameterSetName)'." } } |