Base64 Encoding with Powershell and .NET Framework

Today I’ve answered a question in one of my blog articles on SendGrid API and PowerShell on how to add attachments to an email when using the API.
The official documentation is pretty clear if you want to pass a text or binary file as an attachment the SendGrid API is requiring a couple of strings: filename and content in base64,  but in case anybody finds a roadblock here this article it may help you.

If you haven’t heard before of Base64 it worth reading a little bit of history from Wikipedia just to understand the context a bit more.

As less common usage that I’ve also seen where it was used for text/code obfuscation on phishing attacks or injecting malicious payloads inside web pages on compromised websites.

This is the simple helper function to encode a file (text or binary) into a base64 encoded string.


There are a couple of libraries from the .NET Framework that I used to do the actual encoding, so the helper function is a wrapper in the end.

After the function definition, I’ve added a quick example where I create a file from listing all the current working directory content and redirecting the output to a file.  I can then pass it as an argument to my function as a test to show you how can you use it.

UPDATE:

One comment in another article pushed me to review this code snippet and to improve it.

 

As usual, this source code is available on my GitHub repository.

5 Replies to “Base64 Encoding with Powershell and .NET Framework”

  1. i’m having trouble with this. when using this on a csv file (windows) it seems to be stripping the CRLF (new line) from the file. so when i reopen the attachment in excel its a single column/row instead of one line per row.

    1. $ContentBase64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($(Get-Content c:\temp\1.csv)))

      [System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($ContentBase64)) | Set-Content -Path C:\temp\2.csv

      the 2.csv is missing the line-breaks at the end of each row.

      1. Hi Spizzy,
        Thanks for your comment. The best suggestion at this stage would be not using get-content, which I guess is the issue.

        Please have a look at this:
        #I create a test csv file from listing the directory content
        Get-ChildItem | export-csv -path "c:\temp\1.csv"

        #OLD method using get-content
        $ContentBase64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($(Get-Content c:\temp\1.csv)))
        [System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($ContentBase64)) | Set-Content -Path C:\temp\2.csv

        #NEW one using System.Io.File.ReadAllText
        $ContentBase64 = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes([System.IO.File]::ReadAllText("c:\\temp\\1.csv")))
        [System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($ContentBase64)) | Set-Content -Path C:\temp\3.csv

        Compare now 2.csv and 3.csv. You’ll see that 3.csv is like 1.csv and it is not missing any CRLF. I hope this helps.

        Let me know if this solves your issue, I’ve tested it just with sample files and I never noticed this issue. Thanks for pointing it out I will modify the code in my other article.
        Regards
        Regards

        1. awesome thanks. i was also able to solve this by use “get-content -raw -path c:\1.csv” and it kept the linebreaks.

          you’re the man, thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.