| Executive Summary: Lesson 2 in Robert Sheldon's PowerShell 201 series covers the if, for, and while statements. This lesson explains the various components that make up these statementsand provides examples of how to use each type of statement for tasks such as retrieving a list of text files in a folder and retrieving a list of processes and the number of handles used by those processes. |
Windows PowerShell provides several ways to control the
flow of code, including the if, for, and while statements.
You can use these three statements to define conditions
and the actions to occur when those conditions
are met. You can even specify the actions to occur
when a condition isn’t met. Let’s look at the various
components that make up the if, for, and while statements and how to
use each type of statement for tasks such as retrieving a list of text files
in a folder and retrieving a list of processes and the number of handles
they’re using.
The if Statement
An if statement contains a conditional code block, which is enclosed in parentheses, and a script block,
which is enclosed in braces. The conditional code block specifies a condition, whereas the script block
specifies one or more actions. When the condition is met—that is, when the conditional code block
evaluates to true—PowerShell runs the script block. When the conditional code block evaluates to false,
PowerShell skips the script block.
For example, the following code initializes the $files variable, then defines a basic if statement:
$files = dir c:\archivedfiles\*.txt
if ($files -ne $null)
{
"There are files in this folder."
write-host
}
The first line assigns a collection of text files to $files. The if statement uses the $files variable in its conditional
code block ($files -ne $null) to specify that the variable must not be null. In other words, the
variable must contain text files. When there are text files, the conditional code block evaluates to true
and the script block runs and displays the message There are files in this folder. When the conditional
code block evaluates to false, the if statement ends. As a result, no message is displayed when the folder
doesn’t contain text files.
At times, you might want to take a specific
action when a conditional code block
evaluates to false. You can do so by adding
an else clause. This clause begins with the
keyword else, followed by its own script
block. The else script block runs when none
of the if statement’s conditional code blocks
evaluate to true. Take, for example, the following
if statement:
$files = dir c:\archivedfiles\*.doc
if ($files -ne $null)
{
"There are Word " +
"files in this folder."
write-host
}
else
{
"No Word files in this folder."
write-host
}
When the conditional code block ($files -ne
$null) evaluates to false, the else script block
runs and displays the message No Word files
in this folder.
In this example, the if statement takes
into account two scenarios: the folder contains
Microsoft Word files or doesn’t contain
them. However, there might be times when
you want the statement to handle more than
two scenarios. In these situations, you can add a few elseif clauses. (If you need to use
many elseif clauses, you should consider
using a switch statement, which I’ll discuss
in the next lesson.) For each elseif clause, you
define a conditional code block and a script
block. When the conditional code block
evaluates to true, the script block runs.
For example, the code in Listing 1 uses
elseif clauses to determine how many files
are in a folder. In this code, one if statement
is embedded in another if statement. The
code begins by assigning a collection of text
files to $files. The outer if statement then
checks to see whether $files is null. I perform
this check rather than using the Count
property to determine the number of files
because I had to provide for the possibility
that there might be only one file in the folder.
The Count property is available only when
there’s two or more files in a folder. When
there’s more than one file, PowerShell treats
$files as an array, which supports the Count
property. When there’s only one file, PowerShell
treats $files as a scalar (i.e., single)
value, which means the Count property isn’t
available.
When the outer if statement finds that
$files is null, the else clause in callout B runs.
This clause’s script block displays the message
No files in folder. When $files isn’t null, the
inner if statement in callout A runs. The inner
if statement’s conditional code block defines
three conditions: an if condition
and two elseif conditions.
The if condition ($files.count -gt 10)
specifies that the number of text files must
be greater than 10. When this conditional
code block evaluates to true, the script
block displays the message More than 10
files in folder.
The first elseif condition ($files.count -gt
7 -and $files.count -le 10) specifies that the
number of text files must be greater than
7 but less than or equal to 10. When this conditional code block evaluates to true, the
script block displays the message 8-10 files
in folder.
The second elseif condition ($files.count
-gt 4 -and $files.count -le 7) specifies that the
number of text files must be greater than 4
but less than or equal to 7. When that conditional
code block evaluates to true, the script
block displays the message 5-7 files in folder.
If none of the three conditional code
blocks evaluate to true, the else clause’s
script block runs. It displays the message
Fewer than 5 files in folder.
Continue to page 2
As Listing 1, demonstrates,
you can embed if statements in the script
block of another if statement, but you aren’t
limited to embedding only these types of
statements. You can, for example, embed a
foreach statement in an if statement’s script
block, as shown in Listing 2. The foreach statement runs only when the if statement’s conditional code block evaluates
to true. In other words, when the folder
contains text files, the foreach statement will
loop through those text files. Each time a loop runs, foreach returns the text file’s size,
as Figure 1, shows.
The for Statement
In Lesson 1, I showed you how to implement
foreach loops to iterate through a
collection. You can also use for statements
to loop through collections. A for statement
implements a counting loop that
iterates through a collection as long as
the condition is true. Like if statements, for statements include a conditional code
block and a script block. However, the for statement’s conditional code block is more
complex.
Let’s take a look at a simple example.
The following for statement displays the
values assigned to the $a variable:
for ($a = 1; $a -le 5; $a++) {$a}
The statement begins with the keyword for, followed by the conditional code block
($a = 1; $a -le 5; $a++). The for statement’s
conditional code block is made up of three
parts, which are separated by
semicolons. The first part ($a
= 1) initializes the $a variable
with the value 1. The $a variable
provides a base value, or
starting value, for the other
code block elements.
The second part ($a -le 5) is
the condition itself. In this case,
the value in $a must be less
than 5 to evaluate to true. The
third part ($a++) increments $a
by 1 at the end of each loop. As
a result, the statement will continue
to step through the collection
as long as the value in $a is
less than or equal to 5. When $a
equals 6, the for statement ends. Figure 2 shows sample output
from this statement.
In some cases, you won’t
know the number of elements
in a collection. The code in Listing 3 demonstrates how you
can use a for statement to iterate
through such collections.
This code begins by storing
a collection of text files in the
$files variable. The if statement
uses the $files variable and its
Count property ($files.count) to check the file count. As I mentioned previously,
if there’s only one file in the collection,
PowerShell returns an object (i.e., a System
.IO.FileSystemInfo object) that has a scalar
value. If there are no files, PowerShell
doesn’t return an object. In either case, the
Count property doesn’t exist. As a result,
you receive a null value if you try to call the
Count property, which is why you can use it
as a condition in the if statement.
When $files.count returns a null value,
the elseif clause in callout B checks for the
condition of there being only one file. If this
condition isn’t met, there are no files and the
else clause in callout C runs.
When $files.count doesn’t return a null
value (i.e., PowerShell returns a System
.Array object so the Count property exists),
the code in callout A runs because there are
at least two files. In callout A, the embedded for statement’s conditional code block uses
the Count property to determine the exact
number of files (i.e., elements) in the collection.
As long as $i is less than the number of
elements, the condition evaluates to true.
Note that I initialize $i to 0. I use 0 because
collections (such as $files) use base 0 indexing.
In the script block, I use $i to specify which
element to retrieve from the collection. For
instance, during the first loop, $i is set to 0. This
means that $files[$i] is the same as $files[0].
On the second loop, $i equals 1, so the value
becomes $files[1], and so on. Figure 3 shows
sample results from the code in Listing 3.
One other item worth pointing out is
that you can declare and initialize the
base variable before the for statement. For example, in Listing 4,
the $i variable is declared
and initialized in the line
highlighted by callout A.
As you can see, the code
is easier to read with this
setup.
The while Statement
Like the for statement,
the while statement is a
type of loop that iterates
through a collection. The while statement, which
consists of a conditional
code block and a script
block, continues as long as
the conditional code block
evaluates to true. The following
code provides a
simple example of how
this works:
$count = 0
while ($count -lt 5)
{
$count++
"The count is
$count."
}
The first line of code initializes the $count
variable to 0. This variable is used as a base
or starting value for the looping. The conditional
code block ($count -lt 5) specifies that
$count must be less than 5.
When the conditional code block evaluates
to true, the script block runs. The
first statement in the script block increments
$count by 1. The second statement
outputs a string that displays the running
value in $count, as shown in the results:
The count is 1.
The count is 2.
The count is 3.
The count is 4.
The count is 5.
Note that when $count is 4 in the conditional
code block, the script block increments
$count by 1 and displays a value of 5 in the
output. It’s not until the next time through the
loop that the conditional code block evaluates
to false, ending the while loop.
Sometimes you might not know the
number of elements in a collection that’s
being iterated through with a while loop. In
this situation, you can use the Count property
to retrieve that value:
$proc = Get-Process
$count = 0
while ($count -lt
$proc.count)
{
"The " +
$proc[$count].name +
" process uses " +
$proc[$count].handles +
" handles."
$count ++
}
This code first assigns the
results of the Get-Process
cmdlet to the $proc variable.
This cmdlet returns
a list of processes running
on the local system. The
conditional code block in
the while loop specifies
that the value in $count
must be less than the
total number of processes
($proc.count). Figure 4 shows sample results from
running this code. As you
can see, you can use the
$proc variable to retrieve
not only the number of
processes but also each
process’s name and number of handles.
Moving Forward
In this lesson, you learned about the if,
for, and while statements. These statements,
along with the foreach statement
and ForEach-Object cmdlet discussed in
Lesson 1, provide a wide range of tools for
implementing flow-control statements. You
should try out all these statements and try
to combine them in different ways, such as
adding if statements to foreach statements.
The more comfortable you become with
using these statements, the better you’ll
understand them and be able to implement
them in your code.