Make a choice
Remember the old MS-DOS choice command? It prompts the user to make a choice in a batch program by displaying a prompt and pausing for the user to choose from a set of user-option keys.
In PowerShell, you can provide the same mechanism with .NET built-in classes without the need for external files. You can see this method in action on every cmdlet declared with -confirm parameter.
PS > Get-Process s* | Stop-Process -confirm
Confirm
Are you sure you want to perform this action?
Performing operation "Stop-Process" on Target "services (520)".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
The user is presented with "plain old message box kind" prompt, built from a caption, message and number of choices to choose from:
Confirm = Caption
Are you sure you want to... = Message
And the choices:
[Y] Yes
[A] Yes to All
[N] No
[L] No to All
[S] Suspend
In my scripts I used to build this mechanism manually and write to the host the caption/message and choices until I 'found' this while digging on Mighty MoW's PowerTab scripts. The method is also described on MSDN PSHostUserInterface.PromptForChoice.
PS > $host.ui | gm
TypeName: System.Management.Automation.Internal.Host.InternalHostUserInterface
Name MemberType
---- ----------
...
Prompt Method
PromptForChoice Method
PromptForCredential Method
...
The definition for PromptForChoice is:
System.Int32 PromptForChoice(String caption, String message, Collection`1 choices, Int32 defaultChoice)
So, how can you implement it in your scripts? Here is my variation:
$caption = "Confirm";
$message = "Are you sure?";
$yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes","help";
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no);
$answer = $host.ui.PromptForChoice($caption,$message,$choices,0)
switch ($answer){
0 {"You entered 0"; break}
1 {"You entered 1"; break}
}
write-host "Rest of script goes here..."
Here is the output:
PS C:\Scripts> .\PromptForChoice.ps1
Confirm
Are you sure?
[Y] Yes [N] No [?] Help (default is "Y"): n
You entered 1
Rest of script goes here...
PS >
Note that the special character "&" (ampersand) might be embedded in the label string to indicate that the next character is a "hot key" (for example, "Yes to &All"). The hot key allows the user to quickly set the input focus to this choice.
The default choice is determined by the order/index of the collection variables ($choices). To indicate no default, set defaultChoice to -1:
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no);
$yes = 0
$no = 1
$yes = 0
$no = 1
$retry = 2
There is also the "Help" option, which we didn't explicitly define.
The strings "help" in the $yes and $no variables are the help text to display when the user types "?"
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
I also wanted to implement the Suspend feature. Suspending the process is totally awesome. You have another chance to pause operation and get up to date, verified information, before proceeding. I knew that there is something called "Nested Prompt" and something inside felt that this is the place where it might be used. So I made some tests and here's the code with Suspend.
$caption = "Confirm";
$message = "Are you sure?";
$yes = new-Object System.Management.Automation.Host.ChoiceDescription "&Yes","help";
$no = new-Object System.Management.Automation.Host.ChoiceDescription "&No","help";
$Suspend = new-Object System.Management.Automation.Host.ChoiceDescription "&Suspend","help";
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no,$suspend);
$Answer = $host.ui.PromptForChoice($caption,$message,$Choices,0)
switch ($Answer){
1 {"You entered 1"; break}
2 {"You entered 2, entering nested prompt, type exit to return"; $Host.EnterNestedPrompt()}
}
write-host "Rest of script goes here..."
Here is the output:
PS C:\Scripts> .\PromptForChoice.ps1
Confirm
Are you sure?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): s
You entered 2, entering nested prompt, type exit to return
PS >>> exit
Rest of script goes here...
PS >
Note that the PowerShell prompt is visually changing, colored in yellow ( adding >> to the default prompt) indicating that you're inside a nested prompt. To exit nested prompts simply type exit.
2 comments:
Entering "-1" as the default choice doesn't work.
Hello!
Well, but, if i want to change the colors for "Caption", "Message" and for "Answers"?
How can I make this?
Thanks.
Post a Comment