Skip to content

Instantly share code, notes, and snippets.

@neuralpain
Last active August 12, 2024 14:00
Show Gist options
  • Save neuralpain/283a2de1e7078c95e0c97a4fb6cc0e08 to your computer and use it in GitHub Desktop.
Save neuralpain/283a2de1e7078c95e0c97a4fb6cc0e08 to your computer and use it in GitHub Desktop.
Simple Toast Notification for Windows
<#
.SYNOPSIS
Creates and displays a Windows Toast notification
.DESCRIPTION
Creates a Windows Toast notification and displays it to the user
.PARAMETER AppId
The AppId of the application that will display the notification
- PowerShell ID: {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe
- Terminal ID: Microsoft.WindowsTerminal_8wekyb3d8bbwe!App
.PARAMETER ToastTitle
The title of the Toast notification
.PARAMETER ToastText
The first line of text of the Toast notification
.PARAMETER ToastText2
The second line of text of the Toast notification
.PARAMETER Attribution
The attribution text of the Toast notification
.PARAMETER ActionButtonUrl
The URL to open when the user clicks the action button
.PARAMETER ActionButtonText
The text to display on the action button
.PARAMETER HeroImage
The URL of the hero image to display on the Toast notification
.PARAMETER ProfileImage
The URL of the profile image to display on the Toast notification
.PARAMETER KeepAlive
Keep the Toast notification alive until the user dismisses it
.PARAMETER LongerDuration
Display the Toast notification for a longer duration
.EXAMPLE
New-ToastNotification "Hello World" "This is a Toast notification"
Creates and displays a Toast notification with the title "Hello World" and the text "This is a Toast notification"
.NOTES
The function requires Windows 10 build 10586 (Anniversary Update) or higher
#>
function New-ToastNotification {
[CmdletBinding()]
Param (
[String]$AppId = "Microsoft.WindowsTerminal_8wekyb3d8bbwe!App",
[String]$Url,
[String]$ToastTitle,
[String][Parameter(ValueFromPipeline)]$ToastText,
[String][Parameter(ValueFromPipeline)]$ToastText2,
[string]$Attribution,
[String]$ActionButtonUrl,
[String]$ActionButtonText,
[String]$HeroImage,
[String]$ProfileImage,
[switch]$KeepAlive,
[switch]$LongerDuration
)
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
$Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText04)
$RawXml = [xml] $Template.GetXml()
($RawXml.toast.visual.binding.text | Where-Object { $_.id -eq "1" }).AppendChild($RawXml.CreateTextNode($ToastTitle)) | Out-Null
($RawXml.toast.visual.binding.text | Where-Object { $_.id -eq "2" }).AppendChild($RawXml.CreateTextNode($ToastText)) | Out-Null
($RawXml.toast.visual.binding.text | Where-Object { $_.id -eq "3" }).AppendChild($RawXml.CreateTextNode($ToastText2)) | Out-Null
$XmlDocument = New-Object Windows.Data.Xml.Dom.XmlDocument
$XmlDocument.LoadXml($RawXml.OuterXml)
if ($Url) {
# <toast activationType="protocol" launch="/"></toast>
$XmlDocument.DocumentElement.SetAttribute("activationType", "protocol")
$XmlDocument.DocumentElement.SetAttribute("launch", $Url)
}
if ($Attribution) {
# <text placement="attribution"> ... </text>
$attrElement = $XmlDocument.CreateElement("text")
$attrElement.SetAttribute("placement", "attribution")
$attrElement.InnerText = $Attribution
# Find the <binding> element where the new <text> element should be added
$bindingElement = $XmlDocument.SelectSingleNode('//toast/visual/binding')
# Append the new <text> element to the <binding> element
$bindingElement.AppendChild($attrElement) | Out-Null
}
if ($ProfileImage) {
# <image placement="appLogoOverride" src="..." />
$imgElement = $XmlDocument.CreateElement("image")
$imgElement.SetAttribute("placement", "appLogoOverride")
$imgElement.SetAttribute("hint-crop", "circle")
$imgElement.SetAttribute("src", $ProfileImage)
# Find the <binding> element where the new <image> element should be added
$bindingElement = $XmlDocument.SelectSingleNode('//toast/visual/binding')
# Append the new <image> element to the <binding> element
$bindingElement.AppendChild($imgElement)
}
if ($HeroImage) {
# <image placement="hero" src="..." />
$imgElement = $XmlDocument.CreateElement("image")
$imgElement.SetAttribute("placement", "hero")
$imgElement.SetAttribute("src", $HeroImage)
# Find the <binding> element where the new <image> element should be added
$bindingElement = $XmlDocument.SelectSingleNode('//toast/visual/binding')
# Append the new <image> element to the <binding> element
$bindingElement.AppendChild($imgElement) | Out-Null
}
if ($ActionButtonUrl) {
# <actions><action ... /></actions>
# Create the <actions> element
$actionsElement = $XmlDocument.CreateElement("actions")
# Create the <action> element with the required attributes
$actionElement = $XmlDocument.CreateElement("action")
$actionElement.SetAttribute("content", $ActionButtonText)
$actionElement.SetAttribute("activationType", "protocol")
$actionElement.SetAttribute("arguments", $ActionButtonUrl)
# Append the <action> element to the <actions> element
$actionsElement.AppendChild($actionElement) | Out-Null
# Append the <actions> element to the root <toast> element
$XmlDocument.DocumentElement.AppendChild($actionsElement) | Out-Null
}
if ($KeepAlive) {
$XmlDocument.DocumentElement.SetAttribute("scenario", "incomingCall")
}
elseif ($LongerDuration) {
$XmlDocument.DocumentElement.SetAttribute("duration", "long")
}
$Toast = [Windows.UI.Notifications.ToastNotification]::new($XmlDocument)
$Toast.Tag = "PowerShell"
$Toast.Group = "PowerShell"
if (-not($KeepAlive -or $LongerDuration)) {
$Toast.ExpirationTime = [DateTimeOffset]::Now.AddMinutes(1)
}
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId)
$Notifier.Show($Toast)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment