Hi,
a long time ago I wrote a Menu function for quickly choose predefined options in a script. An example
Source the menu.ps1 in your script and call fShowMenu. This will show the menu. The function needs 2 parameters:
Parameter 1: The menu title as string
Parameter 2: A hashtable with the Menuentries. The key of an Menuitem is returned by the function the corresponding value is shown at the menu.
# Source the file . .\menu.ps1 # Call Menu funtion fShowMenu "Choose your favorite Band" @{"sl"="Slayer";"me"="Metallica";"ex"="Exodus";"an"="Anthrax"}
Now you can navigate through the menu by pressing the up and down arrow keys and the return key to quit the menu or you can select an menu entry directly by pressing the leading number or character of the menu item at the keyboard.
PS D:\> fShowMenu "Choose your favorite Band" @{"sl"="Slayer";"me"="Metallica";"ex"="Exodus";"an"="Anthrax"} Choose your favorite Band 1: Metallica 2: Exodus 3: Anthrax 4: Slayer Your choice: 3 an
In this example “3” selects “Anthrax” and the function returns “an”.
Up to 90 menu items are possible. This should be enough for the most cases.
Michael
Where does the 90 item limit come from?
The limit comes from the keyboard shortcut. You have only to press one key without to hit return to select an entry and therefore only a-z, A-Z, 0-9 is available.
Michael
Is there a way to run a program using the menu in ISE?
I get
Choose your favorite Band
The handle is invalid.
At C:\Projects\PowerShell\Menu\Menu.ps1:67 char:2
+ $iMenuStartLineAbsolute=[System.Console]::CursorTop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], IOException
+ FullyQualifiedErrorId : System.IO.IOException
Exception setting “CursorTop”: “The handle is invalid.
Hi chavv,
the Powershell ISE doesn’t have a “real” console, its a Windows form and therefore its not possible to use [System.Console] proberties.
Michael
Thanks, but what about “ordering” of items?
They don’t appear in the order they are written, even your example gives:
1: Metallica
2: Anthrax
3: Slayer
4: Exodus
while in the source they are
@{“sl”=”Slayer”;”me”=”Metallica”;”ex”=”Exodus”;”an”=”Anthrax”}
The only workaround I found – importing function into main program source and using “global” hashtable variable. No matter what I do, if I send the has as parameter it gets borked in the function.
Well, I risk to become annoying, but I found a solution 😀
Changing param declaration of the function (it seems the type [System.Collections.IDictionary] works with ordered/not ordered hashtables just fine ):
param (
[System.String]$sMenuTitle,
# [System.Collections.Hashtable]$hMenuEntries
[System.Collections.IDictionary] $hMenuEntries
)
For those who wants to use a order menu, the below will help.
Do chavv’s actions above, where you update [System.Collections.Hashtable]$hMenuEntries to [System.Collections.IDictionary] $hMenuEntries on line 17.
In your script where you use the function, prepare the hashtable casting it as [ordered]. Then feed that into the fShowMenu.
#Example PowerShell, it should produce the menu as ordered below in the hashtable.
$MyOrderMenuList = [ordered] @{
“sl”=”Slayer”;
“me”=”Metallica”;
“ex”=”Exodus”;
“an”=”Anthrax”
}
$MenuResponse = fShowMenu “Choose your favorite Band” $MyOrderMenuList
$MenuResponse
#End Example