PowerShell: Display A Menu And Get a Valid Choice

While it’s normally best practice to not display anything on the host and to batch as much as possible with PowerShell; sometimes you need a UI.  Here’s a pair of functions to display a menu on the screen, automatically number the possible responses and only return when a valid choice is made.

What I want is a function that will take a question and some options as parameters and display them to the screen.  The options should be automatically numbered which should be the only valid responses to the menu.

First, a fancy banner to display the question;

function Get-HeaderFormattedArray
{
    param
    (
        [string]$HeaderString=""
    )
    $TitleBar = ""
    #Builds a line for use in a banner
    for ($i = 0; $i -lt ($HeaderString.Length) + 2; $i++)
    {
        $TitleBar += $TitleChar
    }
    Return @($TitleBar, "$TitleChar$HeaderString$TitleChar", $TitleBar, "")
}

This returns an array of 3 lines of text;  the passed string ($HeaderString) with a line before and after it.  You’ll need to define $TitleChar as whatever you want the lines to be made out of.

And now the actual menu function;

<# .SYNOPSIS Writes a menu to the screen and gets a valid selection. .DESCRIPTION Writes a menu to the screen and gets a valid selection. It generates the number next to the menu item automatically and checks the input is one of the numbers used. .PARAMETER Banner The title of the menu .PARAMETER DisplayOptions An array of options to display .PARAMETER ClearScreen If this switch is specified the host is cleared whenever the menu is redisplayed .NOTES Name : Get-MenuAnswer Author : Neil Riches V1.62 Initial Version #>
function Get-MenuAnswer
{
    param
    (
        [string]$Banner="",
        [string[]]$DisplayOptions=@(),
        [switch]$ClearScreen=$False
    )
    If ($DisplayOptions.Count -gt 0)
    {
        $ValidSelection=$False
        do
        {
            if($ClearScreen)
            {
                Clear-Host
            }
            $FormattedBanner=Get-HeaderFormattedArray -HeaderString $Banner
            Write-Host
            $FormattedBanner | Write-Host
            Write-Host
            $OptionCount=0
            ForEach($Option in $DisplayOptions)
            {
                $OptionCount+=1
                Write-Host "$OptionCount) $Option"
            }
            Write-Host
            $Answer=Read-Host -Prompt "Enter an option "
            $IntAnswer=$Answer -as [int32]
            if ($IntAnswer -ne $Null)
            {
                if (($IntAnswer -gt 0) -and ($IntAnswer -le $OptionCount))
                {
                    $ValidSelection=$True
                }
            }
        }Until ($ValidSelection)
        return $Answer
    }

}

The function takes the $Banner string you want to display, an array of $DisplayOptions and whether you want the screen to be cleared.

In action, it looks like;

The function will keep looping until one of the numbered options is chosen and then return the result.

Some important parts of the function;

If ($DisplayOptions.Count -gt 0)

This makes sure there are some options to choose!

$FormattedBanner=Get-HeaderFormattedArray -HeaderString $Banner

This gets a banner from the previous function.

            ForEach($Option in $DisplayOptions)
            {
                $OptionCount+=1
                Write-Host "$OptionCount) $Option"
            }

Loops through the $DisplayOptions and writes a number next to each.

            $IntAnswer=$Answer -as [int32]
            if ($IntAnswer -ne $Null)
            {
                if (($IntAnswer -gt 0) -and ($IntAnswer -le $OptionCount))

This tries to convert the written choice (a String) into a number.  If it’s possible the code next checks that the number picked is between 1 and the number of $DisplayOptions.

Until ($ValidSelection)
        return $Answer

Finally this keeps generating the menu until a valid selection has been picked!

2 Replies to “PowerShell: Display A Menu And Get a Valid Choice”

    1. Hi. No. $TitleChar is a global variable you’ll have defined somewhere else. It’s used to create the bar in the menu (using “*” you’d get a banner line of “******************************”).

      You could define it in the function as well though if you wanted;

      $TitleBar = “”
      $TitleChar = “-”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: