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).
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