PowerShell Terminal: Menu Template

I created this for part of a bigger project and figured it’d make a good generic template for any PowerShell script needing a basic menu using the up and down arrow keys and enter key to make a selection.  For example data it lists the items in the root of the C: drive, but can easily be supplied any array of strings to list out in the menu. The chosen item is stored as a string in the $selection variable to be used later in the script.

<# Title: PowerShell Menu Template | Author: Michael Casey | Date: July 3rd, 2019 | Website: https://michael-casey.com/ #>

#Sample list data to populate menu:
#Set $List to any array to populate the menu with custom options
$List = Get-ChildItem -Path C:\ -Name

#menu offset to allow space to write a message above the menu
$xmin = 3
$ymin = 3

#Write Menu
Clear-Host
Write-Host ""
Write-Host "  Use the up / down arrow to navigate and Enter to make a selection"
[Console]::SetCursorPosition(0, $ymin)
foreach ($name in $List) {
    for ($i = 0; $i -lt $xmin; $i++) {
        Write-Host " " -NoNewline
    }
    Write-Host "   " + $name
}

#Highlights the selected line
function Write-Highlighted {

    [Console]::SetCursorPosition(1 + $xmin, $cursorY + $ymin)
    Write-Host ">" -BackgroundColor Yellow -ForegroundColor Black -NoNewline
    Write-Host " " + $List[$cursorY] -BackgroundColor Yellow -ForegroundColor Black
    [Console]::SetCursorPosition(0, $cursorY + $ymin)     
}

#Undoes highlight
function Write-Normal {
    [Console]::SetCursorPosition(1 + $xmin, $cursorY + $ymin)
    Write-Host "  " + $List[$cursorY]  
}

#highlight first item by default
$cursorY = 0
Write-Highlighted

$selection = ""
$menu_active = $true
while ($menu_active) {
    if ([console]::KeyAvailable) {
        $x = $Host.UI.RawUI.ReadKey()
        [Console]::SetCursorPosition(1, $cursorY)
        Write-Normal
        switch ($x.VirtualKeyCode) { 
            38 {
                #down key
                if ($cursorY -gt 0) {
                    $cursorY = $cursorY - 1
                }
            }

            40 {
                #up key
                if ($cursorY -lt $List.Length - 1) {
                    $cursorY = $cursorY + 1
                }
            }
            13 {
                #enter key
                $selection = $List[$cursorY]
                $menu_active = $false
            }
        }
        Write-Highlighted
    }
    Start-Sleep -Milliseconds 5 #Prevents CPU usage from spiking while looping
}

Clear-Host
Write-Host $selection
#May use switch statement here to process menu selection

Screenshot of the PowerShell menu template script running

Leave a Reply

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