Hey, Scripting Guy! Question

Hey, Scripting Guy! I am trying to get ready for the Summer Scripting Games. I understand they are coming up fairly soon. So I am thinking I want to compete in the beginner division this year for Windows PowerShell. I am trying to get my head around looping. I know that you are talking about it this week, but I am still thrown for a loop (pun intended). Can you help me?

- RI

SpacerHey, Scripting Guy! Answer

Hi RI,

So you are planning on competing in the 2009 Summer Scripting Games, and you want to get into shape? Good idea! We have been working on the 2009 Summer Scripting Games for a while now, and although we are not going to spoil any surprises, we can say it would be good to be on top of your game.

Looping technology is something that is essential to master. It occurs everywhere and should be a tool that you can use without thought. When you are confronted with a collection of items, an array, or other bundle of items, you have to know how to easily walk through the mess without resorting to research, panic, or hours searching the Internet with Live search. Let's examine the Do…Until…Loop construction. Most of the scripts that do looping on the TechNet Script Center seem to use the Do…While…Loop. The scripts that use Do…Until…Loop are typically used to read through a text file (do until the end of the stream) or to read through an Active X Data Object (ADO) recordset (do until the end of the file). As you will see today, these are not required coding conventions and are not meant to be limitations. You can frequently perform the same thing by using any of the different looping constructions.

This week we are looking at scripting with Windows PowerShell. Windows PowerShell is installed by default on Windows Server 2008 R2 and Windows 7. It is an optional installation on Windows Server 2008, and a download for Windows Vista, Windows XP, and Windows Server 2003. The Windows PowerShell Scripting Hub is a good place to start using Windows PowerShell. An excellent book for learning Windows PowerShell is the Microsoft Press book, Microsoft Windows PowerShell Step by Step. This book has many hands-on labs and uses real-world examples to show the use of Windows PowerShell.

Before we get too far into answering your question, let's consider a script we wrote to explain what we are talking about. In the DemoDoUntil.vbs script seen just below, we first assign a value of 0 to the variable i. We then create an array with the numbers 1 through 5 contained in it. We use the Do…Until…Loop construction to walk through the array until the value of the variable i is equal to the number 5. The script will continue to run until the value of the variable i is equal to 5. This is what a Do…Until…Loop construction does. It runs until a condition is met. The difference between a Do…Until…Loop and a Do…While…Loop is that the Do…While…Loop runs while a condition is true.

Inside the loop, we first display the value that is contained in the array element 0 on the first pass through the loop. This is because we first set the value of the variable i equal to 0. We next increment the value of the variable i by 1 and loop around until the value of i is equal to 5. The DemoDoUntil.vbs script is seen here:

i = 0
ary = array(1,2,3,4,5)
Do Until i = 5
 wscript.Echo ary(i)
 i = i+1
Loop

We can write the same script by using Windows PowerShell. In the DemoDoUntil.ps1 script, we first set the value of the $i variable to 0. We then create an array with the numbers 1 through 5 in it. We store that array in the $ary variable. We then arrive at the Do…Loop (Do...Until) construction. After the Do keyword, we open a set of braces (curly brackets). Inside the curly brackets we use the $i variable to index into the $ary array and to retrieve the value that is stored in the first element (element 0) of the array. We then increment the value of the $i variable by 1. We continue to loop through the elements in the array until the value of the $i variable is equal to 5. At that time, we end the script. This script resembles the DemoDoWhile.ps1 script we saw in yesterday’s “Hey, Scripting Guy!” article.

DemoDoUntil.ps1

$i = 0
$ary = 1..5

Do
{
 $ary[$i]
 $i ++
} Until ($i -eq 5)

In VBScript, if a Do…While…Loop condition was never true, the code inside the loop wouldn't execute. In Windows PowerShell, the Do…While and the Do…Until constructions always run at least once. This can be unexpected behavior and is something you should always be aware of. This is illustrated in the DoWhileAlwaysRuns.ps1 script. The script assigns the value of 1 to the variable $i. Inside the script block for the Do…While loop, we display a message that states we are inside the Do loop. The loop condition is While the variable $i is equal to 5. As you can see, the value of the $i variable is 1. Therefore, the value of the $i variable will never reach 5 because we are not incrementing it. The DoWhileAlwaysRuns.ps1 script is seen here:

DoWhileAlwaysRuns.ps1

$i = 1

Do
{
 "inside the do loop"
} While ($i -eq 5)

When we run the script, the text "inside the do loop" is displayed once. This is seen here:

Image of the script block of a Do...While statement, which always runs one time

 

What about a similar script that uses the Do…Until construction? The EndlessDoUntil.ps1 script is the same script as the DoWhileAlwaysRuns.ps1 script, except for one small detail. Instead of using Do…While, we are using Do…Until. The rest of the script is the same. The value of the $i variable is equal to 1, and in the script block for the Do…Until loop, we display the string "inside the do loop." This line of code should execute once for each Do loop until the value of $i is equal to 5. Because the value of $i is never increased to 5, the script will continue to run. The EndlessDoUntil.ps1 script is shown here:

EndlessDoUntil.ps1

$i = 1

Do
{
 "inside the do loop"
} Until ($i -eq 5)

Before we run the EndlessDoUntil.ps1 script, we should know how to interrupt the running of the script. We hold down the CTRL key and press C (CTRL+C). This was the same keyboard shortcut that would break a runaway VBScript that was run in Cscript. The results of running the EndlessDoUntil.ps1 script are seen here:

Image of the Do...While loop interrupted by CTRL+C

 

If you have a situation in which the script block must not execute if the condition is not true, you should use the While statement. We looked at the While statement in Tuesday’s “Hey, Scripting Guy!” article. Again we have the same kind of script. We assign the value of 0 to the variable $i, and instead of using a Do… kind of construction, we use the While statement. The condition we are looking at is the same condition we used for the other scripts: while the value of $i is equal to 5. Inside the script block, we display a string that states we are inside the While loop. The WhileDoesNotRun.ps1 script is shown here:

WhileDoesNotRun.ps1

$i = 0

While ($i -eq 5)
{
 "Inside the While Loop"
}

It is perhaps a bit anticlimactic, but let's just run the WhileDoesNotRun.ps1 script to make sure we have not messed up something. When we run the WhileDoesNotRun.ps1 script, we are greeted with the pretty blue display that you see here:

Image of the script block not executing because the While condition is not satisfied

 

RI, I hope this discussion will help you get in shape for the 2009 Summer Scripting Games. Follow us on Twitter for all the latest and greatest information about the 2009 Summer Scripting Games. Details will be announced there first, and then will be made available on the Script Center home page. Ed will be speaking at Tech∙Ed 2009 in Los Angeles in a couple of weeks, and if you are there, please stop by the Scripting Guys booth and chat us up. This also brings to a conclusion our discussion of looping with Windows PowerShell. Join us tomorrow as we open the e-mail bag and answer all those short-answer kind of questions. Once again, it’s time for the sensation sweeping the nation: Quick-Hits Friday! Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys