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 MenuClear-HostWrite-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 linefunction 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 highlightfunction Write-Normal { [Console]::SetCursorPosition(1 + $xmin, $cursorY + $ymin) Write-Host " " + $List[$cursorY]}
#highlight first item by default$cursorY = 0Write-Highlighted
$selection = ""$menu_active = $truewhile ($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-HostWrite-Host $selection#May use switch statement here to process menu selection