Understanding the PowerShell While Statement

Microsoft Scripting Guy, Ed Wilson, is here. Today I am happy to provide you with an excerpt from my new book Windows PowerShell 3.0 Step by Step, published by Microsoft Press.

In VBScript, you had the While…Wend loop. An example of using the While…Wend loop is the WhileReadLineWend.vbs script. The first thing you do in the script is create an instance of the FileSystemObject, and store it in the objFSO variable. You then use the OpenTextFile method to open a test file, and you store that object in the objFile variable.

You then use the While…Not …Wend construction to read one line at a time from the text stream and display it on the screen. You continue to do this until you are at the end of the text stream object. A While … Wend loop continues to operate as long as a condition is evaluated as True. In this example, as long as you are not at the end of the stream, you will continue to read the line from the text file. The WhileReadLineWend.VBS script is shown here:

Constructing the While statement

As you probably have already guessed, you have the same kind of construction available to you in Windows PowerShell. The While statement in Windows PowerShell is used in the same way that the While…Wend statement was used in VBScript.

In the DemoWhileLessThan.ps1 script, you first initialize the variable $i to be equal to 0. You then use the While keyword to begin the While loop. In Windows PowerShell, you must include the condition that will be evaluated inside a set of parentheses. For this example, you determine the value of the $i variable with each pass through the loop.

If the value of $i is less than the number 5, you will perform the action that is specified inside the braces, which set off the script block. In VBScript, the condition that is evaluated is positioned on the same line with the While statement, but no parentheses are required.

Although this is convenient from a typing perspective, it actually makes the code a bit confusing to read. In Windows PowerShell, the statement is outside the parentheses, and the condition is clearly delimited by the parentheses. In VBScript, the action that is performed is added between two words: While and Wend. In Windows PowerShell, there is no Wend statement, and the action to be performed is positioned inside a pair of braces.

Although shocking at first to user’s coming from a VBScript background, the braces are always used to contain code. This is what is called a script block, and they are used everywhere. As soon as you are used to seeing them, you will find them with other language statements also. The good thing is that you do not have to look for items such as the keyword Wend, or the keyword Loop (from the Do…Loop fame).

Understanding expanding strings

In Windows PowerShell, there are two kinds of strings: literal strings and expanding strings. In the DemoWhileLessThan.ps1 script you use the expanding string (signified when you use the double quotation mark ( “ ). (The literal string uses the single quotation mark ( ‘ ). You want to display the name of the variable, and you want to display the value that is contained in the variable.

This is a perfect place to showcase the expanding string. In an expanding string, the value that is contained in a variable is displayed to the screen when a line is evaluated. As an example, consider the following script. You assign the value 12 to the variable $i. You then put $i inside a pair of double quotation marks, which creates an expanding string. When the line “$i is equal to $i” is evaluated, you obtain “12 is equal to 12,” which, although true, is barely illuminating. This is shown here:

PS C:\> $i = 12 PS C:\> "$i is equal to $i" 12 is equal to 12 PS C:\>

Understanding literal strings

What you probably wanted to do is display both the name of the variable and the value that is contained inside it. In VBScript, you would have to use concatenation. For this example to work, you have to use the literal string as shown here:

If you want to use the advantage of the expanding string, you have to suppress the expanding nature of the expanding string for the first variable. To do this, you use the escape character, which is the grave accent (or backtick) as shown here:

In the DemoWhileLessThan.ps1 script, you use the expanding string to print the status message of the value of the $i variable during each trip through the While loop. You suppress the expanding nature of the expanding string for the first $i variable so you can see which variable you are talking about. As soon as you have done this, you increment the value of the $i variable by one. To do this, you use the $i++ syntax. This is identical to saying the following:

$i = $i + 1

The advantage is that the $i++ syntax is less typing. The DemoWhileLessThan.ps1 script is shown here:

When you run the DemoWhileLessThan.ps1 script, you receive the following output.

$i equals 0. This is less than 5 $i equals 1. This is less than 5 $i equals 2. This is less than 5 $i equals 3. This is less than 5 $i equals 4. This is less than 5 PS C:\>

A practical example of using the While statement

Now that you know how to use the While loop, let’s examine the WhileReadLine.ps1 script. The first thing you do is initialize the $i variable and set it equal to 0. You then use the Get-Content cmdlet to read the contents of the testfile.txt and to store the contents into the $fileContents variable.

Use the While statement to loop through the contents of the text file. You do this as long as the value of the $i variable is less than or equal to the number of lines in the text file. The number of lines in the text file is represented by the Length property. Inside the script block, you treat the contents of the $fileContents variable like it is an array (which it is), and you use the $i variable to index into the array to print the value of each line in the $fileContents variable. You then increment the value of the $i variable by one. The WhileReadLine.ps1 script is shown here:

The output is exactly the contents of C:fsotestfile.txt
$fileContents[$i] is using an index [] of the object, and will, line by line, output the screen since Get-Content reads a text file into the $fileContents variable line by line.

Since we don’t know what was in the example txt file, there’s no way to know what the actual output would have been.