Convert.psm1

<#
    .SYNOPSIS
        Converts a base64 encoded string to a string.

    .DESCRIPTION
        Converts a base64 encoded string to a string.

    .PARAMETER Base64
        A Base64 Encoded String.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER ToString
        Switch parameter to specify a conversion to a string object.

    .PARAMETER Decompress
        If supplied, the output will be decompressed using Gzip.

    .EXAMPLE
        ConvertFrom-Base64 -Base64 'QSBzdHJpbmc=' -ToString

        A string

    .EXAMPLE
        ConvertTo-Base64 -Base64 'A string','Another string' -ToString

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        'QSBzdHJpbmc=' | ConvertFrom-Base64 -ToString

        A string

    .EXAMPLE
        'QSBzdHJpbmc=','QW5vdGhlciBzdHJpbmc=' | ConvertFrom-Base64 -ToString

        A string
        Another string

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Base64/
#>

function ConvertFrom-Base64
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Base64/')]
    [OutputType('String')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('String', 'Base64String')]
        [String[]]
        $Base64,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(Mandatory = $false)]
        [Switch]
        $ToString,

        [Parameter(Mandatory = $false)]
        [Switch]
        $Decompress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($b64 in $Base64)
        {
            try
            {
                $bytes = [System.Convert]::FromBase64String($b64)

                if ($ToString)
                {
                    if ($Decompress)
                    {
                        ConvertFrom-CompressedByteArrayToString -ByteArray $bytes -Encoding $Encoding
                    }
                    else
                    {
                        [System.Text.Encoding]::$Encoding.GetString($bytes)
                    }
                }
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
    Converts a Base 64 Encoded String to a Byte Array

    .DESCRIPTION
    Converts a Base 64 Encoded String to a Byte Array

    .PARAMETER String
    The Base 64 Encoded String to be converted

    .EXAMPLE
    PS C:\> ConvertFrom-Base64ToByteArray -String 'dGVzdA=='
    116
    101
    115
    116

    Converts the base64 string to its byte array representation.

    .LINK
    https://msdn.microsoft.com/en-us/library/system.convert.frombase64string%28v=vs.110%29.aspx
#>

function ConvertFrom-Base64ToByteArray
{
    [CmdletBinding()]
    [Alias('ConvertFrom-Base64StringToByteArray')]
    param
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Base64String')]
        [String]$String
    )
    [System.Convert]::FromBase64String($String)
}


<#
    .SYNOPSIS
        Converts a base64 encoded string to a string.

    .DESCRIPTION
        Converts a base64 encoded string to a string.

    .PARAMETER String
        A Base64 Encoded String

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Decompress
        If supplied, the output will be decompressed using Gzip.

    .EXAMPLE
        ConvertFrom-Base64ToString -String 'QSBzdHJpbmc='

        A string

    .EXAMPLE
        ConvertTo-Base64 -String 'A string','Another string'

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        'QSBzdHJpbmc=' | ConvertFrom-Base64ToString

        A string

    .EXAMPLE
        'QSBzdHJpbmc=','QW5vdGhlciBzdHJpbmc=' | ConvertFrom-Base64ToString

        A string
        Another string

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Base64ToString/
#>

function ConvertFrom-Base64ToString
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Base64ToString/')]
    [OutputType('String')]
    [Alias('ConvertFrom-Base64StringToString')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Base64String')]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(Mandatory = $false)]
        [Switch]
        $Decompress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($s in $String)
        {
            try
            {
                $bytes = [System.Convert]::FromBase64String($s)

                if ($Decompress)
                {
                    ConvertFrom-CompressedByteArrayToString -ByteArray $bytes -Encoding $Encoding
                }
                else
                {
                    [System.Text.Encoding]::$Encoding.GetString($bytes)
                }
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts a byte array to a base64 encoded string.

    .DESCRIPTION
        Converts a byte array to a base64 encoded string.

    .PARAMETER ByteArray
        A byte array object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .EXAMPLE
        $bytes = ConvertFrom-StringToCompressedByteArray -String 'A string'
        ConvertFrom-ByteArrayToBase64 -ByteArray $bytes

        H4sIAAAAAAAAC3NUKC4pysxLBwCMN9RgCAAAAA==

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-ByteArrayToBase64/
#>

function ConvertFrom-ByteArrayToBase64
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-ByteArrayToBase64/')]
    [Alias('ConvertFrom-ByteArrayToBase64String')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Bytes')]
        [Byte[]]
        $ByteArray,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8'
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        try
        {
            [System.Convert]::ToBase64String($ByteArray)
        }
        catch
        {
            Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
        }
    }
}


<#
    .SYNOPSIS
    Converts a Byte Array to a MemoryStream

    .DESCRIPTION
    Converts a Byte Array to a MemoryStream

    .PARAMETER ByteArray
    The Byte Array to be converted

    .LINK
    https://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.110).aspx

    .NOTES
    Additional information:
    https://msdn.microsoft.com/en-us/library/63z365ty(v=vs.110).aspx

    .EXAMPLE
    ConvertFrom-ByteArrayToMemoryStream -ByteArray ([Byte[]] (,0xFF * 100))

    This command uses the ConvertFrom-ByteArrayToMemoryStream cmdlet to convert a Byte Array into a Memory Stream.
#>

function ConvertFrom-ByteArrayToMemoryStream
{
    param
    (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Alias('Bytes')]
        [System.Byte[]]$ByteArray
    )
    [System.IO.MemoryStream]::new($ByteArray, 0, $ByteArray.Length)
}


<#
    .SYNOPSIS
        Converts Clixml to an object.
    
    .DESCRIPTION
        Converts Clixml to an object.
    
    .PARAMETER String
        Clixml as a string object.
    
    .EXAMPLE
        $xml = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>ThisIsMyString</S>
</Objs>
"@
        ConvertFrom-Clixml -String $xml

        ThisIsMyString
    
    .EXAMPLE
        $xml = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>ThisIsMyString</S>
</Objs>
"@
        $xml | ConvertFrom-Clixml

        ThisIsMyString
    
    .EXAMPLE
        $xml = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>ThisIsMyString</S>
</Objs>
"@
        $xml2 = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>This is another string</S>
</Objs>
"@
        ConvertFrom-Clixml -String $xml,$xml2

        ThisIsMyString
        This is another string
        
    .EXAMPLE
        $xml = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>ThisIsMyString</S>
</Objs>
"@
        $xml2 = @"
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<S>This is another string</S>
</Objs>
"@
        $xml,$xml2 | ConvertFrom-Clixml

        ThisIsMyString
        This is another string

    .OUTPUTS
        [Object[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Clixml/
#>

function ConvertFrom-Clixml
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-Clixml/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
        Set-Variable -Name 'SPLIT' -Value '(?<!^)(?=<Objs)' -Option 'Constant'
    }
    
    process
    {
        foreach ($s in $String)
        {
            try
            {
                foreach ($record in ($s -split $SPLIT))
                {
                    [System.Management.Automation.PSSerializer]::Deserialize($record)
                }
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts a string to a byte array object.

    .DESCRIPTION
        Converts a string to a byte array object.

    .PARAMETER ByteArray
        The array of bytes to convert.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .EXAMPLE
        $bytes = ConvertFrom-CompressedByteArrayToString -String 'A string
        $bytes.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $bytes[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte System.ValueType

    .OUTPUTS
        [Byte[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-CompressedByteArrayToString/
#>

function ConvertFrom-CompressedByteArrayToString
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-CompressedByteArrayToString/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Byte[]]
        $ByteArray,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8'
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        try
        {
            $inputStream = [System.IO.MemoryStream]::new($ByteArray)
            $output = [System.IO.MemoryStream]::new()

            $gzipStream = [System.IO.Compression.GzipStream]::new($inputStream, ([IO.Compression.CompressionMode]::Decompress))
            $gzipStream.CopyTo($output)
            $gzipStream.Close()
            $inputStream.Close()

            [System.Text.Encoding]::$Encoding.GetString($output.ToArray())
        }
        catch
        {
            Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
        }
    }
}

<#
    .SYNOPSIS
        Converts MemoryStream to a base64 encoded string.

    .DESCRIPTION
        Converts MemoryStream to a base64 encoded string.

    .PARAMETER MemoryStream
        A MemoryStream object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER ToString
        Switch parameter to specify a conversion to a string object.

    .PARAMETER ToBase64
        Switch parameter to specify a conversion to a Base64 encoded string object.

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        ConvertFrom-MemoryStream -MemoryStream $stream -ToBase64

        QSBzdHJpbmc=

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        $stream | ConvertFrom-MemoryStream -ToBase64

        QSBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertFrom-MemoryStream -MemoryStream $stream1,$stream2 -ToBase64

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertFrom-MemoryStream -ToBase64

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        ConvertFrom-MemoryStream -MemoryStream $stream -ToString

        A string

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        $stream | ConvertFrom-MemoryStream -ToString

        A string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertFrom-MemoryStream -MemoryStream $stream1,$stream2 -ToString

        A string
        Another string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertFrom-MemoryStream -ToString

        A string
        Another string

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStream/
#>

function ConvertFrom-MemoryStream
{
    [CmdletBinding(
        HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStream/',
        DefaultParameterSetName = 'ToString'
    )]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(ParameterSetName = 'ToString')]
        [Switch]
        $ToString,

        [Parameter(ParameterSetName = 'ToBase64')]
        [Switch]
        $ToBase64
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($m in $MemoryStream)
        {
            try
            {
                $string = ConvertFrom-MemoryStreamToString -MemoryStream $m -ErrorAction Stop

                switch ($PSCmdlet.ParameterSetName)
                {
                    'ToString'
                    {
                        $string
                    }

                    'ToBase64'
                    {
                        ConvertFrom-StringToBase64 -String $string -Encoding $Encoding
                    }
                }
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts MemoryStream to a base64 encoded string.
    
    .DESCRIPTION
        Converts MemoryStream to a base64 encoded string.
    
    .PARAMETER MemoryStream
        A MemoryStream object for conversion.
    
    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.
    
    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        ConvertFrom-MemoryStreamToBase64 -MemoryStream $stream
        
        QSBzdHJpbmc=

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        $stream | ConvertFrom-MemoryStreamToBase64

        QSBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertFrom-MemoryStreamToBase64 -MemoryStream $stream1,$stream2

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertFrom-MemoryStreamToBase64

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStreamToBase64/
#>

function ConvertFrom-MemoryStreamToBase64
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStreamToBase64/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8'
    )
    
    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($m in $MemoryStream)
        {
            try
            {
                $string = ConvertFrom-MemoryStreamToString -MemoryStream $m
                ConvertFrom-StringToBase64 -String $string -Encoding $Encoding
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
    Converts a Memory Stream to a Secure String

    .DESCRIPTION
    This cmdlet converts a Memory Stream to a Secure String using a Stream Reader object.

    .PARAMETER MemoryStream
    A System.IO.MemoryStream object for conversion.

    .PARAMETER Stream
    A System.IO.Stream object for conversion.

    .EXAMPLE
    $string = 'My Super Secret Value'
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
    $memoryStream = [System.IO.MemoryStream]::new($bytes, 0, $bytes.Length)
    $secure = ConvertFrom-MemoryStreamToSecureString -MemoryStream $memoryStream
    $credential = [PSCredential]::new('MyValue', $secure)

    Converts the provided MemoryStream to a SeureString.

    .LINK
    https://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx

    .NOTES
    Additional information:
    https://msdn.microsoft.com/en-us/library/system.io.streamreader%28v=vs.110%29.aspx
    https://msdn.microsoft.com/en-us/library/system.security.securestring%28v=vs.110%29.aspx
#>

function ConvertFrom-MemoryStreamToSecureString
{
    [CmdletBinding(DefaultParameterSetName='MemoryStream')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'MemoryStream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'Stream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.Stream[]]
        $Stream
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'MemoryStream'
            {
                $inputObject = $MemoryStream
            }
            'Stream'
            {
                $inputObject = $Stream
            }
        }

        foreach ($object in $inputObject)
        {
            try
            {
                $secureString = [System.Security.SecureString]::new()
                $reader = [System.IO.StreamReader]::new($object)
            
                while ($reader.Peek() -ge 0)
                {
                    $secureString.AppendChar($reader.Read())
                }
                $secureString.MakeReadOnly()
            
                $secureString    
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
            finally
            {
                $reader.Dispose()
            }
        }    
    }
}


<#
    .SYNOPSIS
        Converts MemoryStream to a string.

    .DESCRIPTION
        Converts MemoryStream to a string.

    .PARAMETER MemoryStream
        A System.IO.MemoryStream object for conversion.

    .PARAMETER Stream
        A System.IO.Stream object for conversion.

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        ConvertFrom-MemoryStreamToString -MemoryStream $stream

        A string

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        $stream | ConvertFrom-MemoryStreamToString

        A string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertFrom-MemoryStreamToString -MemoryStream $stream1,$stream2

        A string
        Another string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertFrom-MemoryStreamToString

        A string
        Another string

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStreamToString/
#>

function ConvertFrom-MemoryStreamToString
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-MemoryStreamToString/')]
    [Alias('ConvertFrom-StreamToString')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'MemoryStream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'Stream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.Stream[]]
        $Stream
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'MemoryStream'
            {
                $inputObject = $MemoryStream
            }
            'Stream'
            {
                $inputObject = $Stream
            }
        }

        foreach ($object in $inputObject)
        {
            try
            {
                $reader = [System.IO.StreamReader]::new($object)
                if ($PSCmdlet.ParameterSetName -eq 'MemoryStream')
                {
                    $object.Position = 0
                }
                $reader.ReadToEnd()
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
            finally
            {
                if ($reader)
                {
                    $reader.Dispose()
                }
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts a string to a base64 encoded string.

    .DESCRIPTION
        Converts a string to a base64 encoded string.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Compress
        If supplied, the output will be compressed using Gzip.

    .EXAMPLE
        ConvertFrom-StringToBase64 -String 'A string'
        QSBzdHJpbmc=

    .EXAMPLE
        'A string' | ConvertFrom-StringToBase64
        QSBzdHJpbmc=

    .EXAMPLE
        ConvertFrom-StringToBase64 -String 'A string' -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        'A string' | ConvertFrom-StringToBase64 -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        ConvertFrom-StringToBase64 -String 'A string','Another string'
        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        'A string','Another string' | ConvertFrom-StringToBase64
        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        ConvertFrom-StringToBase64 -String 'A string','Another string' -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==
        QQBuAG8AdABoAGUAcgAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        'A string','Another string' | ConvertFrom-StringToBase64 -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==
        QQBuAG8AdABoAGUAcgAgAHMAdAByAGkAbgBnAA==

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToBase64/
#>

function ConvertFrom-StringToBase64
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToBase64/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(Mandatory = $false)]
        [Switch]
        $Compress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($s in $String)
        {
            try
            {
                if ($Compress)
                {
                    $bytes = ConvertFrom-StringToCompressedByteArray -String $s -Encoding $Encoding
                }
                else
                {
                    $bytes = [System.Text.Encoding]::$Encoding.GetBytes($s)
                }

                [System.Convert]::ToBase64String($bytes)
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts a string to a byte array object.

    .DESCRIPTION
        Converts a string to a byte array object.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .EXAMPLE
        $bytes = ConvertFrom-StringToByteArray -String 'A string'
        $bytes.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte[] System.Array

        $bytes[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte System.ValueType

    .EXAMPLE
        $bytes = 'A string','Another string' | ConvertFrom-StringToByteArray

        $bytes.Count
        2

        $bytes.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $bytes[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte[] System.Array

    .OUTPUTS
        [System.Collections.Generic.List[Byte[]]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToByteArray/
#>

function ConvertFrom-StringToByteArray
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToByteArray/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8'
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($s in $String)
        {
            # Creating a generic list to ensure an array of string being handed in
            # outputs an array of Byte arrays, rather than a single array with both
            # Byte arrays merged.
            $byteArrayObject = [System.Collections.Generic.List[Byte[]]]::new()
            try
            {
                $byteArray = [System.Text.Encoding]::$Encoding.GetBytes($s)
                $null = $byteArrayObject.Add($byteArray)
                $byteArrayObject
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}

<#
    .SYNOPSIS
        Converts a string to a compressed byte array object.

    .DESCRIPTION
        Converts a string to a compressed byte array object.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .EXAMPLE
        $bytes = ConvertFrom-StringToCompressedByteArray -String 'A string'
        $bytes.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte[] System.Array

        $bytes[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Byte System.ValueType

    .OUTPUTS
        [System.Collections.Generic.List[Byte[]]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToCompressedByteArray/
#>

function ConvertFrom-StringToCompressedByteArray
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToCompressedByteArray/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8'
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($s in $String)
        {
            # Creating a generic list to ensure an array of string being handed in
            # outputs an array of Byte arrays, rather than a single array with both
            # Byte arrays merged.
            $byteArrayObject = [System.Collections.Generic.List[Byte[]]]::new()
            try
            {
                $byteArray = [System.Text.Encoding]::$Encoding.GetBytes($s)

                [System.IO.MemoryStream] $output = [System.IO.MemoryStream]::new()
                $gzipStream = [System.IO.Compression.GzipStream]::new($output, ([IO.Compression.CompressionMode]::Compress))
                $gzipStream.Write( $byteArray, 0, $byteArray.Length )
                $gzipStream.Close()
                $output.Close()

                $null = $byteArrayObject.Add($output.ToArray())
                $byteArrayObject
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}

<#
    .SYNOPSIS
        Converts a string to a MemoryStream object.

    .DESCRIPTION
        Converts a string to a MemoryStream object.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Compress
        If supplied, the output will be compressed using Gzip.

    .EXAMPLE
        $stream = ConvertFrom-StringToMemoryStream -String 'A string'
        $stream.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $stream = 'A string' | ConvertFrom-StringToMemoryStream
        $stream.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $streams = ConvertFrom-StringToMemoryStream -String 'A string','Another string'
        $streams.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $streams[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $streams = 'A string','Another string' | ConvertFrom-StringToMemoryStream
        $streams.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $streams[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $stream = ConvertFrom-StringToMemoryStream -String 'This string has two string values'
        $stream.Length

        33

        $stream = ConvertFrom-StringToMemoryStream -String 'This string has two string values' -Compress
        $stream.Length

        10

    .OUTPUTS
        [System.IO.MemoryStream[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToMemoryStream/
#>

function ConvertFrom-StringToMemoryStream
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToMemoryStream/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Switch]
        $Compress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($s in $String)
        {
            try
            {
                [System.IO.MemoryStream]$stream = [System.IO.MemoryStream]::new()
                if ($Compress)
                {
                    $byteArray = [System.Text.Encoding]::$Encoding.GetBytes($s)
                    $gzipStream = [System.IO.Compression.GzipStream]::new($stream, ([IO.Compression.CompressionMode]::Compress))
                    $gzipStream.Write( $byteArray, 0, $byteArray.Length )
                }
                else
                {
                    $writer = [System.IO.StreamWriter]::new($stream)
                    $writer.Write($s)
                    $writer.Flush()
                }
                $stream
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}

<#
    .SYNOPSIS
        Converts a string to a base64 encoded string.

    .DESCRIPTION
        Converts a string to a base64 encoded string.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER MemoryStream
        A MemoryStream object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Compress
        If supplied, the output will be compressed using Gzip.

    .EXAMPLE
        $string = 'A string'
        ConvertTo-Base64 -String $string
        QSBzdHJpbmc=

    .EXAMPLE
        (Get-Module -Name PowerShellGet | ConvertTo-Clixml | ConvertTo-Base64).Length
        1057480

        (Get-Module -Name PowerShellGet | ConvertTo-Clixml | ConvertTo-Base64 -Compress).Length
        110876

    .EXAMPLE
        $string = 'A string'
        $string | ConvertTo-Base64
        QSBzdHJpbmc=

    .EXAMPLE
        $string = 'A string'
        ConvertTo-Base64 -String $string -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        $string = 'A string'
        $string | ConvertTo-Base64 -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        ConvertTo-Base64 -String $string1,$string2
        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        $string1,$string2 | ConvertTo-Base64
        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        ConvertTo-Base64 -String $string1,$string2 -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==
        QQBuAG8AdABoAGUAcgAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        $string1,$string2 | ConvertTo-Base64 -Encoding Unicode
        QQAgAHMAdAByAGkAbgBnAA==
        QQBuAG8AdABoAGUAcgAgAHMAdAByAGkAbgBnAA==

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        ConvertTo-Base64 -MemoryStream $stream

        QSBzdHJpbmc=

    .EXAMPLE
        $string = 'A string'
        $stream = [System.IO.MemoryStream]::new()
        $writer = [System.IO.StreamWriter]::new($stream)
        $writer.Write($string)
        $writer.Flush()

        $stream | ConvertTo-Base64

        QSBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertTo-Base64 -MemoryStream $stream1,$stream2

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertTo-Base64

        QSBzdHJpbmc=
        QW5vdGhlciBzdHJpbmc=

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertTo-Base64/
#>

function ConvertTo-Base64
{
    [CmdletBinding(
        DefaultParameterSetName = 'String',
        HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertTo-Base64/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'String')]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'MemoryStream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(Mandatory = $false)]
        [Switch]
        $Compress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference

        $convertSplat = @{
            Encoding    = $Encoding
            ErrorAction = $userErrorActionPreference
        }
    }

    process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'String'
            {
                foreach ($s in $string)
                {
                    if ($Compress)
                    {
                        ConvertFrom-StringToBase64 -String $s @convertSplat -Compress
                    }
                    else
                    {
                        ConvertFrom-StringToBase64 -String $s @convertSplat
                    }
                }
                break
            }

            'MemoryStream'
            {
                foreach ($m in $MemoryStream)
                {
                    if ($Compress)
                    {
                        $string = ConvertFrom-MemoryStreamToString -MemoryStream $m @convertSplat
                        $byteArray = ConvertFrom-StringToCompressedByteArray -String $s @convertSplat
                        ConvertFrom-ByteArrayToBase64 -ByteArray $byteArray @convertSplat
                    }
                    else
                    {
                        ConvertFrom-MemoryStreamToBase64 -MemoryStream $m @convertSplat
                    }
                }
                break
            }

            default
            {
                Write-Error -Message 'Invalid ParameterSetName' -ErrorAction $userErrorActionPreference
                break
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts an object to Clixml.

    .DESCRIPTION
        Converts an object to Clixml.

    .PARAMETER InputObject
        The input object to serialize

    .PARAMETER Depth
        The depth of the members to serialize

    .EXAMPLE
        $string = 'A string'
        ConvertTo-Clixml -InputObject $string

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>A string</S>
</Objs>

    .EXAMPLE
        $string = 'A string'
        $string | ConvertTo-Clixml

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>A string</S>
</Objs>

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        ConvertTo-Clixml -InputObject $string1,$string2

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>A string</S>
</Objs>
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>Another string</S>
</Objs>

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'
        $string1,$string2 | ConvertTo-Clixml

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>A string</S>
</Objs>
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <S>Another string</S>
</Objs>

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertTo-Clixml/
#>

function ConvertTo-Clixml
{
    [CmdletBinding(HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertTo-Clixml/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [PSObject]
        $InputObject,

        [Parameter(Mandatory = $false)]
        [ValidateRange(1, [Int32]::MaxValue)]
        [Int32]
        $Depth = 1
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        foreach ($io in $InputObject)
        {
            try
            {
                [System.Management.Automation.PSSerializer]::Serialize($io, $Depth)
            }
            catch
            {
                Write-Error -ErrorRecord $_ -ErrorAction $userErrorActionPreference
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts an object to a MemoryStream object.

    .DESCRIPTION
        Converts an object to a MemoryStream object.

    .PARAMETER String
        A string object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Compress
        If supplied, the output will be compressed using Gzip.

    .EXAMPLE
        $string = 'A string'
        $stream = ConvertTo-MemoryStream -String $string
        $stream.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $string = 'A string'
        $stream = $string | ConvertTo-MemoryStream
        $stream.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'

        $streams = ConvertTo-MemoryStream -String $string1,$string2
        $streams.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $streams[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .EXAMPLE
        $string1 = 'A string'
        $string2 = 'Another string'

        $streams = $string1,$string2 | ConvertTo-MemoryStream
        $streams.GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True Object[] System.Array

        $streams[0].GetType()

        IsPublic IsSerial Name BaseType
        -------- -------- ---- --------
        True True MemoryStream System.IO.Stream

    .OUTPUTS
        [System.IO.MemoryStream[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertTo-MemoryStream/
#>

function ConvertTo-MemoryStream
{
    [CmdletBinding(
        DefaultParameterSetName = 'String',
        HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertTo-MemoryStream/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'String')]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $String,

        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Switch]
        $Compress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
        $eaSplat = @{
            ErrorAction = $userErrorActionPreference
        }
    }

    process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'String'
            {
                foreach ($s in $string)
                {
                    if ($Compress)
                    {
                        ConvertFrom-StringToMemoryStream -String $s -Compress @eaSplat
                    }
                    else
                    {
                        ConvertFrom-StringToMemoryStream -String $s @eaSplat
                    }
                }
                break
            }

            default
            {
                Write-Error -Message 'Invalid ParameterSetName' @eaSplat
                break
            }
        }
    }
}


<#
    .SYNOPSIS
        Converts a base64 encoded string to a string.

    .DESCRIPTION
        Converts a base64 encoded string to a string.

    .PARAMETER Base64EncodedString
        A Base64 Encoded String

    .PARAMETER MemoryStream
        A MemoryStream object for conversion.

    .PARAMETER Stream
        A System.IO.Stream object for conversion.

    .PARAMETER Encoding
        The encoding to use for conversion.
        Defaults to UTF8.
        Valid options are ASCII, BigEndianUnicode, Default, Unicode, UTF32, UTF7, and UTF8.

    .PARAMETER Decompress
        If supplied, the output will be decompressed using Gzip.

    .EXAMPLE
        ConvertTo-String -Base64EncodedString 'QSBzdHJpbmc='

        A string

    .EXAMPLE
        ConvertTo-String -Base64EncodedString 'QSBzdHJpbmc=','QW5vdGhlciBzdHJpbmc='

        A string
        Another string

    .EXAMPLE
        'QSBzdHJpbmc=' | ConvertTo-String

        A string

    .EXAMPLE
        'QSBzdHJpbmc=','QW5vdGhlciBzdHJpbmc=' | ConvertTo-String

        A string
        Another string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        ConvertTo-String -MemoryStream $stream1,$stream2

        A string
        Another string

    .EXAMPLE
        $string1 = 'A string'
        $stream1 = [System.IO.MemoryStream]::new()
        $writer1 = [System.IO.StreamWriter]::new($stream1)
        $writer1.Write($string1)
        $writer1.Flush()

        $string2 = 'Another string'
        $stream2 = [System.IO.MemoryStream]::new()
        $writer2 = [System.IO.StreamWriter]::new($stream2)
        $writer2.Write($string2)
        $writer2.Flush()

        $stream1,$stream2 | ConvertTo-String

        A string
        Another string

    .OUTPUTS
        [String[]]

    .LINK
        http://convert.readthedocs.io/en/latest/functions/ConvertTo-String/
#>

function ConvertTo-String
{
    [CmdletBinding(
        DefaultParameterSetName = 'Base64String',
        HelpUri = 'http://convert.readthedocs.io/en/latest/functions/ConvertFrom-StringToMemoryStream/')]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'Base64String')]
        [ValidateNotNullOrEmpty()]
        [String[]]
        $Base64EncodedString,

        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'MemoryStream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.MemoryStream[]]
        $MemoryStream,

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            ParameterSetName = 'Stream')]
        [ValidateNotNullOrEmpty()]
        [System.IO.Stream[]]
        $Stream,

        [Parameter(ParameterSetName = 'Base64String')]
        [ValidateSet('ASCII', 'BigEndianUnicode', 'Default', 'Unicode', 'UTF32', 'UTF7', 'UTF8')]
        [String]
        $Encoding = 'UTF8',

        [Parameter(Mandatory = $false, ParameterSetName = 'Base64String')]
        [Switch]
        $Decompress
    )

    begin
    {
        $userErrorActionPreference = $ErrorActionPreference
    }

    process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            'Base64String'
            {
                $InputObject = $Base64EncodedString
                $Function = 'ConvertFrom-Base64ToString'
                $splat = @{
                    Encoding = $Encoding
                }
                if ($Decompress)
                {
                    $splat.Add('Decompress', $true)
                }
                break
            }

            'MemoryStream'
            {
                $InputObject = $MemoryStream
                $Function = 'ConvertFrom-MemoryStreamToString'
                $splat = @{}
                break
            }

            'Stream'
            {
                $InputObject = $Stream
                $Function = 'ConvertFrom-MemoryStreamToString'
                $splat = @{}
                break
            }

            default
            {
                Write-Error -Message 'Invalid ParameterSetName' -ErrorAction $userErrorActionPreference
                break
            }
        }

        if ($InputObject)
        {
            $InputObject | & $Function @splat -ErrorAction $userErrorActionPreference
        }
    }
}