Home > Enterprise >  How do I convert a PowerShell script to Base64?
How do I convert a PowerShell script to Base64?

Time:04-10

I have been working my brain on this one and can not figure out how I'm losing integrity here...

I have the following script I am trying to convert to Base64:

Function Get-Networks { 
    $Network = Get-WmiObject Win32_NetworkAdapterConfiguration | where { $_.MACAddress -notlike $null }  | select Index, Description, IPAddress, DefaultIPGateway, MACAddress | Format-Table Index, Description, IPAddress, DefaultIPGateway, MACAddress     
    $WLANProfileNames = @() 
    $Output = netsh.exe wlan show profiles | Select-String -pattern " : " 
    Foreach ($WLANProfileName in $Output) {     
        $WLANProfileNames  = (($WLANProfileName -split ":")[1]).Trim() 
    } 
    $WLANProfileObjects = @() 
    Foreach ($WLANProfileName in $WLANProfileNames) {     
        try {         
            $WLANProfilePassword = (((netsh.exe wlan show profiles name="$WLANProfileName" key=clear | select-string -Pattern "Key Content") -split ":")[1]).Trim()     
        }
        Catch {         
            $WLANProfilePassword = "The password is not stored in this profile"     
        }     
        $WLANProfileObject = New-Object PSCustomobject      
        $WLANProfileObject | Add-Member -Type NoteProperty -Name "ProfileName" -Value $WLANProfileName     
        $WLANProfileObject | Add-Member -Type NoteProperty -Name "ProfilePassword" -Value $WLANProfilePassword     
        $WLANProfileObjects  = $WLANProfileObject     
        Remove-Variable WLANProfileObject  
        return $WLANProfileObjects 
    } 
}  
$Networks = Get-Networks 
echo $Networks

initially, I was using the following snippet to do it. This would read the contents of my file to a variable and then convert it. I noticed when I converted it back this was outputting everything to one line and messing up the formatting

$Content = Get-Content -Path $FilePath    
$converted = [convert]::ToBase64String([System.Text.encoding]::Unicode.GetBytes($Content))

So I then switched to the following snippet to convert it using the file path instead of saving the content to a variable and I was pleased to see when I converted it back it maintained its integrity.

[convert]::ToBase64String((Get-Content -path $FilePath -Encoding byte))

but when I tried to execute it, this time it threw the following errors and I couldn't be more confused

畆据楴湯䜠瑥中瑥潷歲⁳ൻ␊敎睴牯‽敇⵴浗佩橢捥⁴楗㍮弲敎睴牯䅫慤瑰牥潃普杩牵瑡潩⁼桷牥⁥⁻弤䴮䍁摁牤獥⁳渭瑯楬敫␠畮汬素†⁼敳敬瑣䤠摮硥‬敄捳楲瑰潩Ɱ䤠䅐摤敲獳‬敄慦汵䥴䝐瑡睥祡‬䅍䅃摤敲獳簠䘠牯慭⵴慔汢⁥湉敤ⱸ䐠獥牣灩楴湯‬偉摁牤獥ⱳ䐠晥畡瑬 偉慇整慷ⱹ䴠䍁摁牤獥⁳ഉ␊䱗乁牐景汩乥浡獥㴠⡀ഩ␊畏灴瑵㴠渠瑥桳攮數眠慬桳睯瀠潲楦敬⁳⁼敓敬瑣匭牴湩⁧瀭瑡整湲∠㨠∠਍潆敲捡⡨圤䅌偎潲楦敬慎敭椠伤瑵異⥴ൻ : The term
'畆据楴湯䜠瑥中瑥潷歲⁳ൻ␊敎睴牯‽敇⵴浗佩橢捥⁴楗㍮弲敎睴牯䅫慤瑰牥潃普杩牵瑡潩⁼桷牥⁥⁻弤䴮䍁摁牤獥⁳渭瑯楬敫␠畮汬素†⁼敳敬瑣䤠摮硥‬敄捳楲瑰潩Ɱ䤠䅐摤敲獳‬敄慦汵䥴䝐瑡睥祡‬䅍䅃摤敲獳簠䘠牯慭⵴慔汢⁥湉敤ⱸ䐠獥牣灩楴湯‬偉摁牤獥ⱳ䐠晥畡瑬偉慇整慷ⱹ䴠䍁摁牤獥⁳ഉ␊䱗乁牐景汩乥浡獥㴠⡀ഩ␊畏灴瑵㴠渠瑥桳攮數眠慬桳睯瀠潲楦敬⁳⁼敓敬瑣匭牴湩⁧瀭瑡整湲∠㨠∠਍潆敲捡⡨圤䅌偎潲楦敬慎敭椠伤瑵異⥴ൻ' is not recognized
as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
  畆据楴湯䜠瑥中瑥潷歲⁳ൻ␊敎睴牯‽敇⵴浗佩橢捥⁴楗㍮弲敎睴牯䅫慤瑰牥潃普杩牵瑡潩⁼桷牥⁥⁻弤䴮䍁摁牤獥⁳渭瑯楬敫␠畮汬素†⁼敳敬瑣䤠摮 ...
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : ObjectNotFound: (畆据楴湯䜠瑥中瑥潷歲⁳ൻ␊敎睴...圤䅌偎潲楦敬慎敭椠伤瑵異⥴ൻ:String) [], CommandNotFoundException

How do I simply write a script to convert this file to base64 so I can execute it properly?

CodePudding user response:

To complement your own, effective solution with some background information:

  • Base64 encoding is an ASCII-string-based encoding of arbitrary byte data, so if a string is to be encoded, its specific encoding as an array of bytes needs to be decided on.

  • In your original attempt (as in your effective solution), you correctly obtained your Base64-encoded string based on the bytes that make up the UTF-16LE encoding of the input string to encode ([System.Text.Encoding]::Unicode.GetBytes(...)), because that is what the Windows PowerShell CLI (powershell.exe) / PowerShell (Core) 7 CLI (pwsh) requires in an argument passed to its -EncodedCommand parameter.

    • Terminology note: In .NET and PowerShell, this specific Unicode encoding is poorly named for the abstract Unicode standard ([System.Text.Encoding]::Unicode in .NET, -Encoding Unicode in PowerShell's various file-processing cmdlets)
  • The problem with your original attempt was to use Get-Content without the -Raw switch, as Santiago Squarzon pointed out:

    • Without -Raw, Get-Content emits the target file's lines one by one, which, when (implicitly) collected, result in an array of lines - as opposed to the single, multi-line string that -Raw returns.

      • Either way, Get-Content reads the file content into .NET string(s), which are composed of UTF-16 code units ([char] instances), and to make sure that the file content is interpreted correctly, you may need to use the -Encoding parameter.

      • [System.Text.Encoding]::Unicode.GetBytes() invariably operates on in-memory .NET strings.

    • When an array is passed to a .NET method that expects a single [string] argument, PowerShell - perhaps unfortunately - automatically stringifies it by space-concatenating its elements.

      • Therefore, newlines (line breaks) in the input string are lost (replaced with spaces), which can result in broken code, given that newlines do have syntactic significance in PowerShell code.

CodePudding user response:

I ended up doing a little more research and found a method that did exactly what I needed it to and maintained all its integrity.

$encoded = [Convert]::ToBase64String(
  [System.Text.Encoding]::Unicode.GetBytes(
    (Get-Content -Path $Path -Raw -Encoding UTF8)
  )
)
  • Related