ps/Modules/Cole.PowerShell.Developer/Public/Show-ToastNotification.ps1
2023-05-30 22:51:22 -07:00

140 lines
5.3 KiB
PowerShell

function Show-ToastNotification {
<#
.SYNOPSIS
Used to send a notification message to the screen,
especially useful in automated scripts or scripts
that could use feedback faster than waiting on a program to exit
.DESCRIPTION
This will use the [Windows.UI.Notifications.ToastNotificationManager] to output a small toast window on screen.
Toasts are the notifications that pop up and then disappear after a short period of time, or that stay persistent on screen.
.PARAMETER ToastText
Maximum length 220 characters without a title, 150 charaters with a title. Will trim to the first 150/220 chars.
No trimming occurs if the system is non-interactive, and instead the toast is written to standard output like so:
TOAST===TOAST===TOAST===TOAST===TOAST===TOAST
TITLE: Sample Toast
This is a sample toast notification that was
processed on a text based system
=============================================
#>
[CmdletBinding(DefaultParameterSetName = "Seconds")]
[OutputType([void])]
Param (
[Parameter(Mandatory = $false)]
[string]$ToastTitle = "",
[Parameter(Mandatory = $false)]
[string]$AppId = "PowerShell Toast Window",
[Parameter(Mandatory = $false)]
[string]$Tag = "",
[Parameter(Mandatory = $false)]
[string]$Group = "",
[Parameter(ParameterSetName = "Seconds")]
[int]$Seconds = 15,
[Parameter(ParameterSetName = "Milliseconds")]
[int]$Milliseconds = 0,
[switch]$NoTimeout,
[switch]$ForceTryDisplay,
[Parameter(ValueFromPipeline = $true, Mandatory = $false)]
[Alias('Text')]
[Alias('Content')]
[string]$ToastText,
[switch]$ShowInActionCenter
)
$toastTextEmpty = [string]::IsNullOrWhiteSpace($ToastText)
$toastTitleEmpty = [string]::IsNullOrWhiteSpace($ToastTitle)
if ($toastTextEmpty) {
$ToastText = "<No text provided>"
}
if (Test-IsMacOSPlatform) {
$ToastText = $ToastText.Replace('"',"'")
if ($toastTitleEmpty) {
$ToastTitle = "PowerShell Notification"
}
osascript -e "Display notification \`"$ToastText\`" with title \`"$ToastTitle\`""
return
}
if (!$ForceTryDisplay -and !(Test-IsWindowsDesktop) -and !(Test-IsInteractiveSession)) {
Write-Verbose "Toast notification requested, but the session is non-interactive and/or not running on Windows. Toast support only provided for Windows."
Write-Host "TOAST===TOAST===TOAST===TOAST===TOAST===TOAST"
if (!$toastTitleEmpty) {
Write-Host "TITLE: $ToastTitle"
}
$wrappedLines = (Format-TextWrapToDisplay -Width 45 -Text $ToastText)
foreach($line in $wrappedLines) {
Write-Host $line
}
Write-Host "============================================="
return
}
$expirationTime = $null
if ($PSCmdlet.ParameterSetName -eq "Seconds") {
$Milliseconds = $Seconds * 1000
}
if ($Milliseconds -le 0) {
$NoTimeout = $true
}
if (!$NoTimeout) {
$expirationTime = [DateTimeOffset]::Now.AddMilliseconds($Milliseconds)
}
$toastTextTrim = 220
if ($toastTitleEmpty) {
$toastTextTrim = 150
}
$ToastText = $ToastText.PadRight($toastTextTrim).Substring(0,$toastTextTrim).Trim()
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
$Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
if ($toastTitleEmpty) {
$Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText01)
}
$RawXml = [xml] $Template.GetXml()
Write-Host $RawXml.OuterXml
if ($toastTitleEmpty) {
($RawXml.toast.visual.binding.text | Where-Object {$_.id -eq "1"}).AppendChild($RawXml.CreateTextNode($ToastText)) > $null
} else {
($RawXml.toast.visual.binding.text | Where-Object {$_.id -eq "1"}).AppendChild($RawXml.CreateTextNode($ToastTitle)) > $null
($RawXml.toast.visual.binding.text | Where-Object {$_.id -eq "2"}).AppendChild($RawXml.CreateTextNode($ToastText)) > $null
}
$SerializedXml = New-Object Windows.Data.Xml.Dom.XmlDocument
$SerializedXml.LoadXml($RawXml.OuterXml)
$Toast = [Windows.UI.Notifications.ToastNotification]::new($SerializedXml)
if (![string]::IsNullOrWhiteSpace($Tag)) {
$Toast.Tag = $Tag
}
if (![string]::IsNullOrWhiteSpace($Group)) {
$Toast.Group = $Group
}
if ($null -ne $expirationTime) {
$Toast.ExpirationTime = $expirationTime
}
if ($ShowInActionCenter) {
$RegPath = 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings'
if (!(Test-Path -Path "$RegPath\$AppId")) {
if($PSCmdlet.ShouldProcess("creating: '$RegPath\$AppId' with property 'ShowInActionCenter' set to '1' (DWORD)")) {
(New-Item -Path "$RegPath\$AppId" -Force) | Out-Null
(New-ItemProperty -Path "$RegPath\$AppId" -Name 'ShowInActionCenter' -Value 1 -PropertyType 'DWORD') | Out-Null
}
}
}
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($Toast)
}