Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!
PowerShell

Add Pop-Up Tips for PowerShell WinForms Script

IT pros who have taken the leap and dived head-long into PowerShell will eventually find themselves creating graphical PowerShell scripts and tools. This often means using Windows Forms, which is also known as WinForms. You can create some very complicated graphical tools and often IT pros do just that, where these tools are delegated for administration. I would expect the form interface to be intuitive most of the time, but perhaps you might want to add a little interactive help. You can use the ToolTip control to accomplish this.

Using a WinForms-Based PowerShell Script

Here’s a simple WinForms-based PowerShell script:

#demo-winform.ps1

[void][reflection.assembly]::loadwithpartialname("System.Windows.Forms")

# create form 1
$form1 = New-Object system.Windows.Forms.Form
$form1.text = "Computer Name"
$form1.height = 250 #120
$form1.width = 250
$form1.formborderstyle = 3

# create OK and cancel scriptblocks
$oksb = {
	$form1.dialogresult = 1
	$form1.hide()
}
$cancelsb = {
 	$form1.dialogresult = 2
	$form1.hide()
}

# create OK button
$okbutton1 = New-Object system.Windows.Forms.Button
$okbutton1.text = "OK"
$okbutton1.height=25
$okbutton1.width=75
$okbutton1.top= 121 #51
$okbutton1.left=105 #147
$okbutton1.add_click($oksb)
$form1.controls.add($okbutton1)

# create Cancel button
$cancelbutton1 = New-Object system.Windows.Forms.Button
$cancelbutton1.text = "Cancel"
$cancelbutton1.height=25
$cancelbutton1.width=75
$cancelbutton1.top= 121 #51
$cancelbutton1.left= 15 #66
$cancelbutton1.add_click($cancelsb)
$form1.controls.add($cancelbutton1)

# create label
$label1 = New-Object system.Windows.Forms.Label
$label1.text = "Enter computer name:"
$label1.left=12
$label1.top=9
$label1.width=205
$label1.height=13
$form1.controls.add($label1)

# create text box
$text1 = New-Object system.Windows.Forms.TextBox
#create a default value
$text1.Text=$env:computername
$text1.left=15
$text1.top=25
$text1.height=20
$text1.width=205
$form1.controls.add($text1)

#create some check boxes
$check1=New-Object system.Windows.Forms.CheckBox
$check1.width=150
$check1.Text= "OperatingSystem"
$check1.Top=50
$check1.Left=15
$check1.Checked=$True

$form1.Controls.add($check1)

#create some check boxes
$check2=New-Object system.Windows.Forms.CheckBox
$check2.width=150
$check2.Text= "ComputerSystem"
$check2.Top=70
$check2.Left=15
$check2.Checked=$False

$form1.Controls.add($check2)

#create some check boxes
$check3=New-Object system.Windows.Forms.CheckBox
$check3.width=150
$check3.Text= "BIOS"
$check3.Top=90
$check3.Left=15
$check3.Checked=$False

$form1.Controls.add($check3)

# show form 1
if ($form1.showdialog() -eq 2) {
	# cancelled
	break
}

# get computer info
[email protected]()

if ($check1.Checked) {
 $data = Get-WmiObject -class win32_operatingsystem -ComputerName $text1.text
 $result+= $data
}

if ($check2.Checked) {
 $data = Get-WmiObject -class win32_computersystem -ComputerName $text1.text
 $result+= $data
}

if ($check3.Checked) {
 $data = Get-WmiObject -class win32_bios -ComputerName $text1.text
 $result+= $data
}

# create results form
# create form 2
$form2 = New-Object system.Windows.Forms.Form
$form2.text = "WMI Results: " +($text1.text).toUpper()
$form2.height = 250
$form2.width = 400
$form2.formborderstyle = 3

# create OK and cancel scriptblocks
$oksb2 = {
	$form2.dialogresult = 1
	$form2.hide()
}

# create OK button
$okbutton2 = New-Object System.Windows.Forms.Button
$okbutton2.text = "OK"
$okbutton2.height=25
$okbutton2.width=75
$okbutton2.top=150
$okbutton2.left=147
$okbutton2.add_click($oksb2)
$form2.controls.add($okbutton2)

