Use base64 for NotifyIcon in PowerShell

In addition to be able to use base64 for Images in WPF-based PowerShell Forms, you can also use base64 for icons as well. Essentially, you take the base64, convert it to a memory stream, draw an image from that stream, then convert the image to an icon. Finally, you assign the $notify.Icon this new variable.

Just the NotifyIcon Part

# Add required assembly
Add-Type -AssemblyName PresentationFramework, System.Windows.Forms
 
# here's the base64 string
$base64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7
           DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAJESURBVHhe7ZZRaiNRDAR9ON//St4JKIskikc3gwaBU1
           A/DQ9V/DHk9fl87rgFapPE0XAL1CaJo+EWqE0SR8MtUJskjoZboDZJHA0L7/f79YRxLtO7ZHE0LFDshHEu07tkcTQsUOyEcS7Tu2RxN
           CxQ7IRxLtO7ZHE03AK1SeJouAVqk8TRcAvUJomj4RaoTRJHwwJ9sCaMc5neJYujYYFiJ4xzmd4li6NhgWInjHOZ3iWLo2GBYieMc5ne
           JYuj4RaoTRJHwy1QmySOhlugNkkcDbdAbZI4GhbogzVhnMv0LlkcDQsUO2Gcy/QuWRwNCxQ7YZzL9C5ZHA0LFDthnMv0LlkcDbdAbZI
           4Gm6B2iRxNNwCtUniaLgFapPE0bBAH6wJ41ymd8niaFig2AnjXKZ3yeJoWKDYCeNcpnfJ4mhYoNgJ41ymd8niaLgFapPE0XAL1CaJo+
           EWqE0SR8MtUJskjoYF+mBNGOcyvUsWR8MCxU4Y5zK9SxZHwwLFThjnMr1LFkfDAsVOGOcyvUsWR8MtUJskjoZboDZJHA23QG2SOBpug
           dokcTTcArVJ4mi4BWqTxNFwC9QmiaPhFqhNEkfDLVCbJI6GW6A2SRwd6V/VJ6UmRxwdKepJqckRR0eKOnm9OUJvTl5PbomjI0WdvN4c
           oTcnrye3xNGRok5eb47Qm5PXk1vi6EhRJ683R+jNyevJLXF0pKiT15sj9Obk9eSWODpS1JNSkyOOjhT1pNTk2Idv4f/f/I1//C9/P8C
           PX/4DfF7/AHQpDe71ItxOAAAAAElFTkSuQmCC"
 
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64)
$bitmap.EndInit()
$bitmap.Freeze()
 
# Convert the bitmap into an icon
$image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())

# Create NotificationIcon and set its default values
$notify = New-Object System.Windows.Forms.NotifyIcon
$notify.Text = "Example usage"
$notify.Visible = $true

# This is where the icon is actually set
$notify.Icon = $icon

# Add Event to exit example
$notify.add_Click({
	$notify.Visible = $false
	$notify.Dispose()
})

Easy enough, right? So what if you want to use base64 as both an icon and as an image within the form? Check out the code below.

NotifyIcon + base64 WPF Image

To get this:
small-form

Use this (taking note of the comments):

# Add required assembly
Add-Type -AssemblyName PresentationFramework, System.Windows.Forms
 
# here's the base64 string
$base64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7
           DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAJESURBVHhe7ZZRaiNRDAR9ON//St4JKIskikc3gwaBU1
           A/DQ9V/DHk9fl87rgFapPE0XAL1CaJo+EWqE0SR8MtUJskjoZboDZJHA0L7/f79YRxLtO7ZHE0LFDshHEu07tkcTQsUOyEcS7Tu2RxN
           CxQ7IRxLtO7ZHE03AK1SeJouAVqk8TRcAvUJomj4RaoTRJHwwJ9sCaMc5neJYujYYFiJ4xzmd4li6NhgWInjHOZ3iWLo2GBYieMc5ne
           JYuj4RaoTRJHwy1QmySOhlugNkkcDbdAbZI4GhbogzVhnMv0LlkcDQsUO2Gcy/QuWRwNCxQ7YZzL9C5ZHA0LFDthnMv0LlkcDbdAbZI
           4Gm6B2iRxNNwCtUniaLgFapPE0bBAH6wJ41ymd8niaFig2AnjXKZ3yeJoWKDYCeNcpnfJ4mhYoNgJ41ymd8niaLgFapPE0XAL1CaJo+
           EWqE0SR8MtUJskjoYF+mBNGOcyvUsWR8MCxU4Y5zK9SxZHwwLFThjnMr1LFkfDAsVOGOcyvUsWR8MtUJskjoZboDZJHA23QG2SOBpug
           dokcTTcArVJ4mi4BWqTxNFwC9QmiaPhFqhNEkfDLVCbJI6GW6A2SRwd6V/VJ6UmRxwdKepJqckRR0eKOnm9OUJvTl5PbomjI0WdvN4c
           oTcnrye3xNGRok5eb47Qm5PXk1vi6EhRJ683R+jNyevJLXF0pKiT15sj9Obk9eSWODpS1JNSkyOOjhT1pNTk2Idv4f/f/I1//C9/P8C
           PX/4DfF7/AHQpDe71ItxOAAAAAElFTkSuQmCC"
 
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64)
$bitmap.EndInit()
$bitmap.Freeze()
 
# Convert the bitmap into an icon
$image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
 
# Create NotificationIcon and set its default values
$notify = New-Object System.Windows.Forms.NotifyIcon
$notify.Text = "Example usage"
$notify.Visible = $true

# This is where the icon is actually set
$notify.Icon = $icon
 
# Add Event to exit example
$notify.add_Click({
 $notify.Visible = $false
 $notify.Dispose()
 $form.Close()
})
 
# Create the form to display the image
# Setup the XAML
[xml]$script:xaml = '
    
        
    
'
 
# Create the form and set variables
$script:form = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml))
$xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $form.FindName($_.Name) -Scope Script }
 
# Set source here. Take note in the XAML as to where the variable name was taken.
$thisistheimage.source = $bitmap

# Clean up once closed
$form.Add_Closed({
	$notify.Visible = $false
	$notify.Dispose()
})

# Show form
$form.ShowDialog() | Out-Null

PowerShell + WPF = <3

Chrissy is a Cloud and Datacenter Management & Data Platform MVP who has worked in IT for over 20 years. She is the creator of the popular SQL PowerShell module dbatools, holds a master's degree in Systems Engineering and is coauthor of Learn dbatools in a Month of Lunches. Chrissy is certified in SQL Server, Linux, SharePoint and network security. You can follow her on Twitter at @cl.

Posted in PowerShell, WPF
One comment on “Use base64 for NotifyIcon in PowerShell
  1. Rich says:

    I just plugged your “icon from base64 code” into a function and went from a script with a single external icon file to a script with an array of status-changing icons in a few minutes. Very nice, thanks for sharing.

Leave a Reply