powershellpdfencodingdecodinginvoke-restmethod

PowerShell - Issues Downloading Base64-Encoded PDF (Blank/White PDF)


Overview:

I am trying to make a script that downloads my internet service provider's (ISP) monthly statement. 'Cus, you know, who doesn't do that regularly? My ISP is Spectrum. I have the code that uses Invoke-RestMethod, and it gets the proper response. The response gives me a JSON object with base64-encoded pdf text.

Code:

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add((New-Object System.Net.Cookie("thumbprint_consumer_portal", "xxxx", "/", ".spectrum.net")))
$pdf = Invoke-RestMethod -UseBasicParsing -Uri "https://apis.spectrum.net/selfservice/graph" `
-Method "POST" `
-WebSession $session `
-Headers @{
  "authorization"="Bearer xxxx"
} `
-ContentType "application/json" `
-Body "{$body}"

After getting the pdf code from the json object, I found that the code is Base64 encoded. "No problem!" I thought. So, I decode it, and encode it back into ASCII.

$raw = $pdf.data.viewer.account.statementPdf
$file = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($raw))
Out-File -FilePath "bill.pdf" -InputObject $file

Problem:
The problem is when I try to decode the response, and then output it into a pdf file. The pdf is blank! But, it has the right number of pages, and the file size is the same amount as an original file I downloaded from the website. I am trying both Acrobat and Chrome PDF Viewer to view the PDFs.

Troubleshooting

Expectations

I expect the pdf file to just open properly and show me the billings details, as if I had downloaded it from the website.

Any suggestions?


Solution

  • A PDF document is a binary file, not a text file - so trying to produce a string with [Encoding]::ASCII.GetString(...) won't do you any good.

    Instead, do exactly what you did with CyberChef - decode the base64 string and then output the resulting byte stream directly to disk:

    $fileContents = [System.Convert]::FromBase64String($raw)
    
    # for Windows PowerShell:
    Set-Content -Path path\to\file.pdf -Value $fileContents -Encoding Byte
    # for PowerShell >=7.x:
    Set-Content -Path path\to\file.pdf -Value $fileContents -AsByteStream