# Create a new text box
# create text box
$text2 = New-Object System.Windows.Forms.TextBox
$text2.left=15
$text2.top=9
$text2.height=100
$text2.width=360
$text2.multiline = $True
$text2.scrollbars = "Vertical"
$text2.Font="Lucida Console"
$text2.wordwrap = $True
$text2.text = ($result | Out-String).Trim()
$form2.controls.add($text2)

$form2.showdialog() | Out-Null


The script will present a simple form with a few check boxes.

PowerShell script displays a dialog box. (Image Credit: Jeff Hicks)
PowerShell script displays a dialog box. (Image Credit: Jeff Hicks)

Click, OK and a few WMI queries will run, presenting the results in a new form.

WMI results. (Image Credit: Jeff Hicks)
WMI results. (Image Credit: Jeff Hicks)

This isn’t especially complicated, but let’s add some help. The way I handle this in my forms is to display the help when the user hovers the mouse over a given control. The help text is displayed in the ToolTip control. First, let’s add the control to the script.

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

$tooltip1 = New-Object System.Windows.Forms.ToolTip

When working with WinForms in a PowerShell script, we have to connect some PowerShell action with some event from the form, such as clicking a button or hovering the mouse.

In my projects, I define these actions in scriptblocks. I’m going to write a scriptblock to display the pop-up help for selected controls.

$ShowHelp={
    #display popup help
    #each value is the name of a control on the form.				
     Switch ($this.name) {
        "text1"  {$tip = "Enter the name of a computer"}
        "check1" {$tip = "Query Win32_OperatingSystem"}
        "check2" {$tip = "Query Win32_Computersystem"}
        "check3" {$tip = "Query Win32_BIOS"}
      }
     $tooltip1.SetToolTip($this,$tip)
} #end ShowHelp

The scriptblock includes a switch statement that looks at a string and depending on what it matches, in this case text1 or check2, it assigns a value to the variable $tip and applies the value to the ToolTip object. The $this refers to active control. For each control in my form, I’ll add a connection for the _MouseHover event.

#give the control a name
$text1.name="text1"
#connect the ShowHelp scriptblock with the _MouseHover event for this control
$text1.add_MouseHover($ShowHelp)
$form1.controls.add($text1)

When the form detects that event, it will run the associated command, which in my script is the $ShowHelp scriptblock. If the user hovers on the $Text1 control, then $this will be that control. You must make sure you give each control a name in order for the switch statement to work. The control name doesn’t have to match the variable name, but mine just happens to. I can repeat this process for the other controls in my form. Here is my revised script:

#demo-winform-with-tooltip.ps1

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

#define a tooltip object
$tooltip1 = New-Object System.Windows.Forms.ToolTip

<#
define a scriptblock to display the tooltip
add a _MouseHover event to display the corresponding tool tip
 e.g. $txtPath.add_MouseHover($ShowHelp)
 #>
$ShowHelp={
	#display popup help
    #each value is the name of a control on the form.
    
	Switch ($this.name) {
		"text1"  {$tip = "Enter the name of a computer"}
		"check1" {$tip = "Query Win32_OperatingSystem"}
        "check2" {$tip = "Query Win32_Computersystem"}
        "check3" {$tip = "Query Win32_BIOS"}
	}
	$tooltip1.SetToolTip($this,$tip)
} #end ShowHelp


# create form 1
$form1 = New-Object system.Windows.Forms.Form
$form1.text = "Computer Name"
$form1.height = 250 #120
$form1.width = 250
$form1.formborderstyle = 3

# create OK and cancel scriptblocks
$oksb = {
	$form1.dialogresult = 1
	$form1.hide()
}
$cancelsb = {
 	$form1.dialogresult = 2
	$form1.hide()
}

# create OK button
$okbutton1 = New-Object system.Windows.Forms.Button
$okbutton1.text = "OK"
$okbutton1.height=25
$okbutton1.width=75
$okbutton1.top= 121 #51
$okbutton1.left=105 #147
$okbutton1.add_click($oksb)
$form1.controls.add($okbutton1)

# create Cancel button
$cancelbutton1 = New-Object system.Windows.Forms.Button
$cancelbutton1.text = "Cancel"
$cancelbutton1.height=25
$cancelbutton1.width=75
$cancelbutton1.top= 121 #51
$cancelbutton1.left= 15 #66
$cancelbutton1.add_click($cancelsb)
$form1.controls.add($cancelbutton1)

# create label
$label1 = New-Object system.Windows.Forms.Label
$label1.text = "Enter computer name:"
$label1.left=12
$label1.top=9
$label1.width=205
$label1.height=13
$form1.controls.add($label1)

# create text box
$text1 = New-Object system.Windows.Forms.TextBox
#create a default value
$text1.Text=$env:computername
$text1.left=15
$text1.top=25
$text1.height=20
$text1.width=205
#give the control a name
$text1.name="text1"
#connect the ShowHelp scriptblock with the _MouseHover event for this control
$text1.add_MouseHover($ShowHelp)
$form1.controls.add($text1)

#create some check boxes
$check1=New-Object system.Windows.Forms.CheckBox
$check1.width=150
$check1.Text= "OperatingSystem"
$check1.Top=50
$check1.Left=15
$check1.Name = "check1"
$check1.add_MouseHover($ShowHelp)
$check1.Checked=$True

$form1.Controls.add($check1)

#create some check boxes
$check2=New-Object system.Windows.Forms.CheckBox
$check2.width=150
$check2.Text= "ComputerSystem"
$check2.Top=70
$check2.Left=15
$check2.Name = "check2"
$check2.add_MouseHover($ShowHelp)
$check2.Checked=$False

$form1.Controls.add($check2)

#create some check boxes
$check3=New-Object system.Windows.Forms.CheckBox
$check3.width=150
$check3.Text= "BIOS"
$check3.Top=90
$check3.Left=15
$check3.Name = "check3"
$check3.add_MouseHover($ShowHelp)
$check3.Checked=$False

$form1.Controls.add($check3)

# show form 1
if ($form1.showdialog() -eq 2) {
	# cancelled
	break
}

# get computer info
[email protected]()

if ($check1.Checked) {
 $data = Get-WmiObject -class win32_operatingsystem -ComputerName $text1.text
 $result+= $data
}

if ($check2.Checked) {
 $data = Get-WmiObject -class win32_computersystem -ComputerName $text1.text
 $result+= $data
}

if ($check3.Checked) {
 $data = Get-WmiObject -class win32_bios -ComputerName $text1.text
 $result+= $data
}

# create results form
# create form 2
$form2 = New-Object system.Windows.Forms.Form
$form2.text = "WMI Results: " +($text1.text).toUpper()
$form2.height = 250
$form2.width = 400
$form2.formborderstyle = 3

# create OK and cancel scriptblocks
$oksb2 = {
	$form2.dialogresult = 1
	$form2.hide()
}

# create OK button
$okbutton2 = New-Object System.Windows.Forms.Button
$okbutton2.text = "OK"
$okbutton2.height=25
$okbutton2.width=75
$okbutton2.top=150
$okbutton2.left=147
$okbutton2.add_click($oksb2)
$form2.controls.add($okbutton2)

# Create a new text box
# create text box
$text2 = New-Object System.Windows.Forms.TextBox
$text2.left=15
$text2.top=9
$text2.height=100
$text2.width=360
$text2.multiline = $True
$text2.scrollbars = "Vertical"
$text2.Font="Lucida Console"
$text2.wordwrap = $True
$text2.text = ($result | Out-String).Trim()
$form2.controls.add($text2)

#display form 2
$form2.showdialog() | Out-Null

Now when the user hovers the mouse over one the defined controls, the Tooltip control displays my defined help message.

The form now displays a help message. (Image Credit: Jeff Hicks)
The form now displays a help message. (Image Credit: Jeff Hicks)

When the mouse moves away, the tooltip automatically goes away. Controls without the attached event will have no popup help. I hard coded my popup help, but it wouldn’t be that difficult to read help strings from an external source. This would be especially helpful if you need to provide localized popup text.

You can do all of this manually for simple forms. However, IT pros rarely take the simple approach. A popular tool for creating WinForm-based PowerShell scripts is a commercial tool from SAPIEN called PowerShell Studio. Because this product is widely used, I’ll demonstrate how to add tool tips to a PowerShell Studio project in a future article.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (1)

One response to “Add Pop-Up Tips for PowerShell WinForms Script”

  1. Omega

    Thanks Jeff! PowerShell + WinForms = Win!

Leave a Reply

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.

RSVP Now

Sponsored By