Last Update: Sep 04, 2024 | Published: Oct 27, 2014
Perhaps the greatest feature of the PowerShell ISE is that it is extensible. In my last few articles on the PowerShell ISE I’ve been introducing you to the PSISE object model. The next step is to integrate some of these commands and functions directly into the ISE. We can do this by adding commands directly to the ISE menu.
The PowerShell ISE has an Add-Ons menu, which I’ve highlighted in the figure below.
Microsoft, members of the PowerShell community and you, can add items to this menu using the PSISE object model. Each PowerShell tab has an AddOnsMenu property.
This gets a little tricky because you don’t add an item here, but rather to the Submenus property using the Add() method. The syntax looks like this:
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add(,{ },)
You have to specify something for all three values, although you really only need the first two. If you don’t want to include a keyboard shortcut, such as Ctrl+Alt+7, you can use $Null. In way of demonstration, I’ll add a link to Notepad with a keyboard shortcut.
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Open _Notepad",{Notepad.exe},"Ctrl+Alt+N")
In the ISE, I can use the menu or the keyboard shortcut to launch Notepad. Remember that your command must be a script block, so don’t forget the {}.
If you make a mistake, then the best thing to do is to exit and restart the PowerShell ISE. In fact, this should tell you that this change only lasts for as long as your PowerShell session is open. You can put the command in your ISE profile script to make the change persistent, however. With that said, I usually pipe the command to Out-Null to suppress the pipeline output since I don’t really need to see it.
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Open _Notepad",{Notepad.exe},"Ctrl+Alt+N") | Out-Null
But let’s integrate the PSISE object model. How about an add-on to open the current file in Notepad? First, test your command in the ISE.
PS C:scripts> &{Notepad $psise.CurrentFile.FullPath}
I’m testing inside a scriptblock since that is what I’ll eventually be using. Here’s my final code:
$action = {if ($psise.CurrentFile.IsSaved) { Notepad $psise.CurrentFile.FullPath } else { Write-Warning "$($psise.CurrentFile.FullPath) has not been saved" } } $psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Open Current File in Notepad",$Action,"Ctrl+Alt+O") | Out-Null
I added some logic to the scriptblock so that only saved files are opened in Notepad. Otherwise a warning will be written to the command pane.
You could add as many shortcuts as you need to this menu.
I think there’s also a better option to create your own submenu and add items there. You accomplish this by adding a shortcut without scriptblock and shortcut.
$MyMenu = $psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("MyTools",$null,$null)
I saved the result to a variable. $MyMenu is an ISEMenuItem object that has its own Submenus property, which means I can add an item to it like this:
$MyMenu.Submenus.Add( "Save all unsaved files", {$psise.CurrentPowerShellTab.Files.Where({-Not $_.isSaved -AND -Not $_.IsUntitled}).Foreach({$_.save()})}, "Ctrl+Alt+S") | Out-Null
Under the MyTools menu I now have a new command.
Now I can work in the ISE and keeping my hands on the keyboard, periodically hit Ctrl+Alt+S to save all my unsaved work.
The action can be as complicated as you need it to be. If you recall a few articles ago, I demonstrated using shortcut keys to cycle through open files. However, there is not a provision for cycling through PowerShell tabs. However, it is possible to do that with the PSISE object model, where I wrote a function to do just that:
Function Get-NextISETab { [cmdletbinding()] Param() $iseTabs = $psISE.PowerShellTabs #get current tab for ($i=0; $i -le $iseTabs.count-1; $i++) { Write-Verbose $iseTabs[$i].Displayname if ($iseTabs[$i].Displayname -eq $psISE.CurrentPowerShellTab.DisplayName) { $current = $i } #check if the next index number if valid if ($current++ -ge $iseTabs.count-1) { $next = 0 } else { $next = $current++ $nextTab = $iseTabs[$next $iseTabs.SelectedPowerShellTab = $NextTa }
In order for this to work this function needs to be in my ISE profile script so every PowerShell tab would know about it. But I don’t want to have to take my hands off the keyboard, so I’ll add this to my menu.
$psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Switch next tab",{Get-NextISETab},"Ctrl+ALT+T") | out-null
I added it to the main add-ons menu. But it could have gone in MyTools as well. When using functions make sure the function is defined before you create the menu item.
With a little work, you can turn the PowerShell ISE into a tool that you control and that allows you to get more done with less effort. It might even be a little fun. If you are interested, you can download my Get-NextISETab function as a text file.
If you want to catch up on my article series about the PowerShell ISE and the ISE object model, here are the rest of the articles in the series: