
close
close
A while back I wrote a few articles on creating a menu driven script in the PowerShell console. In those articles, I used Read-Host to prompt the user for a choice.
If you don’t mind digging into the .NET Framework, then that’s not your only option. You have most likely encountered something like this in PowerShell:
Typical PowerShell prompt for choice (Image Credit: Jeff Hicks)
advertisment
The PromptForChoice method (Image Credit: Jeff Hicks)
$coll = @()
Next, I’ll create one of these ChoiceDescription objects and save the result to a variable.
$c = [System.Management.Automation.Host.ChoiceDescription]::new("Choice &1")
The text “Choice &1” will be displayed in the prompt. The & indicates what character to use for the choice. Whatever immediately follows will be used as you’ll see. In this case, the number 1 will be the option. What does $c look like?
The choice object (Image Credit: Jeff Hicks)
advertisment
$c.HelpMessage = "run choice 1 commands"
The choice object with a help message (Image Credit: Jeff Hicks)
$coll+=$c
It doesn’t make sense to have a prompt for choice menu with only a single item, so I’ll add some more.
advertisment
$d = [System.Management.Automation.Host.ChoiceDescription]::new("Choice &2") $coll+=$d $e = [System.Management.Automation.Host.ChoiceDescription]::new("Choice &3") $coll+=$e $f= [System.Management.Automation.Host.ChoiceDescription]::new("Choice &4") $coll+=$f $g = [System.Management.Automation.Host.ChoiceDescription]::new("Choice &5") $coll+=$g $q = [System.Management.Automation.Host.ChoiceDescription]::new("&Quit") $coll+=$q
The collection of choices (Image Credit: Jeff Hicks)
$r = $host.ui.PromptForChoice("Your Options","Select a choice",$coll,0)
This is what I get when running in the PowerShell ISE:
ISE choice prompt (Image Credit: Jeff Hicks)
PowerShell console choice prompt (Image Credit: Jeff Hicks)
Switch ($r) { 0 { Write-Host "I am the 1st choice" -foregroundcolor yellow } 1 { Write-Host "I am the 2nd choice" -foregroundcolor yellow } 2 { Write-Host "I am the 3rd choice" -foregroundcolor yellow } 3 { Write-Host "I am the 4th choice" -foregroundcolor yellow } 4 { Write-Host "I am the 5th choice" -foregroundcolor yellow } 5 { Write-Host "Thank you" -ForegroundColor green } }
Remember that arrays start counting at 0. Here’s the complete script in action.
The choice prompt in action (Image Credit: Jeff Hicks)
$coll = @()
I’ll create my first entry and add a help message.
$a = [System.Management.Automation.Host.ChoiceDescription]::new("&Services") $a.HelpMessage = "Get Running Services"
Before I add it to the array, I’m going to add a new member to the object using Add-Member.
$a | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-service | where {$_.status -eq "running"}} –force
I’ve added a new method called Invoke that will run the scriptblock assigned to the Value parameter. I can even test it.
Testing the new method (Image Credit: Jeff Hicks)
$coll+=$a $b = [System.Management.Automation.Host.ChoiceDescription]::new("&Processes") $b.HelpMessage = "Get top processes" $b | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-Process | sort WS -Descending | select -first 10} -force $coll+=$b $c = [System.Management.Automation.Host.ChoiceDescription]::new("&Disks") $c.HelpMessage = "Get disk information" $c | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-Ciminstance win32_logicaldisk -filter "drivetype=3"} -force $coll+=$c $q = [System.Management.Automation.Host.ChoiceDescription]::new("&Quit") $q.HelpMessage = "Quit and exit" $q | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Write-Host "Have a nice day." -ForegroundColor Green } -force $coll+=$q
I can prompt for a choice:
$r = $host.ui.PromptForChoice("Task Menu","Select a task:",$coll,0)
Because the value of $r is the index number of the selected item from $coll, I can run my Invoke method.
$coll[$r].invoke()
Invoking the selected choice (Image Credit: Jeff Hicks)
Demo in the console (Image Credit: Jeff Hicks)
do { $r = $host.ui.PromptForChoice("Task Menu","Select a task:",$coll,0) $coll[$r].invoke() | Out-Host } Until ($r -eq $coll.count-1)
The prompt will keep looping until the last item is selected, which is my Quit choice.
Looping (Image Credit: Jeff Hicks)
cls $Title = "Task Menu" $Caption = @" 1 - Get Running Services 2 - Get Top Processes 3 - Get Disk Utilization Q - Quit Select a choice: "@ $coll = @() #$coll = New-Object System.Collections.ObjectModel.Collection $a = [System.Management.Automation.Host.ChoiceDescription]::new("&1 Services") $a.HelpMessage = "Get Running Services" $a | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-service | where {$_.status -eq "running"}} -force # $a.invoke() $coll+=$a $b = [System.Management.Automation.Host.ChoiceDescription]::new("&2 Processes") $b.HelpMessage = "Get top processes" $b | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-Process | sort WS -Descending | select -first 10} -force $coll+=$b $c = [System.Management.Automation.Host.ChoiceDescription]::new("&3 Disks") $c.HelpMessage = "Get disk information" $c | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Get-Ciminstance win32_logicaldisk -filter "drivetype=3"} -force $coll+=$c $q = [System.Management.Automation.Host.ChoiceDescription]::new("&Quit") $q | Add-Member -MemberType ScriptMethod -Name Invoke -Value {Write-Host "Have a nice day." -ForegroundColor Green ; Return} -force $q.HelpMessage = "Quit and exit" $coll+=$q #loop until last option is selected do { $r = $host.ui.PromptForChoice($Title,$Caption,$coll,0) $coll[$r].invoke() | Out-Host if ($r -lt $coll.count-1) { Read-Host "Press any key to continue" cls } } Until ($r -eq $coll.count-1)
A sample menu script (Image Credit: Jeff Hicks)
More in PowerShell
Microsoft’s New PowerShell Crescendo Tool Facilitates Native Command-Line Wraps
Mar 21, 2022 | Rabia Noureen
Most popular on petri