Public/Read-NSPChoice.ps1
|
function Read-NSPChoice { <# .SYNOPSIS Displays numbered choices and returns the selected item's stable value. .DESCRIPTION Accepts objects with Label and Value properties. Values can be strings or objects. Invalid interactive input retries by default; ReturnNull preserves tools whose caller returns to an outer menu on invalid input. Cancel returns $null. -Selection supplies a number for noninteractive callers. The caller owns the action taken after selection. #> [CmdletBinding()] param( [Parameter(Mandatory)][object[]]$Choices, [string]$Prompt = 'Select an option', [string]$CancelKey = 'Q', [ValidateSet('Retry', 'ReturnNull')][string]$InvalidSelectionAction = 'Retry', [int]$Selection ) if ($Choices.Count -eq 0) { throw 'At least one choice is required.' } foreach ($choice in $Choices) { if ($null -eq $choice -or $null -eq $choice.PSObject.Properties['Label'] -or $null -eq $choice.PSObject.Properties['Value']) { throw 'Each choice requires Label and Value properties.' } } if ($PSBoundParameters.ContainsKey('Selection')) { if ($Selection -lt 1 -or $Selection -gt $Choices.Count) { throw "Selection must be between 1 and $($Choices.Count)." } return $Choices[$Selection - 1].Value } for ($index = 0; $index -lt $Choices.Count; $index++) { Write-Host (' {0}. {1}' -f ($index + 1), $Choices[$index].Label) } Write-NSPConsoleLine -Message " $CancelKey. Cancel" -Role Muted while ($true) { $answer = Read-Host $Prompt if ($null -eq $answer) { return $null } $answer = $answer.Trim() if ($answer -ieq $CancelKey) { return $null } $number = 0 if ([int]::TryParse($answer, [ref]$number) -and $number -ge 1 -and $number -le $Choices.Count) { return $Choices[$number - 1].Value } if ($InvalidSelectionAction -eq 'ReturnNull') { Write-NSPConsoleLine -Message 'Invalid selection.' -Role Warning return $null } Write-NSPConsoleLine -Message 'Invalid selection. Choose a listed number or cancel.' -Role Warning } } |