Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun: Messagebox Writer

Posted on January 31, 2014

yellowsub For today's fun I'm revisiting a topic I'm sure I've written about in the past and that is creating a graphical message box in PowerShell. There are a few ways you can do this from using the Visual Basic classes, the old standard WScript.Shell object from VBScript or using WinForms. They all basically work the same way and you probably can't tell from the message box what was used to create it. So I took my version of New-MessageBox which uses the Visual Basic interaction class and updated it a bit.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Here's the new function.

#requires -version 3.0

Function New-Messagebox {

<#
.SYNOPSIS
Display a VisualBasic style message box.

.DESCRIPTION
This function will display a graphical messagebox, like the one from VisualBasic
or VBScript. You must specify a message. The default button is OKOnly and the 
default icon is for Information. If you want to use the value from a button click
in a PowerShell expression, use the -Passthru parameter.

The message box will remain displayed until the user clicks a button. The box may 
also not appear on top, but if you have audio enabled you should hear the Windows 
exclamation sound.

As an added bonus you can use the -Voice parameter to hear the prompt spoken aloud.

.PARAMETER Message
The text to display. Keep it short. The command will throw an exception if the
message length is greater than 800.

.PARAMETER Button
The button set to display. The default is OKOnly. Possible values are:
    OkOnly
    OkCancel
    AbortRetryIgnore
    YesNoCancel
    YesNo
    RetryCancel

.PARAMETER Icon
The icon to display. The default is Information. Possible values are:
    Critical
    Question
    Exclamation
    Information

.PARAMETER Title
The message box title. The default is no title. The title should be less than 
60 characters long, otherwise it will be truncated. Shorter is always better.

.PARAMETER Passthru
Use this parameter if you want the button value to be passed to the pipeline.

.PARAMETER Voice
Use text to speech to announce the prompt. This parameter has an alias of Speak.

.EXAMPLE
.Parameter VoiceGender
The command will use the default voice. Or you can specify either a Male or Female
voice. This parameter will have no affect unless you also use -Voice. This 
parameter has an alias of Gender.

.EXAMPLE
PS C:\> New-Messagebox "Time to go home!"
Display a message box with no title and the OK button.

.EXAMPLE 
PS C:\> $rc= New-Messagebox -message "Do you know what you're doing?" -icon exclamation -button "YesNoCancel" -title "Hey $env:username!!" -passthru
Switch ($rc) {
 "Yes" {"I hope your resume is up to date."}
 "No" {"Wise move."}
 "Cancel" {"When in doubt, punt."}
 Default {"nothing returned"}
}

.EXAMPLE
PS C:\> New-MessageBox -message "Are you the walrus?" -icon question -title "Hey, Jude" -button YesNo -voice

Display the message box and speak the message.

.NOTES
Version      : 2.0
Last Updated : 1/30/2014

Learn more:
  PowerShell in Depth: An Administrator's Guide
  PowerShell Deep Dives
  Learn PowerShell 3 in a Month of Lunches 
  Learn PowerShell Toolmaking in a Month of Lunches 
 

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

"Those who forget to script are doomed to repeat their work."

.LINK
https://jdhitsolutions.com/blog/

.INPUTS
None
.OUTPUTS
[system.string]

#>

[cmdletbinding()]

Param (
[Parameter(Position=0,Mandatory=$True,
HelpMessage="Specify a display message or prompt for the message box",
ValueFromPipelinebyPropertyName=$True)]
[ValidateNotNullorEmpty()]
[Alias("prompt")]
[ValidateScript({
 if ($_.length -gt 800) {
   Throw "Keep the message to less than 800 characters"
 }
 else {
    $True
 }
})]
[string]$Message,

[Parameter(ValueFromPipelinebyPropertyName=$True)]
[ValidateSet("OkOnly","OkCancel","AbortRetryIgnore","YesNoCancel","YesNo","RetryCancel")]
[string]$Button="OkOnly",

[Parameter(ValueFromPipelinebyPropertyName=$True)]
[ValidateSet("Critical", "Question", "Exclamation", "Information")]
[string]$Icon="Information",
[ValidateScript({
 if ($_.length -gt 60) {
   Throw "Keep the title to less than 60 characters"
 }
 else {
    $True
 }
})]
[Parameter(ValueFromPipelinebyPropertyName=$True)]
[string]$Title,

[Parameter(ValueFromPipelinebyPropertyName=$True)]
[switch]$Passthru,

[Parameter(ValueFromPipelinebyPropertyName=$True)]
[Alias("Speak")]
[switch]$Voice,

[Parameter(ValueFromPipelinebyPropertyName=$True)]
[ValidateSet("Male","Female")]
[Alias("Gender")]
[string]$VoiceGender

)

Write-Verbose "Starting $($myinvocation.MyCommand)"
Write-Verbose "Title = $Title"
Write-Verbose "Icon = $icon"
Write-Verbose "Button = $Button"
Write-Verbose "Message = $Message"


Try { 
    Write-Verbose "Loading VisualBasic assembly"
    #load the necessary assembly
    Add-Type -AssemblyName "Microsoft.VisualBasic" -ErrorAction Stop     
    if ($voice) {
        Write-Verbose "Loading speech assembly"
        Try { 
            #load the necessary assembly
            Add-Type -assembly system.speech -ErrorAction Stop
            $synth = new-object System.Speech.Synthesis.SpeechSynthesizer -ErrorAction Stop
            if ($VoiceGender) {
                Write-Verbose "Selecting a $voiceGender voice"
                $synth.SelectVoiceByHints($VoiceGender)
            }
            else {
                Write-Verbose "Using default voice"
            }
            $synth.SpeakAsync($message) | Out-Null
        }
        Catch {
            Write-Warning "Failed to add System.Speech assembly or create the SpeechSynthesizer object."
            Write-Warning $error[0].Exception.Message
            #bail out
            Return
        }
    } #if $voice    
    
    #create the message box using the parameter values
    #Whatever button the user clicks will be the return value
    $returnValue = [microsoft.visualbasic.interaction]::Msgbox($message,"$button,$icon",$title)
}
Catch {
    Write-Warning "Failed to add Microsoft.VisualBasic assembly or create the messagebox."
    Write-Warning $error[0].Exception.Message
}
#write return value if -Passthru is called
if ($Passthru) {
    Write-Verbose "Passing return value from message box"
    Write-Output $returnValue
}

Write-Verbose "Ending $($myinvocation.MyCommand)"

} #end function

