If you’re building a script that’s capable of doing various tasks simultaneously, a great way of providing input for that script is to use an interactive menu in the console.

Adam Bertram

Adam Bertram is a 20-year IT veteran, Microsoft MVP, blogger, and trainer. Adam is the founder of the e-learning tech screencast platform TechSnips. Catch up on Adam’s articles at adamtheautomator.com, or follow TechSnips on Twitter at @techsnips_io.

In order to write code that’s reusable, it's important not to hardcode values that may change at some future point. The best practice is to separate the input values from the processing and the output. In PowerShell, there are many ways to make this happen including using command-line parameters, building fancy GUIs, using input boxes, and so on. Your exact situation will dictate which method you choose.

Constructing an interactive menu that allows the user to select between different options is a great way to build scripts for less PowerShell-savvy people, or it can simply be used as a kind of input gateway to a lot of the functionality that you’ve already built in PowerShell.

Let’s go over how to build a rudimentary interactive menu in the PowerShell console.

This menu consists of two main components: a function that displays the menu, and a switch statement that takes the input and directs the code which way to go, depending on the selection. First, we’ll build the menu function. I’ll call this Show-Menu.

This is a simple function that first clears the console and then writes a few lines to it. When ran with the title parameter set to 'My Menu', it will look like this:

Show-Menu -Title 'My Menu' output

Show-Menu -Title 'My Menu' output

This is great, but as you can see, it dropped me back to the console again. I had no way to actually provide input to the menu. We need a way to make it pause after the menu is displayed to allow me to send it a keystroke. To do this, I can put a Read-Host immediately afterward to ask me for input.

Menu prompts for input

Menu prompts for input

I can now provide some kind of input, but it's still not functional. I have no way to do anything with the input once PowerShell receives it. I need a way to achieve something, depending on the input. A great construct to use here is the switch statement.

I now have the opportunity to do something with the input I receive from Read-Host.

Menu accepts input

Menu accepts input

Awesome! This works great. but maybe I want to do something and then keep the menu up until I say otherwise (by hitting the 'Q' key). I need the menu to come up again and again after I select an option. To do this, I can use a do/until loop. This lets me do something based on the menu selection, and then immediately render the menu again until 'Q' has been selected.

At this point, when this script is run, it will display the menu and prompt for a selection. Once the selection is made, the switch statement will decide what to do. It will then pause, as a demonstration, to show the output of the selection. Then, if only 'Q' is chosen, it will break out of the loop and return control to the console.

Join the 4sysops PowerShell group!

1+
Share
15 Comments
  1. […] This menu consists of two main components: a function that displays the menu, and a switch statement that takes the input and directs the code which way to go, depending on the selection. First, we’ll build the menu function. I’ll call this Show-Menu.. Read the full article on 4SysOps. […]

    0

  2. danny 3 years ago

    What a great und useful article!

    Thank you Adam!

    0

  3. readerweb 3 years ago

    User experience starts with a menu.  I will stop showing codes and will put focus on showing menus for each task.  Thank you for he useful post.

    0

  4. Daniel Potter 3 years ago

    5+

  5. Ayo Dada 2 years ago

    Hi Adam,

    I managed to create an interactive menu, how would I get it to run some get script i have already develop example

    So I have some individual script that can get a AAD user etc and i want to use an interactive menu to give the user the option

    example below

    Write-Host "================ $Title ================"

    Write-Host "1: Press '1' Get AAD Users."
    Write-Host "2: Press '2' Get AAD Devices."
    Write-Host "3: Press '3' Get AAD Devices"
    Write-Host "Q: Press 'Q' to quit."
    }
    do
    {
    Show-Menu
    $input = Read-Host "Please select a task by number Or Q to Quit"
    switch ($input)
    {
    '1' {
    cls
    'You chose option #1'
    } '2' {
    cls
    'You chose option #2'
    } '3' {
    cls
    'You chose option #3'
    } 'q' {
    return
    }
    }
    pause
    }
    until ($input -eq 'q')

    im getting the menu option but i need to now pass the function to a menu parameter the script at the end of each action to execute my script or do i add a loop.

    any direction would be helpful

     

    2+

  6. Lev 2 years ago

    i don't know what is the problem, but i stuck here:

    0

    • Swapnil Kambli 5 months ago

      Complete script for your reference 

       

      0

      • Michael 5 months ago

        The script looks good and I'd like to use it but when I modify it I never see the results onscreen.

        What do I need to change to see the results?

         

        Thank you.

        1+

        Users who have LIKED this comment:

        • avatar
        • Swapnil Kambli 5 months ago

          Hi Michael,
          The script above provides a basic framework for menu and IO system. 
          You could fill in the blocks, extend it or further improve it.
          If you could provide me with details of modifications I would be glad to help you identify the break in the flow.

          0

  7. Nino Crudele 1 year ago

    Great article, exactly was I was looking for, simple and very clear.

    0

  8. Daniel 10 months ago

    Is there a way to add some fun by adding an "else" for if the user selects something not on the list (say they randomly type "whatever..." and press enter, where it'll recognize that it's not an option and return something to them such as "That wasn't an option... what were you thinking?"

    1+

  9. TrixM 5 months ago

    A bit old, but you can add "Default" as a keyword to the end of the switch statement (no quotes), with a default action that gets executed if none of the switch options match the input.

    4+

    Users who have LIKED this comment:

    • avatar
  10. Daniel 2 months ago

    This is Awesome!

    Thanks
    Dan

    0

  11. JOhn 4 weeks ago

    I have a problem with my script, which matches closely to what is above. The first time I run it, I get the menu, make a "1" selection (get-mailbox), it pauses, but I get no results. If I press 1 again, THEN I get results. What I want it to do is give me results and pause at the end of those results so I can review them. I seemed to have narrowed this down to the "sort" option in my menu item. If I remove the sort, this all works. Any ideas?

     

    function Show-Menu

    {
        param ([string]$Title = 'My Menu')
        Clear-Host

    Write-Host "================ Mailbox Report Options ================"
     
    Write-Host "1: Press '1' for HC Mailboxes."
    Write-Host "2: Press '2' for MC Mailboxes."
    Write-Host "3: Press '3' for HP Mailboxes."
    Write-Host "Q: Press 'Q' to quit."
    Write-host "`n"
    }

    DO
    {
    Show-Menu –Title 'My Menu'

    $input = Read-Host "Please make a selection"

    switch ($input)
         {
            '1' {get-mailbox -OrganizationalUnit "ou=HC,OU=Domain Users,DC=contoso,DC=com" | get-mailboxstatistics | select displayname, totalitemsize | sort totalitemsize}
        
        '2' {get-mailbox -OrganizationalUnit "ou=MC,OU=Domain Users,DC=contoso,DC=com" | get-mailboxstatistics | select displayname, totalitemsize | sort totalitemsize}
            
        '3' {get-mailbox -OrganizationalUnit "ou=HP,OU=Domain Users,DC=contoso,DC=com" | get-mailboxstatistics | select displayname, totalitemsize | sort totalitemsize}

        'q' {EXIT}
         }
    pause
    }
    until ($input -eq 'q')

    1+

  12. Todd 2 weeks ago

    John try using Format-Table in the place of Select

    0

Leave a reply

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

*

© 4sysops 2006 - 2019

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