Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's English Pages

:

Engineering and troubleshooting by Directory Master!
MCM: Directory

Quick Launch

Ondrej Sevecek's English Pages > Posts > PowerShell SWITCH statement with multiple values for a single target choice
August 07
PowerShell SWITCH statement with multiple values for a single target choice

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

 

Comments

Too much noise and will catch substrings

You should use anchors and parentheses in your regex:
 
$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) {

  '\A(yes|y|1|true|t)\Z' { $boolOption = $true }
  '\A(no|n|0|false|f)\Z' { $boolOption = $false }
  default { $boolOption = $false }
}

echo 'You selected: ' $boolOption

Otherwise, "yomama" or "mamayo" will be considered 'y'.
 on 08/03/2016 17:45

Re: PowerShell SWITCH statement with multiple values for a single target choice

cool, thanks!
 on 08/03/2016 18:32

Add Comment

Title


You do not need to provide any value this column. It will automatically fill with the name of the article itself.

Author *


Body *


Type number two as digit *


This simple antispam field seems to work well. Just put here the number.

Attachments