PowerShell – Balloon Tip – Toast

email me

Updated 2/8/2019

If you’re just looking to do basic things with toasts, read up on BurntToast. It makes using toasts much easier.

https://github.com/Windos/BurntToast/blob/master/Installer/BurntToast.msi

Install-Module -Name BurntToast
Import-module BurntToast

Simple Toast

$hdrText = New-BTText -Content 'Eddie''s Website'
$subText = New-BTText -Content 'Click to open the site.'
$aBinding = New-BTBinding -Children $hdrText, $subText
$aVisual = New-BTVisual -BindingGeneric $aBinding
$aContent = New-BTContent -Visual $aVisual -Launch 'https://eddiejackson.net' -ActivationType Protocol
Submit-BTNotification -Content $aContent

 

Moving on…

Simple Toast with Balloon

[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)

# Remove and Unregister events if created earlier. Tip, remove the events you haven’t created earlier

#Remove-Event BalloonClicked_event -ea SilentlyContinue

#Unregister-Event -SourceIdentifier BalloonClicked_event -ea silentlycontinue

#Remove-Event BalloonClosed_event -ea SilentlyContinue

#Unregister-Event -SourceIdentifier BalloonClosed_event -ea silentlycontinue

Remove-Event Clicked_event -ea SilentlyContinue

Unregister-Event -SourceIdentifier Clicked_event -ea silentlycontinue

# Create the object and customize the message

$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon

$objNotifyIcon.Icon = [System.Drawing.SystemIcons]::Information

$objNotifyIcon.BalloonTipIcon = “Info”

$objNotifyIcon.BalloonTipTitle = “Technology Notification”

$objNotifyIcon.BalloonTipText = “Google Plugin was installed! ” + [DateTime]::Now.ToShortTimeString()

$objNotifyIcon.Text = “Technology Notification”

$objNotifyIcon.Visible = $True

Register-ObjectEvent -InputObject $objNotifyIcon -EventName Click -SourceIdentifier Clicked_event -Action {

[System.Windows.MessageBox]::Show('Hello')
$objNotifyIcon.Visible = $False

#[System.Windows.Forms.MessageBox]::Show(“Clicked”,”Information”);$objNotifyIcon.Visible = $False

} | Out-Null

# Show Notification

$objNotifyIcon.ShowBalloonTip(1000)

 

More Advanced Toast (yes, this is the toast you’re looking for)

The PowerShell file below is a toast with a base64 image, and two buttons with action items. You can either convert an image to base64 (and the image be embedded into the script), or just point to an image (you’ll probably want to package any extra resource files you use).

Toast1.ps1

more at Microsoft…

 


App on Computer

To add an app or an installation file action to a toast button (where the app resides on the computer), simply apply CLASSES_ROOT registry keys before you run the toast. This is to meet some basic security requirements which allow toasts to access files on the local machine. Toasts don’t normally have access to the files on your computer; this is by design.

Reg Keys (save as toast.reg)

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\YourApp]
@=”myProto Protocol”
“URL Protocol”=””

[HKEY_CLASSES_ROOT\YourApp\DefaultIcon]
@=”C:\\setup\\setup.exe,1″

[HKEY_CLASSES_ROOT\YourApp\shell]

[HKEY_CLASSES_ROOT\YourApp\shell\open]

[HKEY_CLASSES_ROOT\YourApp\shell\open\command]
@=”\”c:\\setup\\setup.exe\””

Now place the App Reference Name into the XML of the toast, as the argument (with the colon).

<action content=”Install” activationType=”protocol” arguments=”YourApp:“>

—test your toast now

 

 

Older Post

This launches a balloon notification. Tested in W7 and W10.
Some details of the process…
First, you need to load up an assembly to take advantage of a method that will help to extract the icon image from the file.

Add-Type -AssemblyName System.Windows.Forms

 

Second, you need to add the System.Windows.Forms assembly into your PowerShell session, before we can make use of the NotifyIcon class. Your function checks whether there is already an icon that you can reuse.  This is done by using a “shared variable”, which is a variable that has “script:” scope. Shared variables will be active as long as the script is running.

