Convert Modern SharePoint Page Banner Images to Base-64 using PowerShell

I was recently asked to write a PowerShell script that identified a bunch of pages and emailed them. They wanted the emails to include the Banner Image (the page/news thumbnail). No problem, I’ll just grab the handy BannerImageUrl field and stick it in some HTML, right? Nope.

Although you can certainly create an email with images using the URL, unless the user is logged in, those images will cause a bunch of authentication errors. This is especially a problem for people checking their email on their phones. Sadness!

Fortunately, you can grab those images in PowerShell and convert them to base-64 strings. That way the authentication for the images is only needed when running the script and not when the user opens the email.

The Father

Here’s a basic script that covers the concept using PnP PowerShell:

# Connect to your site
# (this example assumes an entry in Windows Credential Manager,
# but you can pass credentials however you need here)
$connection = Get-PnPConnection
# Setup a Web Client using credentials pulled from the connection
$client = New-Object System.Net.WebClient
$client.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($connection.PSCredential.UserName, $connection.PSCredential.Password)
$client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
# Get a page
# (You could be doing this in a loop or using Get-PnPClientSidePage)
$page = Get-PnPListItem List "Site Pages" Id 294
# Grab the value of the image and convert it to base-64
# and slap the data information to the front
$image = "data:image/png;base64," + [convert]::ToBase64String($client.DownloadData($page.FieldValues.BannerImageUrl.Url))
# In this sample, just copying the HTML value to the clipboard to prove it works
# Normally, you'd build an HTML string and append it for your email
Set-Clipboard Value "<img src=""$image"">"
# All done!

In the Gist above, the HTML value is put in your clipboard. This is just to make it easy to prove it works. Run the script, paste the result in codepen in a browser where you are not authenticated to the site and witness the magic!

The key bit is the setup of the web client (lines 8-10) and the call to convert the downloaded data (line 18). You can easily wrap this logic up inside a foreach loop to process all your pages/news and build a nice html based email. Wowee!