Changes

Jump to: navigation, search

The Windows PowerShell 1.0 switch Statement

9,188 bytes added, 16:30, 3 December 2008
New page: 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'' st...
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 langauges) 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 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:

<pre>
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"
</pre>

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'')<br>
{
<pattern> { ''statements'' }<br>
<pattern> { ''statements'' }<br>
<pattern> { ''statements'' }<br>
<pattern> { ''statements'' }<br>
default { ''statements'' }<br>
}

This syntax needs a little explanation before we embark on creating a ''switch'' based version of the above ''if ... elseif .. else'' construct.

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, or an expression. Following on from the case line are the Windows PowerShell statements which are to be executed in the event of the pattern match or expression evaluating to be ''true''.

After the ''statements'' comes 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.

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:

<pre>
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"

</pre>

== 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:

<pre>
$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"
}
}
</pre>

Because there is no ''break'' after a match has been found, the switch statement moves on to other cases, resulting the following output:

<pre>
First match. The car is a Jeep
Second match. The car is still a Jeep
</pre>

To avoid this problem, all that is needed is a ''break'' statement in each set of match statements. For example:

<pre>
$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"
}
}
</pre>

As a result of these changes, the switch statement will exit when it find a match to the "Patriot" car model resulting in just one line of output:

<pre>
First match. The car is a Jeep
</pre>

== 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 the 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:

<pre>
$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"
}
}
</pre>

Note also that the expression must be enclosed in curly braces ({}). When executed, the preceding example will generate the following output:

<pre>
15 is less than 20
</pre>

== 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 ''-wildard'' 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":

<pre>
RedBull
RedLine
</pre>

Similarly, regular expressions may be used by specifying the ''-regex'' option when constructing the switch statement. In the following statement, regular expressions are using to detect whether the value begins and ends with specific characters:

<pre>
switch -regex ("apple")
{
'^a' { "Begins with a" }
'e$' { "ends with e" }
'^c' { "Begins with c" }
}

Begins with a
Ends with e
</pre>

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 ==

Navigation menu