Files
Invoke-SymmectricCryptography/Invoke-SymmectricCryptography.ps1
2023-10-18 15:13:52 -04:00

622 lines
41 KiB
PowerShell

## Microsoft Function Naming Convention: http://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
#region Function Invoke-SymmectricCryptography
Function Invoke-SymmectricCryptography
{
<#
.SYNOPSIS
Performs value encryption or decryption using a specified algorithm.
.DESCRIPTION
A random key and initialization vector (IV) will be generated with each execution for maximum security.
This means that the resulting encrypted data will NEVER be the same, even if the value to be encrypted is!
This function is great for encrypting data that will NOT be transmitted over a network. In other words, data at rest.
If transmitting the data over a network is required, consider breaking the encrypted data, key, and initialization vector apart.
.PARAMETER Encrypt
Specifies that encryption will be performed.
.PARAMETER Decrypt
Specifies that decryption will be performed.
.PARAMETER Algorithm
Specifies the algorithm used for encryption or decryption.
.PARAMETER Data
Specifies the original string value that will be encrypted.
.PARAMETER EncryptedData
Specifies the previously encrypted string value that will be decrypted.
.PARAMETER Key
Specifies the decryption key that is required for decryption.
.PARAMETER InitializationVector
Specifies the initialization vector (IV) that is required for decryption.
.PARAMETER Export
Specifies that the encrypted data is to be exported.
.PARAMETER ExportFormat
Specifies the format that the encrypted data will be exported in.
.PARAMETER ExportPath
Specifies the path that the encrypted data will be exported to.
.PARAMETER ContinueOnError
Specifies that errors will be logged as warnings, but not considered fatal.
.EXAMPLE
$EncryptionResult = Invoke-SymmectricCryptography -Encrypt -Algorithm AES -Data 'SomeValueRequiringEncryption'
Write-Output -InputObject ($EncryptionResult)
.EXAMPLE
$DecryptionResult = Invoke-SymmectricCryptography -Decrypt -Algorithm AES -Data 'msDFP5hUQo8flkb+qnRSl+1yEaKEhl5Lr3LBfClXSMY=' -Key 'oc5cuCuOhw1qJvwr1iwHr9mOWXmLTMCgw1zlIOZDf78=' -InitializationVector 'zDpcPE2a4YWF/gFmGQoZhQ=='
Write-Output -InputObject ($DecryptionResult)
.EXAMPLE
$InvokeSymmectricCryptographyParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeSymmectricCryptographyParameters.Encrypt = $True
$InvokeSymmectricCryptographyParameters.Algorithm = 'AES'
$InvokeSymmectricCryptographyParameters.Data = New-Object -TypeName 'System.Collections.Generic.List[System.String]'
$InvokeSymmectricCryptographyParameters.Data.Add("AValueThatNeedsToBeEncrypted")
$InvokeSymmectricCryptographyParameters.Data.Add("AnotherValueThatNeedsToBeEncrypted")
$InvokeSymmectricCryptographyParameters.Export = $True
$InvokeSymmectricCryptographyParameters.ExportFormat = 'XML'
$InvokeSymmectricCryptographyParameters.ExportPath = "$($Env:UserProfile)\Downloads\EncryptedData.xml"
$InvokeSymmectricCryptographyParameters.ContinueOnError = $False
$InvokeSymmectricCryptographyParameters.Verbose = $True
$EncryptionResult = Invoke-SymmectricCryptography @InvokeSymmectricCryptographyParameters
Write-Output -InputObject ($EncryptionResult)
.EXAMPLE
$InvokeSymmectricCryptographyParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeSymmectricCryptographyParameters.Decrypt = $True
$InvokeSymmectricCryptographyParameters.Algorithm = 'AES'
$InvokeSymmectricCryptographyParameters.EncryptedData = 'msDFP5hUQo8flkb+qnRSl+1yEaKEhl5Lr3LBfClXSMY='
$InvokeSymmectricCryptographyParameters.Key = 'oc5cuCuOhw1qJvwr1iwHr9mOWXmLTMCgw1zlIOZDf78='
$InvokeSymmectricCryptographyParameters.InitializationVector = 'zDpcPE2a4YWF/gFmGQoZhQ=='
$InvokeSymmectricCryptographyParameters.ContinueOnError = $False
$InvokeSymmectricCryptographyParameters.Verbose = $True
$DecryptionResult = Invoke-SymmectricCryptography @InvokeSymmectricCryptographyParameters
Write-Output -InputObject ($DecryptionResult)
.EXAMPLE
$InvokeSymmectricCryptographyParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeSymmectricCryptographyParameters.Encrypt = $True
$InvokeSymmectricCryptographyParameters.Algorithm = 'AES'
$InvokeSymmectricCryptographyParameters.Data = "AValueThatNeedsToBeEncrypted"
$InvokeSymmectricCryptographyParameters.ContinueOnError = $False
$InvokeSymmectricCryptographyParameters.Verbose = $True
$EncryptionResult = Invoke-SymmectricCryptography @InvokeSymmectricCryptographyParameters
Write-Output -InputObject ($EncryptionResult)
$InvokeSymmectricCryptographyParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$InvokeSymmectricCryptographyParameters.Decrypt = $True
$InvokeSymmectricCryptographyParameters.Algorithm = $EncryptionResult.Algorithm
$InvokeSymmectricCryptographyParameters.EncryptedData = $EncryptionResult.Data
$InvokeSymmectricCryptographyParameters.Key = $EncryptionResult.Key
$InvokeSymmectricCryptographyParameters.InitializationVector = $EncryptionResult.InitializationVector
$InvokeSymmectricCryptographyParameters.ContinueOnError = $False
$InvokeSymmectricCryptographyParameters.Verbose = $True
$DecryptionResult = Invoke-SymmectricCryptography @InvokeSymmectricCryptographyParameters
Write-Output -InputObject ($DecryptionResult)
.NOTES
Any useful tidbits
.LINK
https://codeandkeep.com/PowerShell-Aes-Encryption/
.LINK
https://smsagent.blog/2022/09/23/encrypting-sensitive-data-for-transit-or-rest-with-powershell/
.LINK
https://stackoverflow.com/questions/67883498/powershell-password-encryption-decryption-with-key
.LINK
https://medium.com/@sumindaniro/encrypt-decrypt-data-with-powershell-4a1316a0834b
#>
[CmdletBinding(ConfirmImpact = 'Low', DefaultParameterSetName = 'Encryption', PositionalBinding = $True)]
Param
(
[Parameter(Mandatory=$True, ParameterSetName = 'Encryption')]
[Switch]$Encrypt,
[Parameter(Mandatory=$True, ParameterSetName = 'Decryption')]
[Switch]$Decrypt,
[Parameter(Mandatory=$True, ParameterSetName = 'Encryption')]
[Parameter(Mandatory=$True, ParameterSetName = 'Decryption')]
[ValidateNotNullOrEmpty()]
[ValidateSet('AES', 'DES', 'RC2', 'TripleDES')]
[String]$Algorithm,
[Parameter(Mandatory=$True, ParameterSetName = 'Encryption')]
[ValidateNotNullOrEmpty()]
[String[]]$Data,
[Parameter(Mandatory=$True, ParameterSetName = 'Decryption')]
[ValidateNotNullOrEmpty()]
[String]$EncryptedData,
[Parameter(Mandatory=$True, ParameterSetName = 'Decryption')]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$')]
[String]$Key,
[Parameter(Mandatory=$True, ParameterSetName = 'Decryption')]
[ValidateNotNullOrEmpty()]
[ValidatePattern('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$')]
[String]$InitializationVector,
[Parameter(Mandatory=$False, ParameterSetName = 'Encryption')]
[Switch]$Export,
[Parameter(Mandatory=$False, ParameterSetName = 'Encryption')]
[ValidateNotNullOrEmpty()]
[ValidateSet('JSON', 'XML')]
[String]$ExportFormat,
[Parameter(Mandatory=$False, ParameterSetName = 'Encryption')]
[ValidateNotNullOrEmpty()]
[ValidateScript({$_ -imatch '(^([A-Z]\:|\\\\.*\\.*)\\.*\.(json|xml)$)'})]
[System.IO.FileInfo]$ExportPath,
[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)}
$DateTimeXMLFormat = 'yyyy-MM-ddTHH:mm:ss' ###2022-10-24T12:45:15###
[ScriptBlock]$GetCurrentDateTimeXMLFormat = {(Get-Date).ToString($DateTimeXMLFormat)}
$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 = {
$ErrorMessageList = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$ErrorMessageList.Add('Message', $_.Exception.Message)
$ErrorMessageList.Add('Category', $_.Exception.ErrorRecord.FullyQualifiedErrorID)
$ErrorMessageList.Add('Script', $_.InvocationInfo.ScriptName)
$ErrorMessageList.Add('LineNumber', $_.InvocationInfo.ScriptLineNumber)
$ErrorMessageList.Add('LinePosition', $_.InvocationInfo.OffsetInLine)
$ErrorMessageList.Add('Code', $_.InvocationInfo.Line.Trim())
ForEach ($ErrorMessage In $ErrorMessageList.GetEnumerator())
{
$LoggingDetails.ErrorMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - ERROR: $($ErrorMessage.Key): $($ErrorMessage.Value)"
Write-Warning -Message ($LoggingDetails.ErrorMessage)
}
Switch (($ContinueOnError.IsPresent -eq $False) -or ($ContinueOnError -eq $False))
{
{($_ -eq $True)}
{
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)
#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)
[String[]]$SuppliedScriptParameters = $PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key):$($_.Value.GetType().Name)"}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Supplied Function Parameter(s) = $($SuppliedScriptParameters -Join ', ')"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Execution of $($FunctionName) began on $($FunctionStartTime.ToString($DateTimeLogFormat))"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Parameter Set Name: $($PSCmdlet.ParameterSetName)"
Write-Verbose -Message ($LoggingDetails.LogMessage)
#Create an object that will contain the functions output.
$OutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
#Determine the fully qualified Crypto Service Provider based on the specified algorithm
Switch ($Algorithm)
{
{($_ -iin @('AES'))}
{
$CryptoServiceProvider = 'System.Security.Cryptography.AESCryptoServiceProvider'
$CryptoServiceProviderName = 'AESCryptoServiceProvider'
}
{($_ -iin @('DES'))}
{
$CryptoServiceProvider = 'System.Security.Cryptography.DESCryptoServiceProvider'
$CryptoServiceProviderName = 'DESCryptoServiceProvider'
}
{($_ -iin @('RC2'))}
{
$CryptoServiceProvider = 'System.Security.Cryptography.RC2CryptoServiceProvider'
$CryptoServiceProviderName = 'RC2CryptoServiceProvider'
}
{($_ -iin @('TripleDES'))}
{
$CryptoServiceProvider = 'System.Security.Cryptography.TripleDESCryptoServiceProvider'
$CryptoServiceProviderName = 'TripleDESCryptoServiceProvider'
}
}
#Create an object that will contain that encrypted data objects
$EncryptedDataOutputObjectList = New-Object -TypeName 'System.Collections.Generic.List[System.Management.Automation.PSObject]'
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
}
}
Process
{
Try
{
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to symmetrically $($PSCmdlet.ParameterSetName.Replace('ion', '').ToLower()) the provided data using the `"$($Algorithm)`" cryptographic service provider. Please Wait..."
Write-Verbose -Message ($LoggingDetails.LogMessage)
Switch ($PSCmdlet.ParameterSetName)
{
{($_ -iin @('Encryption'))}
{
$OutputObjectProperties.Algorithm = $Algorithm
$OutputObjectProperties.CryptoServiceProvider = $CryptoServiceProvider
$OutputObjectProperties.CryptoServiceProviderName = $CryptoServiceProviderName
$DataObjectCount = ($Data | Measure-Object).Count
For ($DataObjectIndex = 0; $DataObjectIndex -lt $DataObjectCount; $DataObjectIndex++)
{
$DataObject = $Data[$DataObjectIndex]
$EncryptedDataOutputObjectProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$EncryptedDataOutputObjectProperties.Algorithm = $Algorithm
$CryptoServiceDictionary = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$CryptoServiceDictionary.Encoder = [System.Text.Encoding]::UTF8
$CryptoServiceDictionary.Provider = New-Object -TypeName ($CryptoServiceProvider)
$CryptoServiceDictionary.Provider.Mode = [System.Security.Cryptography.CipherMode]::CBC
$CryptoServiceDictionary.Provider.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$CryptoServiceDictionary.Provider.GenerateKey()
$CryptoServiceDictionary.Provider.GenerateIV()
$CryptoServiceDictionary.Encryptor = $CryptoServiceDictionary.Provider.CreateEncryptor($CryptoServiceDictionary.Provider.Key, $CryptoServiceDictionary.Provider.IV)
$CryptoServiceDictionary.DataBytes = $CryptoServiceDictionary.Encoder.GetBytes($DataObject)
$CryptoServiceDictionary.MemoryStream = New-Object -TypeName 'System.IO.MemoryStream'
$CryptoServiceDictionary.CryptoStreamMode = [System.Security.Cryptography.CryptoStreamMode]::Write
$CryptoServiceDictionary.CryptoStreamArgumentList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.MemoryStream)
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.Encryptor)
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.CryptoStreamMode)
$CryptoServiceDictionary.CryptoStream = New-Object -TypeName 'System.Security.Cryptography.CryptoStream' -ArgumentList ($CryptoServiceDictionary.CryptoStreamArgumentList.ToArray())
$CryptoServiceDictionary.StreamWriterArgumentList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
$CryptoServiceDictionary.StreamWriterArgumentList.Add($CryptoServiceDictionary.CryptoStream)
$CryptoServiceDictionary.StreamWriter = New-Object -TypeName 'System.IO.StreamWriter' -ArgumentList ($CryptoServiceDictionary.StreamWriterArgumentList.ToArray())
$CryptoServiceDictionary.StreamWriter.Write($CryptoServiceDictionary.DataBytes, 0, $CryptoServiceDictionary.DataBytes.Length)
$Null = $CryptoServiceDictionary.StreamWriter.Close()
$Null = $CryptoServiceDictionary.CryptoStream.Close()
$Null = $CryptoServiceDictionary.MemoryStream.Close()
$EncryptedDataOutputObjectProperties.EncryptedData = [Convert]::ToBase64String($CryptoServiceDictionary.MemoryStream.ToArray())
$EncryptedDataOutputObjectProperties.Key = [Convert]::ToBase64String($CryptoServiceDictionary.Provider.Key)
$EncryptedDataOutputObjectProperties.InitializationVector = [Convert]::ToBase64String($CryptoServiceDictionary.Provider.IV)
$EncryptedDataOutputObjectProperties.DKIV = "$($EncryptedDataOutputObjectProperties.EncryptedData):$($EncryptedDataOutputObjectProperties.Key):$($EncryptedDataOutputObjectProperties.InitializationVector)"
$EncryptedDataOutputObject = New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($EncryptedDataOutputObjectProperties)
$EncryptedDataOutputObjectList.Add($EncryptedDataOutputObject)
$Null = $CryptoServiceDictionary.Clear()
}
}
{($_ -iin @('Decryption'))}
{
$CryptoServiceDictionary = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
$CryptoServiceDictionary.Encoder = [System.Text.Encoding]::UTF8
$CryptoServiceDictionary.Provider = New-Object -TypeName ($CryptoServiceProvider)
$CryptoServiceDictionary.Provider.Mode = [System.Security.Cryptography.CipherMode]::CBC
$CryptoServiceDictionary.Provider.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$CryptoServiceDictionary.Provider.Key = [System.Convert]::FromBase64String($Key)
$CryptoServiceDictionary.Provider.IV = [System.Convert]::FromBase64String($InitializationVector)
$CryptoServiceDictionary.Decryptor = $CryptoServiceDictionary.Provider.CreateDecryptor($CryptoServiceDictionary.Provider.Key, $CryptoServiceDictionary.Provider.IV)
$CryptoServiceDictionary.DataBytes = [System.Convert]::FromBase64String($EncryptedData)
$CryptoServiceDictionary.MemoryStreamArgumentList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
$CryptoServiceDictionary.MemoryStreamArgumentList.Add($CryptoServiceDictionary.DataBytes)
$CryptoServiceDictionary.MemoryStreamArgumentList.Add(0)
$CryptoServiceDictionary.MemoryStreamArgumentList.Add($CryptoServiceDictionary.DataBytes.Length)
$CryptoServiceDictionary.MemoryStream = New-Object -TypeName 'System.IO.MemoryStream' -ArgumentList ($CryptoServiceDictionary.MemoryStreamArgumentList.ToArray())
$CryptoServiceDictionary.CryptoStreamMode = [System.Security.Cryptography.CryptoStreamMode]::Read
$CryptoServiceDictionary.CryptoStreamArgumentList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.MemoryStream)
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.Decryptor)
$CryptoServiceDictionary.CryptoStreamArgumentList.Add($CryptoServiceDictionary.CryptoStreamMode)
$CryptoServiceDictionary.CryptoStream = New-Object -TypeName 'System.Security.Cryptography.CryptoStream' -ArgumentList ($CryptoServiceDictionary.CryptoStreamArgumentList.ToArray())
$CryptoServiceDictionary.StreamReaderArgumentList = New-Object -TypeName 'System.Collections.Generic.List[Object]'
$CryptoServiceDictionary.StreamReaderArgumentList.Add($CryptoServiceDictionary.CryptoStream)
$CryptoServiceDictionary.StreamReader = New-Object -TypeName 'System.IO.StreamReader' -ArgumentList ($CryptoServiceDictionary.StreamReaderArgumentList.ToArray())
[String]$DecryptedData = $CryptoServiceDictionary.StreamReader.ReadToEnd()
$OutputObjectProperties.DecryptedData = $DecryptedData
$Null = $CryptoServiceDictionary.MemoryStream.Close()
$Null = $CryptoServiceDictionary.CryptoStream.Close()
$Null = $CryptoServiceDictionary.MemoryStream.Close()
$Null = $CryptoServiceDictionary.Clear()
}
}
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
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)
#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)
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Function `'$($FunctionName)`' is completed."
Write-Verbose -Message ($LoggingDetails.LogMessage)
}
Catch
{
$ErrorHandlingDefinition.Invoke()
}
Finally
{
Switch ($PSCmdlet.ParameterSetName)
{
{($_ -iin @('Encryption'))}
{
$OutputObjectProperties.EncryptedDataObjectList = $EncryptedDataOutputObjectList
Switch ($Export.IsPresent)
{
{($_ -eq $True)}
{
Switch ($True)
{
{([String]::IsNullOrEmpty($ExportFormat) -eq $True) -or ([String]::IsNullOrWhiteSpace($ExportFormat) -eq $True)}
{
[String]$ExportFormat = 'JSON'
}
}
$OutputObjectProperties.ExportFormat = $ExportFormat
Switch ($ExportFormat)
{
{($_ -iin @('JSON'))}
{
$OutputObjectProperties.ExportContent = $OutputObjectProperties | ConvertTo-JSON -Depth 10 -Compress:$False
}
{($_ -iin @('XML'))}
{
$XMLWriterSettings = New-Object -TypeName 'System.XML.XMLWriterSettings'
$XMLWriterSettings.Indent = $True
$XMLWriterSettings.IndentChars = "`t" * 1
$XMLWriterSettings.Encoding = [System.Text.Encoding]::Default
$XMLWriterSettings.NewLineHandling = [System.XML.NewLineHandling]::None
$XMLWriterSettings.ConformanceLevel = [System.XML.ConformanceLevel]::Document
$XMLWriterSettings.OmitXmlDeclaration = $False
$XMLStringBuilder = New-Object -TypeName 'System.Text.StringBuilder'
$XMLWriter = [System.XML.XMLTextWriter]::Create($XMLStringBuilder, $XMLwritersettings)
[ScriptBlock]$AddXMLWriterNewLine = {$XMLWriter.WriteWhitespace(("`r`n" * 2))}
$Null = $XMLWriter.WriteStartDocument()
$Null = $AddXMLWriterNewLine.Invoke()
$Null = $XMLWriter.WriteStartElement('Settings')
$Null = $XMLWriter.WriteStartElement('Metadata')
$XMLWriter.WriteElementString('GeneratedDate', $GetCurrentDateTimeXMLFormat.InvokeReturnAsIs())
$Null = $XMLWriter.WriteEndElement()
$Null = $XMLWriter.WriteStartElement('Secrets')
ForEach ($OutputObjectProperty In $OutputObjectProperties.GetEnumerator())
{
Switch ($OutputObjectProperty.Key)
{
{($_ -iin @('Algorithm'))}
{
$XMLWriter.WriteAttributeString($OutputObjectProperty.Key, $OutputObjectProperty.Value)
}
}
}
ForEach ($EncryptedDataObject In $OutputObjectProperties.EncryptedDataObjectList)
{
$SecretID = [System.GUID]::NewGUID().ToString().ToUpper()
$Null = $XMLWriter.WriteStartElement('Secret')
$Null = $XMLWriter.WriteAttributeString('Enabled', $True)
$Null = $XMLWriter.WriteAttributeString('ID', $SecretID)
ForEach ($EncryptedDataObjectProperty In $EncryptedDataObject.PSObject.Properties)
{
Switch (($Null -ine $EncryptedDataObjectProperty.Value) -and ([String]::IsNullOrEmpty($EncryptedDataObjectProperty.Value) -eq $False) -and ([String]::IsNullOrWhiteSpace($EncryptedDataObjectProperty.Value) -eq $False))
{
{($_ -eq $True)}
{
Switch ($True)
{
{($EncryptedDataObjectProperty.Name -iin @('EncryptedData', 'Key', 'InitializationVector'))}
{
$Null = $XMLWriter.WriteStartElement($EncryptedDataObjectProperty.Name)
$XMLWriter.WriteCData($EncryptedDataObjectProperty.Value)
$Null = $XMLWriter.WriteEndElement()
}
}
}
}
}
$Null = $XMLWriter.WriteEndElement()
}
$Null = $XMLWriter.WriteEndElement()
$Null = $XMLWriter.WriteEndElement()
$Null = $XMLWriter.WriteEndDocument()
$Null = $XMLWriter.Flush()
$Null = $XMLWriter.Close()
$OutputObjectProperties.ExportContent = $XMLStringBuilder.ToString() -ireplace '(utf\-\d+)', 'utf-8'
}
}
Switch (([String]::IsNullOrEmpty($ExportPath) -eq $False) -and ([String]::IsNullOrEmpty($ExportPath) -eq $False))
{
{($_ -eq $True)}
{
$OutputObjectProperties.ExportPath = $ExportPath.FullName
Switch ([System.IO.Directory]::Exists($ExportPath.Directory.FullName))
{
{($_ -eq $False)}
{
$Null = [System.IO.Directory]::CreateDirectory($ExportPath.Directory.FullName)
}
}
$LoggingDetails.LogMessage = "$($GetCurrentDateTimeMessageFormat.Invoke()) - Attempting to export the encrypted contents for $($DataObjectCount) secret(s) in $($ExportFormat) format. Please Wait. [Path: $($ExportPath.FullName)]"
Write-Verbose -Message ($LoggingDetails.LogMessage)
$Null = [System.IO.File]::WriteAllText($ExportPath.FullName, $OutputObjectProperties.ExportContent, $XMLWriterSettings.Encoding)
}
Default
{
$OutputObjectProperties.ExportPath = $Null
}
}
}
}
}
}
Switch ($PSCmdlet.ParameterSetName)
{
{($_ -iin @('Encryption'))}
{
$OutputObject = New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
{($_ -iin @('Decryption'))}
{
#$OutputObject = $DecryptedData
$OutputObject = New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($OutputObjectProperties)
Write-Output -InputObject ($OutputObject)
}
}
}
}
}
#endregion