Home Blog Adding New Context Menus

Adding New Context Menus

(edited May 4, 2016) If you feel something is missing in ISESteroids, just add it yourself! Let’s check out in this post how you can add your own custom commands to the user interface.

Want to see a real project in action first, that is using these techniques? Have a look here: http://commonsensedev.com/2015/10/using-tortoisesvn-version-control-with-isesteroids/.  This adds SVN version control capabilities to ISESteroids using exactly the simple techniques described below.

Add-SteroidsContextCommand: Adding a “Visit Link” Command

Let’s start with adding a new context command to ISESteroids. When you right-click a URL, you may want to navigate to that URL. So here is an example that adds “Visit Link in String”:

Add context menu command

Your new context menu command appears only if the clicked item is a string, and if the string contains a URL. Here is a script that creates the command:

$regex = '\b(?:https?:\/\/)?(?:[\da-z\\\.-]+)\.(?:[a-z\\\.]{2,6})(?:[\/\w\\ \.-]*)*\/?\b'
# code to execute
$code = {
 $regex = '\b(?:https?:\/\/)?(?:[\da-z\.-]+)\.(?:[a-z\.]{2,6})(?:[\/\w \.-]*)*\/?\b'
 $text = $args[1]
 if ($text -match $regex)
 Start-Process iexplore $matches[0]
# add context menu command
Add-SteroidsContextMenuCommand -DisplayName 'Visit Link in String' -ScriptBlock $code -ToolTip 'Displays Link in Browser' -TokenType String -RegularExpression $regex
# right-click string and look for "Visit Link in String"
$url = 'Here is a URL to visit: http://www.powertheshell.com.'
$nourl = 'Here is no URL to visit: some://thing'

When you run this inside ISESteroids, and then right-click the string in $url, you see a new context menu command “Visit Link in String”. When you click it, Internet Explorer opens the URL for you. When you right-click the other string in $nourl, the command is not there.

Creating Highly Specific Context Commands

Key to this is the cmdlet Add-SteroidsContextMenuCommand. It takes a displayname and a tooltip, plus a scriptblock of code that you would like to execute.

When the scriptblock executes, it receives two arguments: $args[0] is the editor object being clicked, and $args[1] is the data, in this case the clicked string.

Since you do not want to display your new command everywhere, -TokenType String tells the cmdlet that the new command should only be displayed for strings. And since you don’t want to show it for every string, you can add a regular expression identifying a valid URL.

Or How About “Ping IP Address” Instead?

The regular expression uses word boundaries (“\b”) on both ends to make sure the URL is a separate word and not part of something else. You could use other regular expressions, for example identfying an IP address, and then add your own context menu command that would ping it.

Removing Custom Commands

Use Remove-SteroidsContextMenuCommand to remove a command within the current session. This can be useful when you are playing with the code and running it multiple times.

ISESteroids will never overwrite an existing context command, even if it has the same name, because it could use different options, so there are valid use cases to have multiple custom context commands with the same name.

Keeping Custom Commands Around

Adjustments to your context menus are lost when ISESteroids closes. To keep them, add the code to your profile script. You can easily open it via menu: File/Open Profile Script/Current User.

Add-SteroidsEditorTabCommand: Adding Commands to a Tab

In addition to context commands in the editor pane, you can also add your own commands to an editor tab. Let’s try and add a command that copies the current file to another location, for example a staging area.

adding context command to tab

In essence, the next example illustrates how you can bind any custom command to the editor tab. Note that you can use a backslash in the command name to create submenus.

$code = 
 # find out the current editor text and the
 # current file name
 $text = $psise.CurrentFile.Editor.Text
 $filename = Split-Path -Path $psise.CurrentFile.FullPath -Leaf
 # this is the path where the script is copied to
 # can be anything, will be the temp folder in this demo
 $path = $env:temp
 $file = Join-Path -Path $Path -ChildPath $filename
# copy editor content to new file
 $text | Set-Content -Path $file -Encoding UTF8
 # show new file in explorer
 explorer.exe "/select,$file"
Add-SteroidsEditorTabCommand -DisplayName 'My Tools\Copy Script to Staging' -ScriptBlock $code -ToolTip 'Copies current script to the staging area' -Force

When you run this code and then right-click any editor tab, you find your new custom command at the bottom of the tab context menu.