The Read-Host cmdlet allows prompting for user input in PowerShell. With the help of the .NET ChoiceDescription class, you can create a more professional-looking menu system to let your script interact with the user.

A good PowerShell automation script typically requires no interactivity. After all, if a script is interactive, that means a human must be in front of it to press a key. We try to stay away from that by defining all the scenarios ahead of time and feeding parameters into our scripts at runtime with no interaction. However, there are times when we need to gather input where we can't define scenarios ahead of time or we're building scripts for end users.

PowerShell has a few ways to introduce interactivity into our scripts. Today, we're going to discuss two of them: using the Read-Host command and creating our custom selection menu using the .NET System.Management.Automation.Host.ChoiceDescription object.

Prompting for user input with Read-Host ^

The easiest and most common way to add interactivity to your scripts is by using the built-in Read-Host command. This command pauses the script wherever it occurs and expects some input. By default, it will simply stop code execution with no indication of what's going on besides a flashing prompt. So it's important to use the Prompt parameter, which displays some text before it prompts for input.

Prompting for input with Read Host

Prompting for input with Read Host

You can see from the screenshot above that when input occurs, the command then returns that input. I typed Red as input, and it returned Red. This doesn't do much good if we're not capturing that input somehow and making a decision from it. It's best we send that output to a variable. At that point, we can then perform a series of checks against the input provided.

Now you can see it didn't simply return Red to the console but captured it with the $favColor variable. At this point, we can add some logic in there to do different things based on that input.

Create a menu with the .NET ChoiceDescription class ^

Read-Host is versatile and can prompt for any text, but it doesn't look "official." It doesn't look like it is a part of PowerShell itself. For a more professional way of asking for input (multiple inputs), we can use the .NET ChoiceDescription object. This object allows us to define different options and then use a .NET method called PromptForChoice to display those options to the user.

This method of asking for input requires defining all the options ahead of time by creating multiple ChoiceDescription .NET objects. We then pass those objects to another .NET object that displays them in the console and asks the user to choose.

The .NET method that shows the options is called $host.ui.PromptForChoice(). This method requires four arguments to run: the title for the menu of options, the message to display, an array of System.Management.Automation.Host.ChoiceDescription objects, and a default choice if the user simply hits Enter.

First, we'll define all the options. Using the previous example, let's limit the number of favorite colors to Red, Blue, and Yellow. To do that, we'll have to create three objects each representing a choice.

Finally, we'll display them to the user, first defining the prompt title and message.

When run from the console, it'll then display a prompt that looks like it came from PowerShell itself.

And if you run the above code in PowerShell ISE, a graphical dialog box will appear:

Displaying an options menu with the ChoiceDescription class

Displaying an options menu with the ChoiceDescription class

The value of $result isn't the text specified; it's an index number starting at 0. So, for example, if you chose Red, the result would be 0, or if you chose Yellow, the value would be 2. You could make this distinction by using a switch statement to make a decision based on the input you provided.

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!

6+

Users who have LIKED this post:

  • avatar
  • avatar
  • avatar
Share
7 Comments
  1. Fantastic, Complicated scenario explained in a simple way. Thanks Adam for your post

    1+

  2. Mike Ciokiewicz 2 years ago

    This is very helpful!  Is there any way to order the choices in a list vs a table?

    0

  3. Jim Younger 2 years ago

    Very helpful!  I have also found Out-GridView with text files to be extremely helpful for a quick and easy menu based system including nested groups (plus it allows changes to the menu/text file without having to open your script).  It's also flexible in that you can limit the response to a single selection or multiple, depending on your needs.

    For example, to force a single selection you could use:

    To allow multiple selections using the standard CTRL-click/SHIFT-click options you could use:

    Or use both of these in combination (first the user selects the group which determines which file to display its contents).  It's not perfect but very flexible.  You'll need to include error handling (e.g. verify the files exist; was anything selected at all) but otherwise it works in a pinch.

    0

  4. Billy-O 12 months ago

    I didn't get any pop-up box (using PS 5.0 on Windows 10).

    0

  5. A simpler and less redundant way to provide switch UI, this works in the CLI as a choice, or in ISE as a message box. There are other ways to pull this, you can use one of the other methods PSCmdlet SupportsShouldProcess I think does this same thing, but I'm not super certain.
    ```
    switch ( $host.UI.PromptForChoice( 
        'Stuff-Happening' , 
        'Do you want to make stuff happen?' , 
        [ System.Management.Automation.Host.ChoiceDescription [] ]@( 
            '&Heck yeah!' , 
            '&Not really'
            '&Only if it works) , 
        [int] 0 ) )
        {
               0 { echo "You chose Heck yeah!" }
               1 { echo "You chose Not really, you might like doing things the long way. And, that's ok." }
               2 { echo "If it works, then I guess I may use this method instead. Arrays are pretty cool." }
         }
    ```

    Tried to post this on Stack Overflow and it got about -8 points in about 45 minutes, not sure why. It's less redundant and does the same thing without tying up any variables.

    4+

    • matviyko 2 weeks ago

      With the myriad of enteprise extensible applications, integrations/services, etc. assigned to an Engineer/Administrator spectrum of responsibility(ies)...Automation using PowerShell scripts/modules can lighten the workload, sometimes removing a tedious "hat" from being worn; provided the/a script/module has been supplied with succinct and exacting documentation, written to allow the "proverbial" least-experienced script-user/co-worker a means to suss out before execution.

      Perhaps that explains the diminutive feedback via stackOverflow?

      0

    • matviyko 2 weeks ago

      With the myriad of enterprise extensible applications, integrations/services, etc. assigned to an Engineer/Administrator spectrum of responsibility(ies)...Automation using PowerShell scripts/modules can lighten the workload, sometimes removing a tedious "hat" from being worn; provided the/a script/module has been supplied with succinct and exacting documentation, written to allow the "proverbial" least-experienced script-user/co-worker a means to suss out before execution.

      Perhaps that explains the diminutive feedback via stackOverflow?

      0

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2020

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account