Getting Started With Custom Shortcut Menus in PowerShell

Shortcut menus can enhance the usability and efficiency of PowerShell GUI applications. Here’s how to integrate right-click support into PowerShell GUIs.

Brien Posey

May 14, 2024

5 Min Read
computer mouse on binary code background
Alamy

Ever since the days of Windows 95, Microsoft has enabled access to shortcut menus (or context menus, as Microsoft calls them) by right-clicking on an object. Recently, while working with a GUI-based PowerShell script I had developed, I caught myself instinctively trying to right-click on an object within the interface. It highlighted how right-clicking is a common user interaction pattern in many software interfaces. This led me to consider whether I could integrate right-click support into a PowerShell GUI.

As it turns out, PowerShell allows you to create elaborate and useful shortcut menus. In this article, I will show you how it’s done.

What Normally Happens When You Right-Click Objects?

Before showing you how to build a shortcut menu in PowerShell, let's look at what normally happens when you right-click objects within a PowerShell GUI. To illustrate the concept, I have prepared a really simple script:

Add-Type -AssemblyName System.Windows.Forms

# Create Form
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Shortcut Menu Demo"
$Form.Size = New-Object System.Drawing.Size(1000,800)
$Form.FormBorderStyle = "FixedDialog"

# Create text box
$Textbox = New-Object System.Windows.Forms.TextBox
$Textbox.Multiline = $True
$Textbox.font="Arial,14"
$Textbox.Size = New-Object System.Drawing.Size(400,200)
$Textbox.Location = New-Object System.Drawing.Point(20,20)
$Form.Controls.Add($textbox)

# Show form
$Form.ShowDialog() | Out-Null

This script creates a basic PowerShell GUI containing a single text box. If you right-click within the text box, PowerShell does indeed display a shortcut menu. However, the menu shown is the default Windows shortcut menu (Figure 1). It’s the same menu that you would encounter if you right-click within Notepad (Figure 2).

screenshot showing the default shortcut menu in PowerShell

Figure 1. This is the shortcut menu that PowerShell displays by default.

Related:Solving the PowerShell GUI Paradox (With Example Scripts)

screenshot showing that the Notepad shortcut menu is the same as PowerShell shortcut menu

Figure 2. Notepad displays the same shortcut menu.

To demonstrate how to build custom shortcut menus, I have added a shortcut menu to the script we saw above. This custom shortcut menu features Copy and Paste commands.

Add-Type -AssemblyName System.Windows.Forms

# Create Form
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Shortcut Menu Demo"
$Form.Size = New-Object System.Drawing.Size(1000,800)
$Form.FormBorderStyle = "FixedDialog"

# Create text box
$Textbox = New-Object System.Windows.Forms.TextBox
$Textbox.Multiline = $True
$Textbox.font="Arial,14"
$Textbox.Size = New-Object System.Drawing.Size(400,200)
$Textbox.Location = New-Object System.Drawing.Point(20,20)
$Form.Controls.Add($textbox)

# Shortcut Menu
$ShortcutMenu = New-Object System.Windows.Forms.ContextMenu

# First Menu Choice (Copy)
$MenuItemCopy = New-Object System.Windows.Forms.MenuItem
$MenuItemCopy.Text = "Copy"
$MenuItemCopy.Add_Click({
    $textbox.Copy()
})

# Second Menu Choice (Paste)
$MenuItemPaste = New-Object System.Windows.Forms.MenuItem
$MenuItemPaste.Text = "Paste"
$MenuItemPaste.Add_Click({
    $Textbox.Paste()
})
$ShortcutMenu.MenuItems.AddRange(@($menuItemCopy, $menuItemPaste))

# Attach context menu to text box
$Textbox.ContextMenu = $ShortcutMenu

# Show form
$Form.ShowDialog() | Out-Null

As you can see, the script above closely resembles the previous script, but it includes additional code for generating a shortcut menu. The first thing you will probably notice is that the shortcut menu is treated as an object.

The basic process for building a PowerShell GUI involves creating a form, defining a series of objects (such as text boxes, buttons, or sliders), and then pinning those objects to the form. While it’s tempting to think of a shortcut menu as an attribute of an object, a shortcut menu is, in fact, an object itself.

However, this is not to say that there is no relationship between a shortcut menu and other objects. On the contrary, PowerShell supports an object attribute known as a context menu. Take a look at the third to last line of code in the script:

$Textbox.ContextMenu = $ShortcutMenu

This attribute doesn’t do anything by itself. It must be pointed toward a ContextMenu object to work.

Like other PowerShell GUI objects, the ContextMenu object requires you to create the object and then define various attributes for the object. Context menus support many of the same standard attributes as other GUI objects, but one attribute stands out as both unique and indispensable: MenuItems.

Just as the shortcut menu is a standalone object, so are the individual items within it. In my sample script, for example, there are two menu options – Copy and Paste – both defined as MenuItem objects.

The sample script uses two attributes in conjunction with the MenuItem objects. The first is the Text attribute. The Text attribute controls the text that is displayed for a particular menu option.The shortcut menu I created contains Copy and Paste options. The word “Copy” is the value that is assigned to the Text attribute for the Copy menu option.

The other attribute used with menu items is Add_Click. This attribute controls the action taken when a menu item is clicked. In this case, the Add_Click actions simply interact with the Windows clipboard for copying or pasting items. However, Add_Click attributes offer broader possibilities than demonstrated in this script.

Functionally, the Add_Click attribute works very similarly to the Click Action attribute used with buttons. Button click actions commonly execute entire blocks of code. A click action can even be configured to call a function, and it’s possible to do exactly that with the Add_Click attribute. You could easily create a menu option that, when clicked, calls a function within your script.

The last thing that I want to point out about the sample script is this line:

$ShortcutMenu.MenuItems.AddRange(@($menuItemCopy, $menuItemPaste))

As mentioned earlier, the context menu and the individual options displayed on the menu are objects. As such, we need a line of code to establish a relationship between these objects. The line of code shown above accomplishes this.

By adding the objects associated with individual menu options to the menu object as an array, the menu options become associated with the menu itself. Additionally, the menu is associated with another object – a text box in this case.

About the Author(s)

Brien Posey

Brien Posey is a bestselling technology author, a speaker, and a 20X Microsoft MVP. In addition to his ongoing work in IT, Posey has spent the last several years training as a commercial astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space.

http://brienposey.com/

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.