if ($script:balloon -eq $null)
{
$script:balloon = New-Object System.Windows.Forms.NotifyIcon
}

 

Then you want to set the system tray icon of the PowerShell ISE by locating its path via Get-Process and accessing the Path property. After you have the path, then you need to extract the icon from the file so it can be applied to the Icon property. Using this approach, you can pull any icon from a file and use it for the system tray icon when the balloon tip is launched.

The Get-Process -id $pid command returns the PowerShell process that is hosting the current session.The ExpandProperty expands the collections, which will output the properties of every object in the collection. In this case, it’s the path to “C:\windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe”

$path = Get-Process -id $pid | Select-Object -ExpandProperty Path

 

The ExtractAssociatedIcon includes the System.Drawing.Icon class and accepts the parameter of string path name.

$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)

 

Okay, moving on to the full function…

 

The Function

function BalloonTip
{

[CmdletBinding()]
param
(
[Parameter(Position=1)]
$text,

[Parameter(Position=2)]
$title,

[Parameter(Position=3)]
$icon
)

Add-Type -AssemblyName System.Windows.Forms

$iconParam = $Icon

if ($script:balloon -eq $null)
{

$script:balloon = New-Object System.Windows.Forms.NotifyIcon
}

$path = Get-Process -id $pid | Select-Object -ExpandProperty Path
$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.BalloonTipIcon = $iconParam
$balloon.BalloonTipText = $text
$balloon.BalloonTipTitle = $title
$balloon.Visible = $true

$balloon.ShowBalloonTip(2000)
}

BalloonTip "Your computer has received updates. Please reboot. - IT Department" "UPDATES" "Warning"
# none - Info - Error - Warning

 

Screenshots

W7

W10

 

Notes

Encoding/Decoding a Text File

clear-host

# Encode

$File1 = "c:\setup\YourFile.txt"

$Content1 = get-content $File1
$Bytes = [System.Text.Encoding]::UTF8.GetBytes($Content1)
$Encoded = [System.Convert]::ToBase64String($Bytes)
#$Encoded | set-content ($File1 + ".b64")
Write-Host "ENCODED: " $Encoded

# Decode
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($Encoded)) | Out-File -Encoding "ASCII" c:\setup\YourFileDecoded.txt
$Content2 = get-content c:\setup\YourFileDecoded.txt
Write-Host "DECODED: " $Content2

 

Decoding an Image

# tmp image name
$Image = "$env:TEMP\Image.png"

# convert from base64
[byte[]]$Bytes = [convert]::FromBase64String($bas64Image)
[System.IO.File]::WriteAllBytes($Image,$Bytes)

 

Encoding/Decoding an EXE

clear-host

# Encode

$FilePath = "c:\setup\NoSleep.exe"
$File = [System.IO.File]::ReadAllBytes($FilePath);

# returns the base64 string
$Base64String = [System.Convert]::ToBase64String($File);

# Decode

function Convert-StringToBinary {
[CmdletBinding()]
param (
[string] $EncodedString
, [string] $FilePath = (‘{0}\{1}’ -f $env:TEMP, [System.Guid]::NewGuid().ToString())
)

try {
if ($EncodedString.Length -ge 1) {

# decodes the base64 string
$ByteArray = [System.Convert]::FromBase64String($EncodedString);
[System.IO.File]::WriteAllBytes($FilePath, $ByteArray);
}
}
catch {
}

Write-Output -InputObject (Get-Item -Path $FilePath);
}

$DecodedFile = Convert-StringToBinary -EncodedString $Base64String -FilePath C:\setup\NoSleep2.exe;

 

More info…

IO.File ReadAllBytes:

$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($FileName))

and WriteAllBytes to decode:

[IO.File]::WriteAllBytes($FileName, [Convert]::FromBase64String($base64string))

 

https://github.com/Windos/BurntToast/issues/22

https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa767914(v=vs.85)