#set an optional alias
Set-Alias -name nmb -Value New-Messagebox

This version has been tweaked to include better parameter validation. I also modified it so that the parameters accept pipeline input by property name. I think the function is pretty well documented so I won't spend much time discussing it. You can try it out for yourself. Be sure to test with bad parameter values so you can see how validation works.

If you had grabbed an older version of this function, there is one breaking change. In the past I think I had the function always write the clicked button value to the pipeline. Now the function doesn't write anything to the pipeline unless you use -Passthru. When you run a command like this:

new-messagebox -Title "Friday Fun" -Message "Do you think PowerShell is fun?" -Icon Question -Button YesNo

You will get this:

MsgBoxYesNo

Nothing will be written to the pipeline because I didn't use -Passthru. Now for the extra-fun part. If you read through the code listing, you may have seen references to a speech assembly. I figured, why not include an option to have the message spoken aloud? So I'm using the System.Speech.Synthesis.SpeechSynthesizer class to speak the text in the message box. Use the -Voice parameter to turn this on. PowerShell will use the default voice for your system. But wait, there's more! I also included a second parameter, VoiceGender, so that you can specify if you want a Male or Female voice. On later client operating systems I believe you get one of each automatically.

https://jdhitsolutions.com/blog/wp-content/uploads/2014/01/demo-messagebox.mp4

Click here to view the video full size or right-click and save the video clip.

Here's the sample script I ran.

#requires -version 3.0

#dot source the New-MessageBox function

. C:\scripts\New-MessageBox.ps1

$r = New-Messagebox -Message "Are you the walrus?" -Title "Hey Jude" -Icon Question -Button YesNo -Voice -VoiceGender Female -Passthru

If ($r -eq "Yes") {
    Write-Host "Excellent! goo goo g'joob." -ForegroundColor Green
}
else {
    $r = New-Messagebox -Message "Are you the eggman?" -Title "Hey Jude" -Icon Question -Button YesNo -Voice -VoiceGender Female -Passthru
    if ($r -eq "Yes") {
        Write-Host "Excellent! They are the eggmen." -ForegroundColor Green
    }
    else {
        Write-Host "Bummer. Let it be." -ForegroundColor Yellow
    }
}

Enjoy!


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

2 thoughts on “Friday Fun: Messagebox Writer”

  1. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, MSExchange, SystemCenter and more – #66 - Windows Management - TechCenter - Dell Community
  2. Jimbob says:
    February 14, 2014 at 9:28 am

    Pretty slick. Thanks man!

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d