Making PowerShell Menus…

So PowerShell doesn’t have a user interface as such, but you still need to get user input and in most cases make decisions based on that input to control the flow of script and the end result.

I found myself having to craft a mini admin utility this week and ideally it needed to prompt for choices and perform tasks based on what the user inputs.

The requirements were;

  • Give the user options
  • Collect the chosen option
  • Control the option entered
  • Act upon the option entered

Give the user options
This bit was the easy, display a list of choices…

Write-host "1. User tasks"
Write-host "2. Group tasks"
Write-host "3. Shared mailbox tasks"
Write-host "4. Quit and exit"

Collect the chosen option
Again this is easy enough, assign a variable the input from a read host command

Write-host "1. User tasks"
Write-host "2. Group tasks"
Write-host "3. Shared mailbox tasks"
Write-host "4. Quit and exit"
$xMenuChoiceA = read-host "Please enter an option 1 to 4..."

Read More & get the Demo script…

Control the answer
Do not continue until the user selects an accepted answer. Use a While loop to keep them going until they enter a number associated with a menu choice.

[int]$xMenuChoiceA = 0
while ( $xMenuChoiceA -lt 1 -or $xMenuChoiceA -gt 4 ){
  Write-host "1. User tasks"
  Write-host "2. Group tasks"
  Write-host "3. Shared mailbox tasks"
  Write-host "4. Quit and exit"
  [Int]$xMenuChoiceA = read-host "Please enter an option 1 to 4..." 
}

Act upon the answer provided
Now we have the users choice we can use switch to progress to the relevant function.

