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.

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.

function Show-Menu
{
    param (
        [string]$Title = 'My Menu'
    )
    Clear-Host
    Write-Host "================ $Title ================"
    
    Write-Host "1: Press '1' for this option."
    Write-Host "2: Press '2' for this option."
    Write-Host "3: Press '3' for this option."
    Write-Host "Q: Press 'Q' to quit."
}

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'
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.

Show-Menu –Title 'My Menu'
$selection = Read-Host "Please make a selection"
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.

Show-Menu –Title 'My Menu'
 $selection = Read-Host "Please make a selection"
 switch ($selection)
 {
     '1' {
         'You chose option #1'
     } '2' {
         'You chose option #2'
     } '3' {
         'You chose option #3'
     } 'q' {
         return
     }
 }

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.

Subscribe to 4sysops newsletter!

do
 {
     Show-Menu
     $selection = Read-Host "Please make a selection"
     switch ($selection)
     {
         '1' {
             'You chose option #1'
         } '2' {
             'You chose option #2'
         } '3' {
             'You chose option #3'
         }
     }
     pause
 }
 until ($selection -eq 'q')

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.