Donnerstag, 25. März 2010

Removing a specific Item from a Powershell ISE Addon menu

Well in ISECreamBasic I had written the function Remove-IseMenu to remove Toplevel menus.
Thanks to Shay Levi and Jaykul it became a nice advanced function with parametersets.

You can find the code in the ISE-Cream project

Just when I finished writing the header comments Ravi wanted to use the function not restricted to toplevel menu items.

First attemps tried to search the tree, but there can be more subitems with the same name hidden in the menu structure. To get it clear I designed the following function, which requires the complete path to the item to delete:

function Remove-IseMenuItem {            

$submenu = $psise.CurrentPowerShellTab.AddOnsMenu.Submenus

for ($j = 0; $j -lt $args.count; $j++)
{
$name = $args[$j]
$count = $submenu.count
#Write-host "arg0: $name $count"
for ($i = 0; $i -lt $submenu.count; $i++)
{
$found = $false
if ($Submenu[$i].DisplayName -eq $name)
{
#Write-host "found toplevel menu $name"
$found = $True
if ( $j -eq ($args.count - 1))
{
Write-host 'Removing'
$null = $submenu.remove($Submenu[$i])
}
else
{
$submenu = $Submenu[$i].submenus
}
break
}
}
if (! $found)
{
Write-host "Menuitem not found"
break
}

}
}

Remove-IseMenuItem Edit Pad

# Remove-Child $Submenu[$i] $Name | out-null



But this looks like an old PowerShell V1 coding style. It doesn't check that all arguments are strings. Please can someone show me, how to set up a PowerShell V2 advanced function parameter declaration for this.

Kommentare:

  1. To solve your validation problem, use this parameter definition:

    param(
    [Parameter(Position = 0, ValueFromRemainingArguments = $true)]
    [ValidateNotNullOrEmpty()]
    [String[]]$Path
    )

    Then users can do any of these:

    Remove-IseMenuItem Edit Pad
    Remove-IseMenuItem -Path Edit Pad
    Remove-IseMenuItem (Edit,Pad)
    Remove-IseMenuItem -Path (Edit,Pad)
    Remove-IseMenuItem ("Edit/Pad" -split "/")
    etc...

    It will automatically convert the arguments to strings, and make sure that the array has at least one string in it. Then refer to $Path instead of $args.

    AntwortenLöschen
  2. Thanks Jason that is the solution. Now I have only to adjust my header comments.

    AntwortenLöschen
  3. I sent you an email (your GMail account) with more info.

    AntwortenLöschen
  4. I got your mail. Thank you.
    But what do I gain, when I add
    [CmdletBinding(SupportsShouldProcess = $false,SupportsTransactions = $false,ConfirmImpact = "None", DefaultParameterSetName = "")] to my above concrete function. I guess it are the defaults anyway).

    I guess that in case I had designed the function to need only the item name and to search the menu tree for the first item it finds with that name and delete it, it would be a good idea to support the whatif parameter.
    To do this i guess, I have to set SupportsShouldProcess = $true and some further actions. MSDN isn't great help in search for examples. It's more a hint of the kind, there must be some way.

    What we want are examples that demonstrate the use of new features, not just syntax.

    OK I see that it is possible to add this here, but would it improve my code?

    AntwortenLöschen
  5. Very handy. Thank you !

    AntwortenLöschen