## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx #region Function ConvertFrom-CertificateToPEM Function ConvertFrom-CertificateToPEM { <# .SYNOPSIS A brief overview of what your function does .DESCRIPTION Slightly more detailed description of what your function does .PARAMETER ParameterName Your parameter description .PARAMETER ParameterName Your parameter description .PARAMETER ParameterName Your parameter description .EXAMPLE $ConvertFromCertificateToPEMParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $ConvertFromCertificateToPEMParameters.SerialNumberList = New-Object -TypeName 'System.Collections.Generic.List[System.String]' $ConvertFromCertificateToPEMParameters.SerialNumberList.Add('3d05e1f73beb5d3cd1be2b9f8d96f6c323260f78') $ConvertFromCertificateToPEMParameters.Export = $True $ConvertFromCertificateToPEMParameters.ExportRootDirectory = "$($Env:Userprofile)\Downloads\Certificates" $ConvertFromCertificateToPEMParameters.ContinueOnError = $False $ConvertFromCertificateToPEMParameters.Verbose = $True $ConvertFromCertificateToPEMResult = ConvertFrom-CertificateToPEM @ConvertFromCertificateToPEMParameters Write-Output -InputObject ($ConvertFromCertificateToPEMResult) .EXAMPLE [String]$RootCALocation = 'Cert:\LocalMachine\My' [String]$RootCAFriendlyName = 'Self Signed Root CA Certificate' $DNSHostEntry = [System.Net.Dns]::GetHostEntry('LocalHost') $NewSelfSignedCertificateParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $NewSelfSignedCertificateParameters.FriendlyName = $RootCAFriendlyName $NewSelfSignedCertificateParameters.Subject = "$($Env:ComputerName.ToUpper())" $NewSelfSignedCertificateParameters.DnsName = New-Object -TypeName 'System.Collections.Generic.List[System.String]' $NewSelfSignedCertificateParameters.DnsName.Add($DNSHostEntry.HostName) $NewSelfSignedCertificateParameters.NotBefore = (Get-Date).Date $NewSelfSignedCertificateParameters.NotAfter = $NewSelfSignedCertificateParameters.NotBefore.Date.AddYears(10) $NewSelfSignedCertificateParameters.CertStoreLocation = $RootCALocation $NewSelfSignedCertificateParameters.KeyExportPolicy = New-Object -TypeName 'System.Collections.Generic.List[Microsoft.Certificateservices.Commands.Keyexportpolicy]' $NewSelfSignedCertificateParameters.KeyExportPolicy.Add('Exportable') $NewSelfSignedCertificateParameters.Provider = 'Microsoft Enhanced RSA and AES Cryptographic Provider' $NewSelfSignedCertificateParameters.TextExtension = New-Object -TypeName 'System.Collections.Generic.List[System.String]' $NewSelfSignedCertificateParameters.TextExtension.Add('2.5.29.19={text}CA=1&pathlength=3') $NewSelfSignedCertificateParameters.TextExtension.Add('2.5.29.37={text}1.3.6.1.5.5.7.3.3') $NewSelfSignedCertificateParameters.KeyUsageProperty = New-Object -TypeName 'System.Collections.Generic.List[Microsoft.Certificateservices.Commands.Keyusageproperty]' $NewSelfSignedCertificateParameters.KeyUsageProperty.Add('All') $NewSelfSignedCertificateParameters.KeyUsage = New-Object -TypeName 'System.Collections.Generic.List[Microsoft.Certificateservices.Commands.Keyusage]' $NewSelfSignedCertificateParameters.KeyUsage.Add('CertSign') $NewSelfSignedCertificateParameters.KeyUsage.Add('CRLSign') $NewSelfSignedCertificateParameters.KeyUsage.Add('DigitalSignature') $NewSelfSignedCertificateParameters.Confirm = $False $SelfSignedCertificate = New-SelfSignedCertificate @NewSelfSignedCertificateParameters $ConvertFromCertificateToPEMParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $ConvertFromCertificateToPEMParameters.CertificateList = New-Object -TypeName 'System.Collections.Generic.List[System.Security.Cryptography.X509Certificates.X509Certificate2]' $ConvertFromCertificateToPEMParameters.CertificateList.Add($SelfSignedCertificate) $ConvertFromCertificateToPEMParameters.Export = $True $ConvertFromCertificateToPEMParameters.ExportRootDirectory = "$($Env:Userprofile)\Downloads\Certificates" $ConvertFromCertificateToPEMParameters.ContinueOnError = $False $ConvertFromCertificateToPEMParameters.Verbose = $True $ConvertFromCertificateToPEMResult = ConvertFrom-CertificateToPEM @ConvertFromCertificateToPEMParameters Write-Output -InputObject ($ConvertFromCertificateToPEMResult) .NOTES Any useful tidbits .LINK Place any useful link here where your function or cmdlet can be referenced #> [CmdletBinding(ConfirmImpact = 'Low', DefaultParameterSetName = 'BySerialNumber')] Param ( [Parameter(Mandatory=$True, ParameterSetName = 'BySerialNumber')] [ValidateNotNullOrEmpty()] [String[]]$SerialNumberList, [Parameter(Mandatory=$True, ParameterSetName = 'ByCertificate')] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.X509Certificate2[]]$CertificateList, [Parameter(Mandatory=$False)] [Switch]$Export, [Parameter(Mandatory=$False)] [AllowEmptyString()] [AllowNull()] [System.IO.DirectoryInfo]$ExportRootDirectory, [Parameter(Mandatory=$False)] [Switch]$ContinueOnError ) Begin { Try { $DateTimeLogFormat = 'dddd, MMMM dd, yyyy @ hh:mm:ss.FFF tt' ###Monday, January 01, 2019 @ 10:15:34.000 AM### [ScriptBlock]$GetCurrentDateTimeLogFormat = {(Get-Date).ToString($DateTimeLogFormat)} $DateTimeMessageFormat = 'MM/dd/yyyy HH:mm:ss.FFF' ###03/23/2022 11:12:48.347### [ScriptBlock]$GetCurrentDateTimeMessageFormat = {(Get-Date).ToString($DateTimeMessageFormat)} $DateFileFormat = 'yyyyMMdd' ###20190403### [ScriptBlock]$GetCurrentDateFileFormat = {(Get-Date).ToString($DateFileFormat)} $DateTimeFileFormat = 'yyyyMMdd_HHmmss' ###20190403_115354### [ScriptBlock]$GetCurrentDateTimeFileFormat = {(Get-Date).ToString($DateTimeFileFormat)} $TextInfo = (Get-Culture).TextInfo $LoggingDetails = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $LoggingDetails.Add('LogMessage', $Null) $LoggingDetails.Add('WarningMessage', $Null) $LoggingDetails.Add('ErrorMessage', $Null) $CommonParameterList = New-Object -TypeName 'System.Collections.Generic.List[String]' $CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::CommonParameters) $CommonParameterList.AddRange([System.Management.Automation.PSCmdlet]::OptionalCommonParameters) [ScriptBlock]$ErrorHandlingDefinition = { Param ( [Int16]$Severity, [Boolean]$ContinueOnError ) $ExceptionPropertyDictionary = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $ExceptionPropertyDictionary.Message = $_.Exception.Message $ExceptionPropertyDictionary.Category = $_.Exception.ErrorRecord.FullyQualifiedErrorID $ExceptionPropertyDictionary.Script = [System.IO.Path]::GetFileName($_.InvocationInfo.ScriptName) $ExceptionPropertyDictionary.LineNumber = $_.InvocationInfo.ScriptLineNumber $ExceptionPropertyDictionary.LinePosition = $_.InvocationInfo.OffsetInLine $ExceptionPropertyDictionary.Code = $_.InvocationInfo.Line.Trim() $ExceptionMessageList = New-Object -TypeName 'System.Collections.Generic.List[String]' ForEach ($ExceptionProperty In $ExceptionPropertyDictionary.GetEnumerator()) { $ExceptionMessageList.Add("[$($ExceptionProperty.Key): $($ExceptionProperty.Value)]") } $LogMessageParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $LogMessageParameters.Message = $ExceptionMessageList -Join ' ' $LogMessageParameters.Verbose = $True Switch ($Severity) { {($_ -in @(1))} {Write-Verbose @LogMessageParameters} {($_ -in @(2))} {Write-Warning @LogMessageParameters} {($_ -in @(3))} {Write-Error @LogMessageParameters} } Switch ($ContinueOnError) { {($_ -eq $False)} { Throw } } } #Determine the date and time we executed the function $FunctionStartTime = (Get-Date) [String]$FunctionName = $MyInvocation.MyCommand [System.IO.FileInfo]$InvokingScriptPath = $MyInvocation.PSCommandPath [System.IO.DirectoryInfo]$InvokingScriptDirectory = $InvokingScriptPath.Directory.FullName [System.IO.FileInfo]$FunctionPath = "$($InvokingScriptDirectory.FullName)\Functions\$($FunctionName).ps1" [System.IO.DirectoryInfo]$FunctionDirectory = "$($FunctionPath.Directory.FullName)" $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is beginning. Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose #Define Default Action Preferences $ErrorActionPreference = 'Stop' [String[]]$AvailableScriptParameters = (Get-Command -Name ($FunctionName)).Parameters.GetEnumerator() | Where-Object {($_.Value.Name -inotin $CommonParameterList)} | ForEach-Object {"-$($_.Value.Name):$($_.Value.ParameterType.Name)"} $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Available Function Parameter(s) = $($AvailableScriptParameters -Join ', ')" Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose [String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {Try {"-$($_.Key):$($_.Value.GetType().Name)"} Catch {"-$($_.Key):Unknown"}} $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')" Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))" Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose #Create an object that will contain the functions output. $OutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[System.Management.Automation.PSObject]' #Set default parameter value(s) Switch ($True) { {([String]::IsNullOrEmpty($ExportRootDirectory) -eq $True) -or ([String]::IsNullOrWhiteSpace($ExportRootDirectory) -eq $True)} { [System.IO.DirectoryInfo]$ExportRootDirectory = "$($Env:Public)\Documents\$($FunctionName)" } } $X509Certificate2List = New-Object -TypeName 'System.Collections.Generic.List[System.Security.Cryptography.X509Certificates.X509Certificate2]' Switch ($PSCmdlet.ParameterSetName) { {($_ -iin @('BySerialNumber'))} { $ExistingCertificateList = Get-ChildItem -Path @('Microsoft.PowerShell.Security\Certificate::\') -Recurse -Force -ErrorAction SilentlyContinue | Where-Object {($Null -ine $_.SerialNumber)} ForEach ($SerialNumber In $SerialNumberList) { Switch ($ExistingCertificateList.SerialNumber -icontains $SerialNumber) { {($_ -eq $True)} { $ExistingCertificates = $ExistingCertificateList | Where-Object {($_.SerialNumber -ieq $SerialNumber)} | Sort-Object -Property @('NotAfter') -Descending -Unique $ExistingCertificateCount = ($ExistingCertificates | Measure-Object).Count $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Located $($ExistingCertificateCount) certificate(s) for certificate serial number `"$($SerialNumber)`"." Write-Verbose -Message ($LoggingDetails.LogMessage) Switch ($ExistingCertificateCount) { {($_ -eq 1)} { $X509Certificate2List.Add($ExistingCertificates) } {($_ -gt 1)} { ForEach ($ExistingCertificate In $ExistingCertificates) { $X509Certificate2List.Add($ExistingCertificate) } } } } } } } {($_ -iin @('ByCertificate'))} { $CertificateList | Sort-Object -Property @('NotAfter') -Descending -Unique | ForEach-Object {($X509Certificate2List.Add($_))} } } } Catch { $ErrorHandlingDefinition.Invoke(2, $ContinueOnError.IsPresent) } Finally { } } Process { Try { $X509Certificate2ListCounter = 1 $X509Certificate2ListCount = ($X509Certificate2List | Measure-Object).Count For ($X509Certificate2ListIndex = 0; $X509Certificate2ListIndex -lt $X509Certificate2ListCount; $X509Certificate2ListIndex++) { Try { $X509Certificate2ListItem = $X509Certificate2List[$X509Certificate2ListIndex] $OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $OutputObjectProperties.SerialNumber = $X509Certificate2ListItem.SerialNumber $OutputObjectProperties.Blobs = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $OutputObjectProperties.Blobs.Certificate = $Null $OutputObjectProperties.Blobs.PublicKey = $Null $OutputObjectProperties.Blobs.PrivateKey = $Null $OutputObjectProperties.Exports = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $OutputObjectProperties.Exports.Certificate = $Null $OutputObjectProperties.Exports.PublicKey = $Null $OutputObjectProperties.Exports.PrivateKey = $Null $OutputObjectProperties.Certificate = $X509Certificate2ListItem $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to process certificate `"$($X509Certificate2ListItem.SerialNumber)`". Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Issuer: $($X509Certificate2ListItem.Issuer)" Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Thumbprint: $($X509Certificate2ListItem.Thumbprint)" Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Serial Number: $($X509Certificate2ListItem.SerialNumber)" Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - DNS Name List: $($X509Certificate2ListItem.DnsNameList -Join ', ')" Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Not Before: $($X509Certificate2ListItem.NotBefore.ToString($DateTimeLogFormat))" Write-Verbose -Message ($LoggingDetails.LogMessage) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Not After: $($X509Certificate2ListItem.NotAfter.ToString($DateTimeLogFormat))" Write-Verbose -Message ($LoggingDetails.LogMessage) $StringBuilders = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $StringBuilders.Certificate = New-Object -TypeName 'System.Text.StringBuilder' $StringBuilders.PrivateKey = New-Object -TypeName 'System.Text.StringBuilder' $StringBuilders.PublicKey = New-Object -TypeName 'System.Text.StringBuilder' $X509KeyStorageFlags = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $X509KeyStorageFlags.Valid = [System.Enum]::GetNames('System.Security.Cryptography.X509Certificates.X509KeyStorageFlags') | Sort-Object $X509KeyStorageFlags.Specified = New-Object -TypeName 'System.Collections.Generic.List[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]' $X509KeyStorageFlags.Specified.Add('Exportable') $X509Certificate2 = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $X509Certificate2.Object = $X509Certificate2ListItem $X509Certificate2.ObjectEncoded = $Null $X509Certificate2.ContentType = $Null $X509Certificate2.OID = $Null $X509Certificate2.DSA = $Null $X509Certificate2.CNG = $Null $X509Certificate2.PublicKey = $Null $X509Certificate2.PublicKeyEncoded = $Null $X509Certificate2.PrivateKey = $Null $X509Certificate2.PrivateKeyEncoded = $Null $X509Certificate2.ContentType = [System.Security.Cryptography.X509Certificates.X509Certificate2]::GetCertContentType($X509Certificate2.Object.RawData) $X509Certificate2.ObjectEncoded = [System.Convert]::ToBase64String($X509Certificate2.Object.RawData, [System.Base64FormattingOptions]::InsertLineBreaks) $Null = $StringBuilders.Certificate.Append('-----BEGIN CERTIFICATE-----').AppendLine() $Null = $StringBuilders.Certificate.Append($X509Certificate2.ObjectEncoded).AppendLine() $Null = $StringBuilders.Certificate.Append('-----END CERTIFICATE-----') $OutputObjectProperties.Blobs.Certificate = $StringBuilders.Certificate.ToString() $X509Certificate2.OID = [System.Security.Cryptography.OID]::New($X509Certificate2.Object.GetKeyAlgorithm()) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - A certificate key algorithm of `"$($X509Certificate2.OID.FriendlyName)`" [OID: $($X509Certificate2.OID.Value)] was detected." Write-Verbose -Message ($LoggingDetails.LogMessage) Switch ($Null -ine $X509Certificate2.Object.PublicKey) { {($_ -eq $True)} { Switch ($X509Certificate2.OID.FriendlyName) { {($_ -iin @('RSA'))} { $X509Certificate2.DSA = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPublicKey($X509Certificate2.Object) $X509Certificate2.CNG = [System.Security.Cryptography.RSACNG]($X509Certificate2.DSA) } {($_ -iin @('ECC'))} { $X509Certificate2.DSA = [System.Security.Cryptography.X509Certificates.ECDSACertificateExtensions]::GetECDSAPublicKey($X509Certificate2.Object) $X509Certificate2.CNG = [System.Security.Cryptography.ECDSACNG]($X509Certificate2.DSA) } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The certificate key algorithm of `"$($X509Certificate2.OID.FriendlyName)`" [OID: $($X509Certificate2.OID.Value)] is unsupported for public key extraction." Write-Warning -Message ($LoggingDetails.LogMessage) } } $X509Certificate2.PublicKey = $X509Certificate2.CNG.Key $X509Certificate2.PublicKeyEncoded = [System.Convert]::ToBase64String(($X509Certificate2.PublicKey.Export([System.Security.Cryptography.CngKeyBlobFormat]::GenericPublicBlob)), [System.Base64FormattingOptions]::InsertLineBreaks) $Null = $StringBuilders.PublicKey.Append('-----BEGIN PUBLIC KEY-----').AppendLine() $Null = $StringBuilders.PublicKey.Append($X509Certificate2.PublicKeyEncoded).AppendLine() $Null = $StringBuilders.PublicKey.Append('-----END PUBLIC KEY-----') $OutputObjectProperties.Blobs.PublicKey = $StringBuilders.PublicKey.ToString() } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The certificate `"$($X509Certificate2ListItem.SerialNumber)`" [Thumbprint: $($X509Certificate2ListItem.Thumbprint)] does not contain a public key." Write-Warning -Message ($LoggingDetails.LogMessage) } } Switch ($X509Certificate2.Object.HasPrivateKey) { {($_ -eq $True)} { Switch ($X509Certificate2.OID.FriendlyName) { {($_ -iin @('RSA'))} { $X509Certificate2.DSA = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($X509Certificate2.Object) $X509Certificate2.CNG = [System.Security.Cryptography.RSACNG]($X509Certificate2.DSA) } {($_ -iin @('ECC'))} { $X509Certificate2.DSA = [System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions]::GetECDSAPrivateKey($X509Certificate2.Object) $X509Certificate2.CNG = [System.Security.Cryptography.ECDSACNG]($X509Certificate2.DSA) } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The certificate key algorithm of `"$($X509Certificate2.OID.FriendlyName)`" [OID: $($X509Certificate2.OID.Value)] is unsupported for private key extracted." Write-Warning -Message ($LoggingDetails.LogMessage) } } $X509Certificate2.PrivateKey = $X509Certificate2.CNG.Key $X509Certificate2.PrivateKeyEncoded = [System.Convert]::ToBase64String(($X509Certificate2.PrivateKey.Export([System.Security.Cryptography.CngKeyBlobFormat]::PKCS8PrivateBlob)), [System.Base64FormattingOptions]::InsertLineBreaks) $Null = $StringBuilders.PrivateKey.Append('-----BEGIN PRIVATE KEY-----').AppendLine() $Null = $StringBuilders.PrivateKey.Append($X509Certificate2.PrivateKeyEncoded).AppendLine() $Null = $StringBuilders.PrivateKey.Append('-----END PRIVATE KEY-----') $OutputObjectProperties.Blobs.PrivateKey = $StringBuilders.PrivateKey.ToString() } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - The certificate `"$($X509Certificate2ListItem.SerialNumber)`" [Thumbprint: $($X509Certificate2ListItem.Thumbprint)] does not contain a private key. Please ensure that the private key is exportable." Write-Warning -Message ($LoggingDetails.LogMessage) } } $WriteAllTextParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' $WriteAllTextParameters.Path = $Null $WriteAllTextParameters.Contents = $Null $WriteAllTextParameters.Encoding = [System.Text.Encoding]::ASCII Switch ($Export.IsPresent) { {($_ -eq $True)} { $X509Certificate2.ExportDirectory = "$($ExportRootDirectory.FullName)\$($X509Certificate2ListItem.SerialNumber)" -As [System.IO.DirectoryInfo] Switch (([String]::IsNullOrEmpty($OutputObjectProperties.Blobs.Certificate) -eq $False) -or ([String]::IsNullOrWhiteSpace($OutputObjectProperties.Blobs.Certificate) -eq $False)) { {($_ -eq $True)} { Switch ($True) { {([System.IO.Directory]::Exists($X509Certificate2.ExportDirectory.FullName) -eq $False)} { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to create directory `"$($X509Certificate2.ExportDirectory.FullName)`". Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) $Null = [System.IO.Directory]::CreateDirectory($X509Certificate2.ExportDirectory.FullName) } } $WriteAllTextParameters.Path = "$($X509Certificate2.ExportDirectory.FullName)\Certificate.pem" $WriteAllTextParameters.Contents = $OutputObjectProperties.Blobs.Certificate $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to export the certificate to `"$($WriteAllTextParameters.Path)`". Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) $Null = [System.IO.File]::WriteAllText($WriteAllTextParameters.Path, $WriteAllTextParameters.Contents, $WriteAllTextParameters.Encoding) Switch ($?) { {($_ -eq $True)} { $OutputObjectProperties.Exports.Certificate = $WriteAllTextParameters.Path } } } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Unable to export the certificate from `"$($X509Certificate2ListItem.SerialNumber)`" [Thumbprint: $($X509Certificate2ListItem.Thumbprint)] to `"$($WriteAllTextParameters.Path)`"." Write-Warning -Message ($LoggingDetails.LogMessage) } } Switch (([String]::IsNullOrEmpty($OutputObjectProperties.Blobs.PublicKey) -eq $False) -or ([String]::IsNullOrWhiteSpace($OutputObjectProperties.Blobs.PublicKey) -eq $False)) { {($_ -eq $True)} { $WriteAllTextParameters.Path = "$($X509Certificate2.ExportDirectory.FullName)\PublicKey.pem" $WriteAllTextParameters.Contents = $OutputObjectProperties.Blobs.PublicKey $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to export the public key to `"$($WriteAllTextParameters.Path)`". Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) $Null = [System.IO.File]::WriteAllText($WriteAllTextParameters.Path, $WriteAllTextParameters.Contents, $WriteAllTextParameters.Encoding) Switch ($?) { {($_ -eq $True)} { $OutputObjectProperties.Exports.PublicKey = $WriteAllTextParameters.Path } } } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Unable to export the public key from certificate `"$($X509Certificate2ListItem.SerialNumber)`" [Thumbprint: $($X509Certificate2ListItem.Thumbprint)] to `"$($WriteAllTextParameters.Path)`"." Write-Warning -Message ($LoggingDetails.LogMessage) } } Switch (([String]::IsNullOrEmpty($OutputObjectProperties.Blobs.PrivateKey) -eq $False) -or ([String]::IsNullOrWhiteSpace($OutputObjectProperties.Blobs.PrivateKey) -eq $False)) { {($_ -eq $True)} { $WriteAllTextParameters.Path = "$($X509Certificate2.ExportDirectory.FullName)\PrivateKey.pem" $WriteAllTextParameters.Contents = $OutputObjectProperties.Blobs.PrivateKey $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to export the private key to `"$($WriteAllTextParameters.Path)`". Please Wait..." Write-Verbose -Message ($LoggingDetails.LogMessage) $Null = [System.IO.File]::WriteAllText($WriteAllTextParameters.Path, $WriteAllTextParameters.Contents, $WriteAllTextParameters.Encoding) Switch ($?) { {($_ -eq $True)} { $OutputObjectProperties.Exports.PrivateKey = $WriteAllTextParameters.Path } } } Default { $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Unable to export the private key from certificate `"$($X509Certificate2ListItem.SerialNumber)`" [Thumbprint: $($X509Certificate2ListItem.Thumbprint)] to `"$($WriteAllTextParameters.Path)`"." Write-Warning -Message ($LoggingDetails.LogMessage) } } } } } Catch { $ErrorHandlingDefinition.Invoke(2, $True) } Finally { $OutputObject = New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($OutputObjectProperties) $OutputObjectList.Add($OutputObject) $X509Certificate2ListCounter++ } } } Catch { $ErrorHandlingDefinition.Invoke(2, $ContinueOnError.IsPresent) } Finally { } } End { Try { #Determine the date and time the function completed execution $FunctionEndTime = (Get-Date) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) ended on $($FunctionEndTime.ToString($DateTimeLogFormat))" Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose #Log the total script execution time $FunctionExecutionTimespan = New-TimeSpan -Start ($FunctionStartTime) -End ($FunctionEndTime) $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function execution took $($FunctionExecutionTimespan.Hours.ToString()) hour(s), $($FunctionExecutionTimespan.Minutes.ToString()) minute(s), $($FunctionExecutionTimespan.Seconds.ToString()) second(s), and $($FunctionExecutionTimespan.Milliseconds.ToString()) millisecond(s)" Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose $LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is completed." Write-Verbose -Message ($LoggingDetails.LogMessage) -Verbose } Catch { $ErrorHandlingDefinition.Invoke(2, $ContinueOnError.IsPresent) } Finally { #Write the object to the powershell pipeline $OutputObjectList = $OutputObjectList.ToArray() Write-Output -InputObject ($OutputObjectList) } } } #endregion