Show system tray or balloon tip notification with PowerShell

Posted by

We had a requirement where we needed to notify the user when a certain number of days were past, the user should be shown a System notification in the tray area. There are a few solutions you can work on to achieve this:

  1. Write a Windows forms (formless application) in VB.Net or C#. Run the application with Windows Service at scheduled intervals.
  2. Use vbscript with Task scheduler. Run at system startup and schedule.
  3. Write PowerShell script with Task scheduler. Run at system startup and schedule.

We’ll explore the 3rd option to use PowerShell script. I found a wonderful article on mcpmag where Mr. Boe Prox explains “Creating a Balloon Tip Notification Using PowerShell”. This article gave me the starting point of solving the problem by using this script. Do check it out!

Using the PowerShell ISE, in the editor, write the following function that’ll get the system uptime.

Function Get-Uptime {
$os = Get-WmiObject win32_operatingsystem -ErrorAction SilentlyContinue
$uptime = (Get-Date) – $os.ConvertToDateTime($os.LastBootUpTime)
#Write-Output (“Last boot: ” + $os.ConvertToDateTime($os.LastBootUpTime) )
#Write-Output (“Uptime : ” + $uptime.Days + ” Days ” + $uptime.Hours + ” Hours ” + $uptime.Minutes + ” Minutes” )
return $uptime.Days
}

The following method as taken from the article shared above, helps generate the balloon tip by including the System.Windows.Forms assembly into our PowerShell session before we can make use of the NotifyIcon class.

Function Invoke-BalloonTip {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True,HelpMessage=”The message text to display. Keep it short and simple.”)]
[string]$Message,

[Parameter(HelpMessage=”The message title”)]
[string]$Title=”Attention $env:username”,

[Parameter(HelpMessage=”The message type: Info,Error,Warning,None”)]
[System.Windows.Forms.ToolTipIcon]$MessageType=”Info”,

[Parameter(HelpMessage=”The path to a file to use its icon in the system tray”)]
[string]$SysTrayIconPath=’C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe’,

[Parameter(HelpMessage=”The number of milliseconds to display the message.”)]
[int]$Duration=5000
)

Add-Type -AssemblyName System.Windows.Forms

If (-NOT $global:balloon) {
$global:balloon = New-Object System.Windows.Forms.NotifyIcon

#Mouse double click on icon to dispose
[void](Register-ObjectEvent -InputObject $balloon -EventName MouseDoubleClick -SourceIdentifier IconClicked -Action {
#Perform cleanup actions on balloon tip
Write-Verbose ‘Disposing of balloon’
$global:balloon.dispose()
Unregister-Event -SourceIdentifier IconClicked
Remove-Job -Name IconClicked
Remove-Variable -Name balloon -Scope Global
})
}

#Need an icon for the tray
$path = Get-Process -id $pid | Select-Object -ExpandProperty Path

#Extract the icon from the file
$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($SysTrayIconPath)

#Can only use certain TipIcons: [System.Windows.Forms.ToolTipIcon] | Get-Member -Static -Type Property
$balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]$MessageType
$balloon.BalloonTipText = $Message
$balloon.BalloonTipTitle = $Title
$balloon.Visible = $true

#Display the tip and specify in milliseconds on how long balloon will stay visible
$balloon.ShowBalloonTip($Duration)

Write-Verbose “Ending function”

}

Get the system uptime using the Get-UpTime function written above, and call the Invoke-BalloonTip to generate the System tray notification.

$lastrebootdays = Get-Uptime
#echo $lastrebootdays

if ($lastrebootdays -eq 0) {
$restartstr = ‘You last restarted your system ‘ + $lastrebootdays + ‘ days back.’
$userstr = ‘Attention ‘ + $env:username + ‘!’
Invoke-BalloonTip -Message $restartstr -Title $userstr -MessageType Info

$msgBoxInput = [System.Windows.Forms.MessageBox]::Show(‘Your last reboot happened ‘ + $lastrebootdays + ‘ days back. ‘ + ‘Would you like to restart your system?’,’Restart System!’,’YesNoCancel’,’Error’)

switch ($msgBoxInput) {
‘Yes’ {
[System.Windows.Forms.MessageBox]::Show(‘Restarted’)
}

‘No’ {
[System.Windows.Forms.MessageBox]::Show(‘Not Restarted’)
}

}
}

The above logic just shows a message box if Yes/No is selected by the user.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.