2

I need to turn an array of comma-seperated values (a .csv) into a bit of JSON that looks like this:

"traits": {
  "file": {
    "content": "R0lGODlhABAQAIAAAAAAAP///yH7BAEAAAAALAAAAAAEAABAAAIBRAA5",
    "file_name": "test.png"
  }
}

I am using the following:

$traits = New-Object PSObject
$file = New-Object PSObject
$file | Add-Member -Type NoteProperty -Name file_name -Value "file.csv"
$file | Add-Member -Type NoteProperty -Name content -Value $([Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes(($domain.GPOs | ConvertTo-Csv))))
$traits | Add-Member -Type NoteProperty -Name group-policies -Value $file

It seems that the content of "content" is incorrectly encoded. To troubleshoot, I copied the content to www.freeformatter.com/base64-encoder.html and found that they don't match.

What am I missing?

Edit: Here is the content of the .csv. This is what I pasted into https://www.freeformatter.com/base64-encoder.html#ad-output:

#TYPE Selected.System.Xml.XmlElement
"Name","GUID","Linked To","Computer Settings","User Settings"
"Autodiscover - Shared Namespace","249b1923-523a-40b6-9180-cc2727414b9b","@{OU Name=servers; OU Path=domain.local/location/servers; Enabled=true; Enforced=false}","@{Enabled=true; Settings=}","@{Enabled=true; Settings=}"

Powershell outputs this:

IwBUAFkAUABFACAAUwBlAGwAZQBjAHQAZQBkAC4AUwB5AHMAdABlAG0ALgBYAG0AbAAuAFgAbQBsAEUAbABlAG0AZQBuAHQAIAAiAE4AYQBtAGUAIgAsACIARwBVAEkARAAiACwAIgBMAGkAbgBrAGUAZAAgAFQAbwAiACwAIgBDAG8AbQBwAHUAdABlAHIAIABTAGUAdAB0AGkAbgBnAHMAIgAsACIAVQBzAGUAcgAgAFMAZQB0AHQAaQBuAGcAcwAiACAAIgBBAHUAdABvAGQAaQBzAGMAbwB2AGUAcgAgAC0AIABTAGgAYQByAGUAZAAgAE4AYQBtAGUAcwBwAGEAYwBlACIALAAiADIANAA5AGIAMQA5ADIAMwAtADUAMgAzAGEALQA0ADAAYgA2AC0AOQAxADgAMAAtAGMAYwAyADcAMgA3ADQAMQA0AGIAOQBiACIALAAiAEAAewBPAFUAIABOAGEAbQBlAD0AcwBlAHIAdgBlAHIAcwA7ACAATwBVACAAUABhAHQAaAA9AGQAbwBtAGEAaQBuAC4AbABvAGMAYQBsAC8AbABvAGMAYQB0AGkAbwBuAC8AcwBlAHIAdgBlAHIAcwA7ACAARQBuAGEAYgBsAGUAZAA9AHQAcgB1AGUAOwAgAEUAbgBmAG8AcgBjAGUAZAA9AGYAYQBsAHMAZQB9ACIALAAiAEAAewBFAG4AYQBiAGwAZQBkAD0AdAByAHUAZQA7ACAAUwBlAHQAdABpAG4AZwBzAD0AfQAiACwAIgBAAHsARQBuAGEAYgBsAGUAZAA9AHQAcgB1AGUAOwAgAFMAZQB0AHQAaQBuAGcAcwA9AH0AIgA=

The website spits out:

I1RZUEUgU2VsZWN0ZWQuU3lzdGVtLlhtbC5YbWxFbGVtZW50DQoiTmFtZSIsIkdVSUQiLCJMaW5rZWQgVG8iLCJDb21wdXRlciBTZXR0aW5ncyIsIlVzZXIgU2V0dGluZ3MiDQoiQXV0b2Rpc2NvdmVyIC0gU2hhcmVkIE5hbWVzcGFjZSIsIjI0OWIxOTIzLTUyM2EtNDBiNi05MTgwLWNjMjcyNzQxNGI5YiIsIkB7T1UgTmFtZT1zZXJ2ZXJzOyBPVSBQYXRoPWRvbWFpbi5sb2NhbC9sb2NhdGlvbi9zZXJ2ZXJzOyBFbmFibGVkPXRydWU7IEVuZm9yY2VkPWZhbHNlfSIsIkB7RW5hYmxlZD10cnVlOyBTZXR0aW5ncz19IiwiQHtFbmFibGVkPXRydWU7IFNldHRpbmdzPX0i
5
  • Can you show some sample source data and how you are reading it. I don't even see where you try to convert it to JSON
    – Matt
    Commented Dec 4, 2018 at 19:06
  • I'm trying to get to JSON like that, but the encoding is wrong. Commented Dec 4, 2018 at 19:36
  • 1
    [System.Text.Encoding]::Unicode.GetBytes(...) -> [System.Text.Encoding]::ASCII.GetBytes(...). Your script uses a different encoding. Commented Dec 4, 2018 at 20:13
  • @AnsgarWiechers I did try with [System.Text.Encoding]::UTF8.GetBytes(...) and get the same result as with ASCII but they only match up to the 48th position, presumably line endings don't match.
    – user6811411
    Commented Dec 4, 2018 at 20:24
  • @LotPings You get a matching result because UTF-8 was designed for backwards compatibility with ASCII. And yes, trailing line breaks probably account for differences at the end of the encoded strings Commented Dec 4, 2018 at 20:28

1 Answer 1

5

There are three (potential) problems:

  • Character encoding:

    • www.freeformatter.com bases the Base64 encoding on the input string's UTF-8 encoding.
    • Your PowerShell code uses UTF-16LE ("Unicode") encoding as the basis; use [System.Text.Encoding]::UTF8.GetBytes() instead, if you want UTF-8.
  • Style of newlines (line endings)

    • Newlines in text pasted at www.freeformatter.com are quietly converted to Windows-style CRLF newlines, whereas your input may have Unix-style LF-only newlines.
  • Newlines getting lost:

    • You're passing the output from ConvertTo-Csv, which is an array of strings to [System.Text.Encoding]::Unicode.GetBytes(), which expects a single string. In the process PowerShell stringifies the array, which means that its elements are joined with a space as the separator, so the original newlines are replaced with spaces, resulting in different encoded output.
    • Therefore, instead of ($domain.GPOs | ConvertTo-Csv), use ($domain.GPOs | ConvertTo-Csv) -join [Environment]::NewLine (which uses the platform-appropriate newline sequence; alternatively, use "`n" or "`r`n" explicitly; also, you may want to append a trailing newline).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.