[int]$xMenuChoiceA = 0
while ( $xMenuChoiceA -lt 1 -or $xMenuChoiceA -gt 4 ){
Write-host "1. User tasks"
Write-host "2. Group tasks"
Write-host "3. Shared mailbox tasks"
Write-host "4. Quit and exit"
[Int]$xMenuChoiceA = read-host "Please enter an option 1 to 4..." }
Switch( $xMenuChoiceA ){
  1{<#run an action or call a function here #>}
  2{<#run an action or call a function here #>}
  3{<#run an action or call a function here #>}
default{<#run a default action or call a function here #>}
}

Now that we have our simple menu structure we can provide bundled up commands into a ready made structure for a User Administration team for example.

My final live copy contains two level menu system and calls itself to ensure the users always return to the main menu.

I know there are other ways in PowerShell to retrieve user input, but using write-host allows us to format the menu with tabs and colours as can be seen below.

Menu Level 1

Menu Level 2

Capture Incorrect Choices

I have saved the Code for the Multi Layered Menu Demonstration for use at your own risk.. Its simple, but it works and that’s how I code 😀

13 thoughts on “Making PowerShell Menus…

  1. Pingback: » Safely Enable SQL Server Agent MultiServer Administration using PowerShell

  2. Great! When I create a shortcut on my desktop to execute it, and I execute an option from the menu, the output is displayed but when finished the window is closed. Is there a way to leave the output window open and/or to display the menu again?
    Again,. great job!!

  3. Great menu, thanks for the snippet.

    Can you help with the validation of selecting a menu item for sub level?
    It works on the first menu, but not the sublevel menu items.

    An example of it working is when I execute the script and there are 4 options. If I press 5, a red message appears saying “Please select one of the options available”

    An example of it not working is when I execute the script and there are 4 option. If I press 1, it then gives me 4 choices. If I press 5, it doesn’t give me the message “Please select one of the options available”. IT simply returns to the menu.

    Hope you can help.

    Thanks,

    Mark.

    • Hey Mark, thanks for your feedback. It turns out I had the level 2 menu variable incorrect.. I have updated the demo version to resolve this. thanks for taking the time to comment.

  4. Awesome example, but I have a question: If option 1 of a menu just returned info say.. a cmdlet like get-adgroupmember
    How would you code it to return the cmdlet results then after x seconds or even a key press return to the original menu?

  5. I am a beginner with Powershell. I wanted to know how to add in the Powershell cmdlet’s as one of the choices.

    First Menu: Write-Host “`t`t`t1. Network Tools” -Fore Cyan
    Second Menu: Write-Host “`t`t`t1. NetStat” -Fore Cyan

    You list it this way after the Second Menu:
    Switch( $xMenuChoiceA ){
    1{}

    How do I add in the PS cmdlet that I want to run when I choose that option? I tried this but I have absolutely no idea of what I am doing.

    while ( $xMenu1 -lt 1 -or $xMenu1 -gt 6 ){
    CLS
    #… Present the Menu Options
    Write-Host “`n`tMulti Layered Menu Demonstration – Admin Processes – Version 1.1`n” -ForegroundColor Magenta
    Write-Host “`t`tPlease select the admin area you require`n” -Fore Cyan
    Write-Host “`t`t`t1. Network Tools” -Fore Cyan
    Write-Host “`t`t`t2. Svhost Lookup” -Fore Cyan
    Write-Host “`t`t`t3. System Information” -Fore Cyan
    Write-Host “`t`t`t4. What Services are Running” -Fore Cyan
    Write-Host “`t`t`t5. Computer Cleanup” -Fore Cyan
    Write-Host “`t`t`t6. Quit and exit`n” -Fore Cyan
    #… Retrieve the response from the user
    [int]$xMenu1 = Read-Host “`t`tEnter Menu Option Number”
    if( $xMenu1 -lt 1 -or $xMenu1 -gt 6 ){
    Write-Host “`tPlease select one of the options available.`n” -Fore Red;start-Sleep -Seconds 1
    }
    }
    Switch ($xMenu1){ #… User has selected a valid entry.. load next menu
    1 {
    while ( $xMenu2 -lt 1 -or $xMenu2 -gt 5 ){
    CLS
    # Present the Menu Options
    Write-Host “`n`tMulti Layered Menu Demonstration – Admin Processes – Version 1.1`n” -Fore Magenta
    Write-Host “`t`tPlease select the Network Administration task you require`n” -Fore Cyan
    Write-Host “`t`t`t1. NetStat” -Fore Cyan
    Write-Host “`t`t`t2. Network Information” -Fore Cyan
    Write-Host “`t`t`t3. IP Address Scan” -Fore Cyan
    Write-Host “`t`t`t4. What’s my IP Address” -Fore Cyan
    Write-Host “`t`t`t5. Go to Main Menu`n” -Fore Cyan
    [int]$xMenu2 = Read-Host “`t`tEnter Menu Option Number”
    if( $xMenu2 -lt 1 -or $xMenu2 -gt 5 ){
    Write-Host “`tPlease select one of the options available.`n” -Fore Red;start-Sleep -Seconds 1
    }
    }
    Switch ($xMenu2){
    ***This is where my issue begins. I do not know how to add in the PS cmdlet so that it runs when selected.*** 1{ Write-Host “`n`tYou Selected Option 1 – “Get-NetworkStatistics -computername exampleComputer | Format-Table -autosize” ‘n” -Fore Yellow;start-Sleep -Seconds 5 }
    2{ Write-Host “`n`tYou Selected Option 2 – Put your Function or Action Here`n” -Fore Yellow;start-Sleep -Seconds 3 }
    3{ Write-Host “`n`tYou Selected Option 3 – Put your Function or Action Here`n” -Fore Yellow;start-Sleep -Seconds 3 }
    4{ Write-Host “`n`tYou Selected Option 3 – Put your Function or Action Here`n” -Fore Yellow;start-Sleep -Seconds 4 }

    default { Write-Host “`n`tYou Selected Option 5 – Quit the Administration Tasks`n” -Fore Yellow; break}

    Thank you,
    Joseph

  6. Auto Formed Menu in PS

    $arr # array of selections
    $menu = @{}
    for ($i=1;$i -le $arr.count; $i++) {
    Write-Host “$i. $($arr[$i-1])”
    $menu.Add($i,($arr[$i-1]))}

    [int]$choice = Read-Host ‘Enter selection’
    $selection = $menu.Item($choice)
    write-host $selection #here is you selection

  7. Hi Paul,

    Thanks for sharing your code. I’m using this as a baseline to create a L1 tool to check remote hosts for disk utilisation, processes, and services check.

    My only problem at the moment is figuring out where to insert the code wherein the script will prompt the user to enter an initial hostname to check.

    After the user enters the hostname it’ll then enter the main menu, proceed to submenus to perform the checks. Another requirement is to be able to enter a new hostname to run new checks.

    $cred = Get-Credential
    $Title = “Quick Check Tool”
    [BOOLEAN]$global:xExitSession=$false

    function LoadMenuSystem {
    [INT]$xMenu1 = 0
    [INT]$xMenu2 = 0
    [BOOLEAN]$xValidSelection = $false

    while ( $xMenu1 -lt 1 -or $xMenu1 -gt 7 ) {
    cls
    Write-Host “================ $Title ================” -ForegroundColor Cyan

    Write-Host “1: Press ‘1’ for Disk Utilization.” -Fore Yellow
    Write-Host “2: Press ‘2’ for Processes.” -Fore Yellow
    Write-Host “3: Press ‘3’ for Services.” -Fore Yellow
    Write-Host “4: Press ‘4’ for Server Info.” -Fore Yellow
    Write-Host “5: Press ‘5’ for SQL Server Table Space.” -Fore Yellow
    Write-Host “6: Press ‘6’ for Another Host(s).” -Fore Yellow
    Write-Host “7: Press ‘7’ to Exit.” -Fore Yellow
    Write-Host “”

    [int]$xMenu1 = Read-Host “Enter Menu Option Number”
    if ( $xMenu1 -lt 1 -or $xMenu1 -gt 7 ){
    Write-Host “Please select one of the options available.`n” -Fore Red; start-Sleep -Seconds 1
    }
    }
    Switch ( $xMenu1 ){
    1 {
    while ( $xMenu2 -lt 1 -or $xMenu2 -gt 7 ){
    cls
    # Present the Menu Options
    Write-Host “Checking Disk Utilization:” -ForegroundColor Green
    Write-Host “1. Disk Utilization” -Fore Cyan
    Write-Host “2. Back to Main Menu`n” -Fore Cyan

    [int]$xMenu2 = Read-Host “Enter SubMenu Option”
    if ( $xMenu2 -lt 1 -or $xMenu2 -gt 2 ){
    Write-Host “Please select a valid option [1-2].`n” -Fore Red; start-Sleep -Seconds 1
    }
    }
    Switch ( $xMenu2 ){
    1 { Write-Host “`nYou Selected Option 1 – Put your Function or Action Here`n” -Fore Yellow; start-Sleep -Seconds 3; Diskutil }
    default { Write-Host “`nYou Selected Option 2 – Exit Disk Utilization Task`n” -Fore Yellow; break}
    }
    }
    2 {
    while ( $xMenu2 -lt 1 -or $xMenu2 -gt 7 ){
    CLS
    # Present the Menu Options
    Write-Host “Checking Processes:” -ForegroundColor Green
    Write-Host “1. Server Process” -Fore Cyan
    Write-Host “2. Back to Main Menu`n” -Fore Cyan
    [int]$xMenu2 = Read-Host “Enter Menu Option Number”
    }
    if ( $xMenu2 -lt 1 -or $xMenu2 -gt 2 ){
    Write-Host “Please select a valid option [1-2].`n” -Fore Red; start-Sleep -Seconds 1
    }
    Switch ( $xMenu2 ){
    1 { Write-Host “`nYou Selected Option 1 – Put your Function or Action Here`n” -Fore Yellow; start-Sleep -Seconds 3; proccheck }
    default { Write-Host “`nYou Selected Option 2 – Exit Disk Utilization Task`n” -Fore Yellow; break}
    }
    }
    3 {
    while ( $xMenu2 -lt 1 -or $xMenu2 -gt 7 ){
    CLS
    # Present the Menu Options
    Write-Host “Checking Services:” -ForegroundColor Green
    Write-Host “1. All Services” -Fore Cyan
    Write-Host “2. All Running Services” -Fore Cyan
    Write-Host “3. All Stopped Services” -Fore Cyan
    Write-Host “4. Back to Main Menu`n” -Fore Cyan
    [int]$xMenu2 = Read-Host “Enter Menu Option Number”
    if ( $xMenu2 -lt 1 -or $xMenu2 -gt 4 ){
    Write-Host “Please select a valid option [1-4].`n” -Fore Red; start-Sleep -Seconds 1
    }
    }
    Switch ( $xMenu2 ){
    1 { Write-Host “`nYou Selected Option 1 – Put your Function or Action Here`n” -Fore Yellow; start-Sleep -Seconds 3; svccheck }
    2 { Write-Host “`nYou Selected Option 2 – Put your Function or Action Here`n” -Fore Yellow; start-Sleep -Seconds 3 }
    3 { Write-Host “`nYou Selected Option 3 – Put your Function or Action Here`n” -Fore Yellow; start-Sleep -Seconds 3 }
    default { Write-Host “`nYou Selected Option 4 – Go to Main Menu`n” -Fore Yellow; break }
    }
    }
    default { $global:xExitSession=$true; break }
    }
    }

    Thank you again for your very helpful script. I have learned a lot from reading your code 🙂

    Regards,

    Ron

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 )

Google photo

You are commenting using your Google 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

This site uses Akismet to reduce spam. Learn how your comment data is processed.