You know when you want the user to make a choice, and you want him to type it out and get it right?
class Choice {
[string] $Key;
[string] $Option;
Choice($Key, $Option) {
$this.Key = $Key
$this.Option = $Option
}
}
<#
.Synopsis
Read userinput and validate against choices
.Description
Read userinput and validate against choices. Must match one of the keys. Not case sensitive.
.Parameter Prompt
Text to show when waiting for input
.Parameter Choices
List of Choice elements
.Parameter NoHints
Don't show list of hints for Choices
.Example
$MyChoices = @(
[Choice]::new('yes', 'Let me continue'),
[Choice]::new('no', 'I want to stop')
)
$key = Get-Choice -Prompt "Do you want to continue?" -Choices $MyChoices
#>
function Get-Choice {
# [OutputType([string])]
param (
[string]$Prompt,
[Choice[]]$Choices,
[switch]$NoHints
)
$Hints = ""
$Comma = ""
$Opts = ""
$Sep = ""
$Choices | ForEach-Object {
$Hints = $Hints + $Comma + '[' + $_.Key + '] ' + $_.Option
$Comma = ', '
$Opts = $Opts + $Sep + $_.Key
$Sep = '|'
}
if (-not $NoHints) {
Write-Host $Hints
}
$pattern = $Opts.ToLower()
$pattern = "¤¤$pattern¤¤" -replace "\|", "¤¤|¤¤"
$ok = $false
while (-not $ok) {
[string]$userinput = (Read-Host -Prompt "$Prompt ($Opts)").ToLower()
$userinput = ("¤¤$userinput¤¤" | Select-String -Pattern $pattern) -replace "¤¤" , ""
$ok = ("$userinput" -ne "")
}
return $userinput
} # Get-Choice