I trust by now you are realizing how valuable Windows PowerShell  is as a management tool. With a one line command you can accomplish an extraordinary amount of work. Sometimes this work may be long running, which is where background jobs come in handy. Or you may simply kick off a long running script and go about your other administrative tasks. Unfortunately, you have to keep stopping what you’re doing to check and see if your script or job has finished. But there is a better way, assuming you are running Windows Vista or later.

When Don Jones was at SAPIEN Technologies, I believe he wrote a blog entry about creating a pop balloon notification in the system tray. This handy system could be used to notify the logged on user just of about anything. I took the liberty of revising the function and turned it into a PowerShell v2.0 function called Show-Balloon.

Function Show-Balloon {

#requires -version 2.0

<#

.Synopsis

    Display a balloon tip message in the system tray.

.Description

    This function displays a user-defined message as a balloon popup in the system tray. This function

    requires Windows Vista or later.

.Parameter Message

    The message text you want to display.  Recommended to keep it short and simple.

.Parameter Title

    The title for the message balloon. The default is Attention: $env:username, where the variable

    will be replaced by the %USERNAME% environmental variable.

.Parameter MessageType

    .The type of message. This value determines what type of icon to display. Valid values are

    Error, Warning, Info and None. The default is Info. This paramater has an alias of 'type'.

.Parameter Duration

    The number of seconds to display the balloon popup. The default is 10.

.Example

    PS C:\>  Show-Balloon "Your script has finished." -duration 15 -Title "Hey, You!!"

    Displays a simple balloon popup for 15 seconds.

.Example

    PS C:\>  Show-Balloon "There was an error with the script: $error[0].Exception.Message" -messagetype "Error"

    Display an error balloon tip showing the exception message from the last error PowerShell detected.

.Example

    PS C:\>  Invoke-command -computer $env:computername -scriptblock {. c:\scripts\show-balloon.ps1; get-eventlog -logname system -newest 500;show-Balloon "Background job complete."} -asjob

    This example uses Invoke-Command to execute a potentially long running expression on the local computer. When

    it is finished, a balloon message is displayed. Because the job runs in a separate scope, the script containing

    the Show-Balloon function is dot sourced. After the Get-Eventlog cmdlet finishes, then the Show-Balloon function

    is run, displaying the message.

.Inputs

    None

.Outputs

    None

.Link

   http://jdhitsolutions.com/blog

.Link

    Write-Warning

    Write-Error

.Notes

 NAME:      Show-Balloon

 VERSION:   1.0

 AUTHOR:    Jeffery Hicks

 LASTEDIT:  11/12/2009

#>

[CmdletBinding()]

Param (

    [Parameter(

     ValueFromPipeline=$False,

     Position=0,

     Mandatory=$True,

     HelpMessage="The message text to display. Keep it short and simple.")]

     [string]$message,

    [Parameter(

     ValueFromPipeline=$False,

     Mandatory=$False,

     HelpMessage="The message title")]

     [string]$Title="Attention $env:username",

    [Parameter(

     ValueFromPipeline=$False,

     Mandatory=$False,

     HelpMessage="The message type: Info,Error,Warning,None")]

     [ValidateSet("Info","Error","Warning","None")]

     [Alias("type")]

     [string]$MessageType="Info",

     [Parameter(

     ValueFromPipeline=$False,

     Mandatory=$False,

     HelpMessage="The number of seconds to display the message.")]

     [int]$duration=10

     )

    Write-Verbose "Starting Function"

    if ($verbosePreference -eq "Continue") {

        Write-Verbose "Getting Operating System"

        Write-Verbose "OS: $((get-wmiobject win32_operatingsystem).caption)"

     }

    Write-Verbose "Loading Assemblies"

    #load Windows Forms and drawing assemblies

    [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null

    [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

    #define an icon image pulled from PowerShell.exe

    Write-Verbose "Extracting the icon from PowerShell.exe"

    $icon=[system.drawing.icon]::ExtractAssociatedIcon((join-path $pshome powershell.exe))

    Write-Verbose "Defining `$notify"

    $notify = new-object system.windows.forms.notifyicon

    $notify.icon = $icon

    $notify.visible = $True

    Write-Verbose "Evaluating MessageType parameter $messagetype"

    #define the tool tip icon based on the message type

    switch ($messagetype) {

     "Error" { $messageIcon=[system.windows.forms.tooltipicon]::Error}

     "Info" {$messageIcon=[system.windows.forms.tooltipicon]::Info}

     "Warning" {$messageIcon=[system.windows.forms.tooltipicon]::Warning}

     Default {$messageIcon=[system.windows.forms.tooltipicon]::None}

    }

    Write-Verbose "Displaying message [ $Message ] for $duration seconds"

    #display the balloon tipe

    $notify.showballoontip($duration,$Title,$message,$MessageIcon)

    Write-Verbose "Ending function"

} #end function

Set-Alias sb Show-Balloon

The function requires PowerShell version 2 and Windows Vista or later. Although it doesn’t check your operating system. I always like providing help information so the function can be used like a cmdlet.

show-balloon

balloontip

The function displays a message in a popup balloon by default for 10 seconds. You can customize the duration, title and the icon. The icon is determined by the MessageType parameter and can be Error, Warning, Info or None.

The function is relatively simple using the Drawings and Forms .NET classes to create and display a NotifyIcon object.

You might use this function to display a message after a script has finished.

PS C:\>  c:\scripts\myscript.ps1;Show-Balloon “Your script has finished.” -duration 15 -Title “Hey, You!!”

By using the ; to indicate a new line I can type a one line command and then move on to something else. You can easily incorporate variables into the message.

PS C:\> MyFunction ; Show-Balloon “There was an error with the script: $($error[0].Exception.Message)” -messagetype “Error”

Or use it with Invoke-Command.

PS C:\> Invoke-command -computer $env:computername -scriptblock {. c:\scripts\show-balloon.ps1;get-eventlog -logname system -newest 500;show-Balloon “Background job complete.”} -asjob

This example uses Invoke-Command to execute a potentially long running expression on the local computer. When  it is finished, a balloon message is displayed. Because the job runs in a separate scope, the script containing  the Show-Balloon function is dot sourced. After the Get-Eventlog cmdlet finishes, then the Show-Balloon function  is run, displaying the message.

I hope you’ll let me know how you use this function.
Download Show-Balloon.ps1

3 Responses to “The PowerShell Balloon Festival”

  1. [...] This post was mentioned on Twitter by Jeffery Hicks and doug finke, glnsize. glnsize said: RT @dfinke: Creating a popup balloon notification in the system tray with #PowerShell http://bit.ly/1pwHzx <- i like! [...]

  2. Hey, you should check out Growl for stuff like this, it’s so much more flexible than systray balloons.

    • Jeffery Hicks
      08:19, 16.11.2009

      I’ve been meaning to try that out. The balloon trick is quick and dirty and doesn’t require anything.