April 29th, 2009

Hey, Scripting Guy! How Can I Use the Do…While…Loop in Windows PowerShell?

Hey, Scripting Guy! Question

Hey, Scripting Guy! I frequently work with arrays in my scripts. The way I write scripts, I end up using Do…While…Loop frequently. I know that you like using the For…Each…Next for arrays, but to me Do…While…Loop seemed easier and more flexible. I looked and cannot find an example of how to use Do…While…Loop in Windows PowerShell. I can find the ForEach statement, but not the Do…While…Loop. It will be a bear if I have to switch over and completely change the way I write scripts.

– AB

SpacerHey, Scripting Guy! Answer

Hi AB,

Ed here. If you have been following us on Twitter, I took the weekend off, and the Scripting Wife and I went to Columbia, South Carolina, in the United States. While we were there we went to the Riverbanks Zoo. So I know exactly what you mean when you say changing the way that you write scripts will be a bear. Perhaps even a bear such as this one I photographed Sunday:

Image of a scary bear

 

However, you are right. We Scripting Guys seem to favor using the For…Each…Next when working with VBScript. We also like it in Windows PowerShell. But as we mentioned on Monday, it is all about choices. There are reasons why the different constructions were created, and each has advantages and disadvantages.

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.

We thought we would practice writing a bit of VBScript, so we created this DemoDoWhile.vbs script just for you AB. The first thing we do is assign the value of 0 to the variable i. We then create an array. To do this, we use the Array function, and assign the numbers 1 through 5 to the variable ary. We then use the Do…While…Loop construction to walk through the array of numbers. As long as the value of the variable i is less than the number 5, we display the value of the variable i. We then increment the value of the variable i and loop back around. The DemoDoWhile.vbs script is seen here:

i = 0
ary = Array(1,2,3,4,5)
Do While i < 5
 WScript.Echo ary(i)
 i = i + 1
Loop

When we run the DemoDoWhile.vbs script in Cscript at the command prompt, we see the numbers 1 through 5 displayed at the command prompt. This is seen here:

Image of the numbers 1 through 5 being displayed by the DemoDoWhile.vbs script when it is run in Cscript

 

We can do exactly the same thing by using Windows PowerShell. The DemoDoWhile.ps1 script and the DemoDoWhile.vbs script are the same. The first thing we do is assign the value of 1 to the variable $i. We then create an array of the numbers 1 through 5 and store that array in the $ary variable. We use a shortcut in Windows PowerShell to make this a bit easier. Actually, arrays in Windows PowerShell are fairly easy anyway. If you want to create an array you just have to assign multiple pieces of data to the variable. To do this, we would separate each piece of data by a comma. This is seen here:

$ary = 1,2,3,4,5

If we needed to create an array with 32,000 numbers in it, it would be impractical to type each number and separate it with a comma. In VBScript we would have to use a For…Next…Loop to add the numbers to the array. In Windows PowerShell, we can use the range operator. To do this, we use a variable to hold the array of numbers that are created, and type the beginning and the ending number separated with two periods. This is seen here:

$ary = 1..5

Unfortunately the range operator does not work for letters. But there is nothing to prevent you from creating a range of numbers that represent the ASCII value of each letter, and then casting it to a string later. In fact we will do that in just a couple of minutes. It is cool! You may even find it useful some day.

Where were we? Oh, yeah. We are now ready for the Do…While…Loop in Windows PowerShell. We use the Do statement and open a set of braces (curly brackets). Inside these curly brackets, we have what is called a script block. The first thing we do is index into the array. On our first pass through the array, the value of $i is equal to 0. We therefore display the first element in the $ary array. We next increment the value of the $i variable by one. We are now done with the script block, so we look at the While statement. The condition we are examining is the value of the $i variable. As long as it is less than 5, we will continue to loop around. As soon as the value of $i is no longer less than the number 5, we stop looping. This is seen here:

DemoDoWhile.ps1

$i = 0
$ary = 1..5
do 
{
 $ary[$i]
 $i++
} while ($i -lt 5)

When we run the DemoDoWhile.ps1 script, we receive the results shown here:

Image of a number displayed when the value of $i is less than 5

 

One thing to be aware of is that we are evaluating the value of $i. We initialized $i at 0. The first number in our array was 1. But the first element number in the array is always 0 in Windows PowerShell (unlike VBScript, which can start arrays with 0 or 1). Our While statement examines the value of $i and not the value that is contained in the array, which is why you see the number 5 displayed.

We can change our DemoDoWhile.ps1 script and do something rather cool by displaying the uppercase letters from A–Z. To do this, we first initialize the $i variable and set it to 0. We then create a range of numbers from 65 through 91. These are the ASCII values for the capital letter A through the capital letter Z. Now we begin the Do statement and open our script block. To this point, the script is identical to the previous one. The trick we will use to separate letters from numbers is to cast the integer to a char. To do this, we use the char data type and put it in square brackets. We then use this to convert an integer to uppercase letter. To display the uppercase letter B from the ASCII value of 66, the code would resemble the following:

PS C:\> [char]66
B

Because we know that the $caps variable contains an array of numbers that range from 65 through 91, and that the variable $i will hold numbers from 0 through 26, we index into the $caps array and cast the integer to a char and display the results. That’s what this line of code does:

[char]$caps[$i]

We then increment the value of $i by one, close the script block, and enter the While statement where we check the value of $i to make sure it is less than 26. As long as $i is less than 26, we continue to loop around. The complete DisplayCapitalLetters.ps1 script is seen here:

$i = 0
$caps = 65..91
do
{
 [char]$caps[$i]
 $i++
} while ($i -lt 26)

AB, we hope that you will explore the Do…While…Loop construction with Windows PowerShell, and you will be able to use it to meet your scripting needs. You know, while I was at the Riverbanks Zoo this weekend, I saw another bear as well. If you encounter a bear while scripting, I hope that it is this guy and not the first bear we saw:

Image of a cuddly bear

 

Keep on scripting, and we will see you tomorrow as we continue talking about looping. Until then, watch out for the bears.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

Author

0 comments

Discussion are closed.