mirror of
https://github.com/Grace-Solutions/Invoke-OpenSSHConfiguration.git
synced 2026-07-26 11:38:14 +00:00
603 lines
43 KiB
PowerShell
603 lines
43 KiB
PowerShell
## 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 |