---
title: "Build Interactive PowerShell Menus"
description: "Create simple and engaging PowerShell menus to enhance your scripts and improve user experience."
canonical: "https://adamtheautomator.com/powershell-menu/"
---

# Build Interactive PowerShell Menus

> Create simple and engaging PowerShell menus to enhance your scripts and improve user experience.

Source: https://adamtheautomator.com/powershell-menu/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Build Interactive PowerShell Menus](https://adamtheautomator.com/wp-content/uploads/2019/07/photo-1551489186-c892fa1428c9.jpg)

# Build Interactive PowerShell Menus

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)20 July 20195 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[PowerShell](/tag/powershell/)

Table of Contents

*   [Read-Host](#read-host)
*   [Using .NET to Create a Powershell Menu](#using-net-to-create-a-menu)
*   [Defining Powershell Menu Options](#defining-menu-options)
*   [Putting it All Together](#putting-it-all-together)

Although PowerShell is a powerful automation scripting language, you can also build some cool console-based scripts with it. Building an interactive menu is a great example. In this post, we’re going to dive into a step-by-step tutorial on you can get interactive with PowerShell and how to create a simple PowerShell menu.

Not a reader? Watch this related video tutorial!

**_Not seeing the video? Make sure your ad blocker is disabled._**

A good [PowerShell](https://adamtheautomator.com/tag/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 of 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 scenarios can’t be defined ahead of time or we’re building scripts for end users.

PowerShell has a few ways we can introduce interactivity into our scripts. Today, we’re going to discuss two of them; using the [`Read-Host`](https://adamtheautomator.com/read-host/ "Read-Host") command and creating our own custom selection menu using the .NET _System.Management.Automation.Host.ChoiceDescription_ object.

## Read-Host

The most common and easiest way to add interactivity into your scripts is by using the built-in `Read-Host` command. This command pauses the script wherever it’s located and expects some kind of 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.

```powershell
PS C:\> Read-Host
Red
Red
```

When input is given, it then returns that input. Above, I typed `Red` as input and `Red` was returned. This doesn’t do much good if we’re not capturing that input somehow and making a decision off of 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.

```powershell
PS> $favColor = Read-Host -Prompt 'What is your favorite color?'
What is your favorite color?: Red
PS> $favColor
Red
```

Now you can see that `Red` wasn’t simply returned to the console but was captured by the `$favColor` variable. At this point, we can add some logic in there to do different things based on that input.

```powershell
if ($favColor -eq 'Red') {
    'My favorite, too!'
} else {
    "Eww..$favColor is not a nice color!"
}
My favorite, too!
```

## Using .NET to Create a Powershell Menu

`Read-Host` is versatile and can prompt for any kind of text but it doesn’t really look “official”. It doesn’t look like it is a part of PowerShell itself. For a more professional way of asking for input (multiple input), we can use the .NET _System.Management.Automation.Host.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 of the options ahead of time by creating multiple _System.Management.Automation.Host.ChoiceDescription_ .NET objects and then passing those objects to another .NET object which displays them onto the console asking the user to choose.

The .NET method that shows the options is call `$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 the choice to default to if the user simply hits Enter.

### Defining Powershell Menu Options

First, we’ll define all of 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.

```powershell
$red = New-Object System.Management.Automation.Host.ChoiceDescription '&Red', 'Favorite color: Red'
$blue = New-Object System.Management.Automation.Host.ChoiceDescription '&Blue', 'Favorite color: Blue'
$yellow = New-Object System.Management.Automation.Host.ChoiceDescription '&Yellow', 'Favorite color: Yellow'
```

Once we have all of the options defined, we’ll group them all together into an array.

```powershell
$options = [System.Management.Automation.Host.ChoiceDescription[]]($red, $blue, $yellow)
```

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

```powershell
$title = 'Favorite color'
$message = 'What is your favorite color?'
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
```

When ran, you’ll then see a prompt that looks like it came from PowerShell itself.

```powershell
Favorite color
What is your favorite color?
[R] Red  [B] Blue  [Y] Yellow  [?] Help (default is "R"):
```

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 Yellow is chosen, 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.

```powershell
switch ($result)
{
    0 { 'Your favorite color is Red' }
    1 { 'Your favorite color is Blue' }
    2 { 'Your favorite color is Yellow' }
}
```

Once your code is in a switch statement, you could then create a handy [PowerShell function](https://adamtheautomator.com/powershell-functions/ "PowerShell function") like below to bring up a menu and prompt for responses. Notice the shortcut to create the `[ChoiceDescription]` objects using the `using` keyword. Thanks to [ttwinlakkes on Reddit](https://www.reddit.com/user/ttwinlakkes/) for the tip.

```powershell
using namespace System.Management.Automation.Host

function New-Menu {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Title,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Question
    )
    
    $red = [ChoiceDescription]::new('&Red', 'Favorite color: Red')
    $blue = [ChoiceDescription]::new('&Blue', 'Favorite color: Blue')
    $yellow = [ChoiceDescription]::new('&Yellow', 'Favorite color: Yellow')

    $options = [ChoiceDescription[]]($red, $blue, $yellow)

    $result = $host.ui.PromptForChoice($Title, $Question, $options, 0)

    switch ($result) {
        0 { 'Your favorite color is Red' }
        1 { 'Your favorite color is Blue' }
        2 { 'Your favorite color is Yellow' }
    }

}
```

Once you have the function built, you can then build menus on the fly by calling the `New-Menu` function as shown below. If I were you, I’d also make the options a parameter too but I’ll leave that one up you.

```powershell
PS> New-Menu -Title 'Colors' -Question 'What is your favorite color?'

Colors
What is your favorite color?
[R] Red  [B] Blue  [Y] Yellow  [?] Help (default is "R"): B
Your favorite color is Blue
```

## Putting it All Together

Now that you’ve got all of the knowledge to create a menu, let’s put that all together and create an interactive menu that stays interactive!

Create a function called `Show-Menu` as shown below. This menu is static.

```powershell
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."
}
```

The `Show-Menu` function just displays the menu. Nothing more.

```powershell
================ My Menu ================
1: Press '1' for this option.
2: Press '2' for this option.
3: Press '3' for this option.
Q: Press 'Q' to quit.
```

However, you can make this an actual interactive menu by implementing a `do/until` loop. Using a `do/until` loop allows you to take an action on input _and_ keeps the menu up if users would like to select more than one option.

The only way to get out of the menu is to type Q. Try it out!

```powershell
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')
```

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-menu%2F&text=Build%20Interactive%20PowerShell%20Menus)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-menu%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-menu%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2026/06/26995-troubleshoot-dns-issues-powershell-codex.webp)

### [Troubleshoot DNS Issues with PowerShell](/troubleshoot-dns-issues-powershell/)

Troubleshoot DNS issues with PowerShell by testing name resolution, DNS client settings, cache entries, and network connectivity in a repeatable workflow.

![](https://adamtheautomator.com/wp-content/uploads/2025/10/image_2025-10-24_095322075.png)

### [Migrating from PowerShell 6 to 7.5: Breaking Changes/New Features](/migrating-powershell-6-to-7-5/)

Migrate from PowerShell Core 6 to 7.5: breaking changes, features, and testing tips.

![](https://adamtheautomator.com/wp-content/uploads/2025/06/featured-image-6.png)

### [How to Add Timeouts to Pester Tests with PowerShell Runspaces](/pester-test-timeout-runspaces/)

Prevent Pester tests from hanging indefinitely using PowerShell runspaces. Learn to handle variable scoping, module loading, TestDrive access, and stream capture challenges with timeout protection.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
