| Today, I was investigating options for an advanced PowerShell switch statement scenario. Basically, I am asking a user to supply an answer to a simple question, something like this:
$optionSelected = Read-Host 'Do you want to mount the VHD image? (Yes/No/Y/N/1/0/True/False/T/F)'
I must convert the user's imput from $optionSelected string to a [bool] type variable. I want to provide user with as simple an option to type as possible, so I accept several different kinds of values to represent the actual $true result - such as the 'Yes', 'Y', '1', 'True' or event others in my native language as well. Similarly, if the user wants to deny the operation (which should result in $false), he/she can type one of the 'No', 'N', '0', 'False'. I also cannot rely on case sensitivity of the user's input.
There is a nice article about the switch statement featuring several nice options such as those -wildcard and -regex switches. Although I could achieve my task with the -regex switch well, I am not so strong in regex and wanted to keep it as simple as possible.
Finally, I came up with the following three possible forms. All ignore case of the input:
Using the -contains conditional statement as my favourite
$optionSelected = Read-Host 'Do you want to mount the VHD image? (Yes/No/Y/N/0/1/True/False/T/F, default = No)'
switch ($optionSelected) {
{ 'Yes', 'Y', '1', 'True', 'T' -contains $_ } { $boolOption = $true }
{ 'No', 'N', '0', 'False', 'F' -contains $_ } { $boolOption = $false }
default { $boolOption = $false }
}
echo 'You selected: ' $boolOption
Using the simplest comparison operators as maybe slightly more powerful attitude
As you see, this may be more flexible in case you need any other type of operator, such as -like, or even employ case sensitive comparisons such as -ceq or -clike
$optionSelected = Read-Host 'Do you want to restart the computer? (Yes/No/Y/N/0/1/True/False/T/F, default = No)'
switch ($optionSelected) {
{ ($_ -eq 'Yes') -or ($_ -eq 'Y') -or ($_ -eq '1') -or ($_ -eq 'True') -or ($_ -eq 'T') } { $boolOption = $true }
{ ($_ -eq 'No') -or ($_ -eq 'N') -or ($_ -eq '0') -or ($_ -eq 'False') -or ($_ -eq 'F') } { $boolOption = $false }
default { $boolOption = $false }
}
echo 'You selected: ' $boolOption
Using the -regex switch to make it as professional as possible
Although you could make it as simple even with regular expressions as in the following example, I would rather precise it a bit more.
$optionSelected = Read-Host 'Do you want to delete the VM? (Yes/No/Y/N/0/1/True/False/T/F, default = No)'
switch -regex ($optionSelected) {
'yes|y|1|true|t' { $boolOption = $true }
'no|n|0|false|f' { $boolOption = $false }
default { $boolOption = $false }
}
echo 'You selected: ' $boolOption
The problem with previous example lies in the fact, that you match as $true also answers which contain t or y characters regardless of the word the user actually typed, and you also match as $false those answers that contain letters n or f on any character position. It would be more precise to make the regular expressions more strict - I use the \A and \Z special regex characters to denote the start and the end of the strings:
$optionSelected = Read-Host 'Do you want to delete the VM? (Yes/No/Y/N/0/1/True/False/T/F, default = No)'
switch -regex ($optionSelected) {
'\Ayes\Z|\Ay\Z|\A1\Z|\Atrue\Z|\At\Z' { $boolOption = $true }
'\Ano\Z|\An\Z|\A0\Z|\Afalse\Z|\Af\Z' { $boolOption = $false }
default { $boolOption = $false }
}
echo 'You selected: ' $boolOption
|