The Windows PowerShell 1.0 switch Statement
Previous | Table of Contents | Next |
Windows PowerShell 1.0 Looping with do and while Statements | Windows PowerShell 1.0 Functions |
Purchase and download the full PDF version of this PowerShell eBook for only $8.99 |
In the Windows PowerShell 1.0 Flow Control with if, else and elseif chapter of this book we looked at how to control program execution flow using the if, else and elseif statements. Whilst these statement constructs work well for testing a limited number of conditions they quickly become unwieldy when dealing with larger numbers of possible conditions. To simplify such situations, Windows PowerShell (as with most other programming and scripting languages) has inherited the switch statement from the C programming language. In this chapter we will explore the switch statement in detail. Those familiar with the switch statement from other programming languages might also be pleasantly surprised by a number of new ideas that the Windows PowerShell developers have added to this popular construct.
Why Use a switch Statement?
For a small number of logical evaluations of a value the if ... else .. elseif ... construct outlined in Windows PowerShell 1.0 Flow Control with if, else and elseif is perfectly adequate. Unfortunately, any more than two or three possible scenarios can quickly make such a construct both time consuming to write and difficult to read. As a case in point consider the following code example. The program is designed to prompt a user for a car model and subsequently uses if .. elseif ... statements to evaluate the car manufacturer:
write-host ("Please Enter Your Vehicle Model: ") $carModel = read-host if ($carModel -eq "Patriot") { $carManufacturer = "Jeep"; } elseif ($carModel -eq "Focus") { $carManufacturer = "Ford"; } elseif ($carModel -eq "Corolla") { $carManufacturer = "Toyota"; } else { $carManufacturer = "unknown"; } write-host "Manufacturer is $carManufacturer"
As you can see, whilst the code is not too excessive it is already starting to become somewhat hard to read and also took more time to write than should really be necessary. Imagine, however, if instead of 3 car models we had to test for 10, 20 or even 100 models. Clearly an easier solution is needed, and that solution is the switch statement.
Windows PowerShell switch Statement Syntax
The syntax for a Windows PowerShell switch statement is as follows:
switch -options (value)
{ <pattern> { statements }
<pattern> { statements }
<pattern> { statements }
<pattern> { statements }
default { statements }
}
In the above syntax outline value represents either a value, or an expression which returns a value. This is the value against which the switch operates. Using our example this would be the string representing the car model.
For each possible match a <pattern> is required. This can either be a single value against which the comparison is made, a wildcard, regular expression or any other expression. Following on from the case lines are the Windows PowerShell statements which are to be executed in the event of the pattern match or expression evaluating to be true.
The statements block may also contain an optional break or continue statement. These statements are used either to break out of the switch statement when a match is found, or skip any remaining code in a loop and begin the next iteration. If a break or continue is not specified, the switch statement will continue to work through any remaining cases even when a match has been found, potentially reducing the performance of the script.
Finally, the default section of the construct defines what should happen if none of the case statements present a match to the value.
A switch Statement Example
With the above information in mind we may now construct a switch statement which provides the same functionality as our previous, and somewhat unwieldy, if ... elseif ... else construct:
write-host ("Please Enter Your Vehicle Model: ") $carModel = read-host switch ($carModel) { "Patriot" { $carManufacturer = "Jeep"; } "Focus" { $carManufacturer = "Ford"; } "Corolla" { $carManufacturer = "Toyota"; } default { $carManufacturer = "unknown"; } } write-host "Manufacturer is $carManufacturer"
Explaining the Example
When executed, the sample script will, once again, prompt for a car model. Once entered, the response is assigned to the $carModel variable which in turn is used as the governing variable in the switch statement.
The default option simply sets the $carManufacturer string to unknown if none of the case statements match the string entered by the user.
Using break in a Windows PowerShell switch Statement
In the above example we did not use the break statement to exit out of the switch statement. Although it was not visible during the execution, the switch statement continued to perform matching even after a match was found. To demonstrate this, consider the following example, where the "Patriot" match is included twice:
$carModel = "Patriot" switch ($carModel) { "Patriot" { write-host "First match. The car is a Jeep" } "Patriot" { write-host "Second match. The car is still a Jeep" } "Corolla" { write-host "This car is a Toyota" } }
Because there is no break after a match has been found, the switch statement moves on to other cases, resulting in the following output:
First match. The car is a Jeep Second match. The car is still a Jeep
To avoid this problem, all that is needed is a break statement in each set of match statements. For example:
$carModel = "Patriot" switch ($carModel) { "Patriot" { write-host "First match. The car is a Jeep"; break } "Patriot" { write-host "Second match. The car is still a Jeep"; break } "Corolla" { write-host "This car is a Toyota" } }
As a result of these changes, the switch statement will exit when it finds a match to the "Patriot" car model resulting in just one line of output:
First match. The car is a Jeep
The switch $_ Variable
When a switch is operating, the value being evaluated for a match is assigned to a special variable referenced by $_. This is provided so that the value may be accessed within the body of the switch construct. This is of particular use when using expressions in a switch statement as described in the following section.
Using Expressions in a Windows PowerShell switch Statement
One of the features of the Windows PowerShell switch statement that is missing from many other implementations in other languages is the ability to use expressions to evaluate whether a case matches. For example, the following switch construct is designed to find out whether the value falls within a particular value range. Note the use of the $_ variable as described above:
$myVal = 15 switch ($myVal) { {$_ -lt 5} { write-host "$_ is less than 5" } {$_ -lt 10} { write-host "$_ is less than 10" } {$_ -lt 20} { write-host "$_ is less than 20" } }
Note also that the expression must be enclosed in curly braces ({}). When executed, the preceding example will generate the following output:
15 is less than 20
Wildcards, Regular Expressions and Case Sensitivity in switch Statements
Another powerful feature of the Windows PowerShell switch statement involves the ability to use wildards and regular expressions (regex) when performing matches.
When using wildards, the -wildcard option must be passed through the switch statement. The following example demonstrates the use of wildcards when seeking a match to a particular value in a switch statement:
$beginsWith = "Red" switch -wildcard ($beginsWith) { Red* { "RedBull" } Red* { "RedLine" } Blue* { "BlueZone" } }
When executed, the above statement produces matches for anything that begins with "Red":
RedBull RedLine
Similarly, regular expressions may be used by specifying the -regex option when constructing the switch statement. In the following statement, regular expressions are used to detect whether the value begins and ends with specific characters:
switch -regex ("apple") { '^a' { "Begins with a" } 'e$' { "ends with e" } '^c' { "Begins with c" } } Begins with a Ends with e
This is a good point to raise the issue of case sensitivity in Windows PowerShell switch statements. The important point to note is that, unless otherwise specified, switch statements are case insensitive. To make a switch statement case sensitive the -casesensitive statement must be used:
switch -casesensitive ("RedLine") { 'redline' { "redline matches" } 'Redline' { "Redline matches" } 'RedLine' { "RedLine matches" } }
Clearly, with a case sensitive match, only one of the switch cases will result in a match (RedLine).
Using switch Statements to Iterate through Ranges and Collections
So far in this chapter we have looked at using switch statements to find matches to a single value. In fact, Windows PowerShell switch statements can be used to iterate through collections of values. A simple example involves a number range:
switch (1..10) { {$_ % 2} {"$_ is an odd number"} default {"$_ is an even number"} }
When executed the following output is generated:
1 is an odd number 2 is an even number 3 is an odd number 4 is an even number 5 is an odd number 6 is an even number 7 is an odd number 8 is an even number 9 is an odd number 10 is an even number
Similarly, the elements of an array can be passed through to the switch statement. In the following example, the array output from a directory listing is run through the switch statement to identify text and Word documents by checking the file name extension of each file name:
switch -wildcard (dir) { '*.txt' {"$_.name is a text file"} '*.doc' {"$_.name is a Word document"} }
When executed, the output might appear as follows:
date.txt is a text file error.txt is a text file filename.txt is a text file letter.doc is a Word document mydata.txt is a text file mydatafile.txt is a text file output.txt is a text file
Using the continue Statement
One final statement that has not yet been covered in relation to the Windows PowerShell switch construct is the continue statement. The continue statement is particularly useful when iterating through collections as described above, and serves to return execution to the top of the switch statement so that execution can be begin on the next element of the collection, thereby bypassing any other tests that may remain in the statement. In the following example, when an odd number is identified, the switch statement immediately moves on to the next value in the range:
switch (1..10) { {$_ % 2} {"$_ is an odd number"; continue} default {"$_ is an even number"} }
If, on the other hand, a break statement had been used in place of the continue in the above example, the switch statement would have exited after the first odd number, instead of continuing to work through the entire range:
switch (1..10) { {$_ % 2} {"$_ is an odd number"; break} default {"$_ is an even number"} } 1 is an odd number
<google>BUY_WPS_BOTTOM</google>