2014-03-15

PowerShell MessageBox

Sometimes I need a tool made in PowerShell to require extra attention from the user. When I did the scripting in Windows Script Host (WSH) I had the MsgBox function in VBScript. It is possible to create a WSH COM object in PowerShell like shown in „VBScript-to-Windows PowerShell Conversion Guide“ on Microsoft TechNet, but I prefer a .NET solution when it is available. To be fair to TechNet, the guide is written for PowerShell v1 that did not have the same interation with .NET as the present version of PowerShell.

A solution that I find easy to use is the static method Show() from the MessageBox class.
[System.Windows.Forms.MessageBox]::('Hello world!', 'Hello', 'OK' ,'Information')
This class is in the .NET namespace System.Windows.Forms.

If the script is executed in PowerShell consloe (powershell.exe) you have to load the assembly System.Windows.Forms
Add-Type -AssemblyName System.Windows.Forms
Is the script running in PowerShell ISE (powershell_ise.exe) the graphics are loaded already.

If you do not want the 'OK' written on the PowerShell console when OK in the Message Box is clicked, then you can stream it to the CmdLet Out-Null
[System.Windows.Forms.MessageBox]::Show('Hello world!', 'Hello', 'OK' ,'Information') | Out-Null

The output is generated by the MessageBoxButtons defined in the MessageBox object and what button the user pressed. In the example above ther is only one possibility („OK“) but it is possible to present other buttons to the user.
The possible MessageBoxButtons are dokumented with the MessageBoxButtons Enumeration.
The answer is from the enumration System.Windows.Forms.DialogResult, and if the answer is piped to the console it is implicit converted to a String by PowerShell.
The answer can be grabbed in a PowerShell variable and used for a more complex reaction to the DialogResult.
$Answer = [System.Windows.Forms.MessageBox]::Show('Hello world!', 'Hello', 'OkCancel' ,'Information')
switch ($Answer) {
  'OK' { 'Cheers' }
  'Cancel' { 'Having a bad day?' }
}


There are several possibilities for an icon. This is described in the documentation of the MessageBoxIcon Enumeration. In the examples above I have used the MessageBoxIcon member „Information“.

One of the nice things with the .NET Windows Forms is that it takes descriptive parameters like "OkCancel" instead of the numeric parameters to MsgBox. This is the reason to the many constant definitions in VBScript files.

The message part can be created in a more complex proces outside the Show() command.
On one occation I wanted the message to be formatted in lines that I added up during the script execution.
To keep track of each message line I added the line to an array, and before showing the message in the MessageBox, I added a NewLine (`n) in the end of each line.
[String[]]$Msg = @()
$Msg += 'Keep Calm'
$Msg += 'And'
$Msg += 'Trust a DBA'
[String]$MsgTxt = ''
$Msg | ForEach-Object { $MsgTxt += $_ + "`n" }
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show($MsgTxt, 'SQLAdmin Message', 'OK', 'Information') | Out-Null

The MessageBox is then
Keep Calm And Trust a DBA

No comments: