Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a number of tasks that I always have to do. These tasks are somewhat repetitive, and I want to be able to write a Windows PowerShell script to eliminate the repetition. Is there something I can use to help with the mind-numbing repetition?

- CH

SpacerHey, Scripting Guy! Answer

Hi CH,

Ed here. Some repetition is good. For example, several years ago the Scripting Wife, a couple of scripting friends, and I went to Aruba. Each day we would walk along the beach at sunset:

Image of Aruba at sunset

 

To be honest, I could do with a bit of that kind of repetition about now. The problem is not the repetition, but the kind of repetition that becomes an issue. Luckily, with Windows PowerShell we can resolve your repetition issue by using the For…Loop (or the For statement, as it is also known).

This week we are looking at scripting 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.

In VBScript, a For…Next…Loop was somewhat easy to create. An example of a simple For…Next…Loop is seen in DemoForLoop.vbs. You use the For keyword, define a variable to keep track of the count, indicate how far you will go, define your action, and specify the Next keyword. That is about all there is to it. It sounds more difficult than it is.

DemoForLoop.vbs

For i = 1 To 5
 WScript.Echo i
Next

You can achieve the same thing in Windows PowerShell. The structure of the For…Loop in Windows PowerShell resembles the structure for VBScript. They both begin with the keyword For, they both initialize the variable, and they both specify how far the loop will progress. One thing that is different is that a For…Loop in VBScript automatically increments the counter variable. In Windows PowerShell, the variable is not automatically incremented, and we add $i++ to increment the $i variable by one. Inside the script block (which is set off by curly brackets) we display the value of the $i variable.

DemoForLoop.ps1

For($i = 0; $i -le 5; $i++)
{
 '$i equals ' + $i 
}

The Windows PowerShell For statement is very flexible, and you can leave one or more elements of it out. In the DemoForWithoutInitOrRepeat.ps1 script, we exclude the first and the last sections of the For statement. We set the $i variable equal to 0 on the first line of the script. We next come to the For statement. In the DemoForLoop.ps1 script, the $i = 0 was moved from inside the For statement to the first line of the script. The semicolon is still required because it is used to separate the three sections of the statement. The condition portion, $i –le 5, is the same as in the previous script. The repeat section, $i ++, is not used either.

In the script section of the For statement, we display the value of the $i variable, and we also increment the value of $i by one. There are two kinds of Windows PowerShell strings: expanding and literal. In the DemoForLoop.ps1 script, you see an example of a literal string—what is entered is what is displayed. This is shown here:

'$i equals ' + $i

In the DemoForWithoutInitOrRepeat.ps1 script, you see an example of an expanding string. The value of the variable is displayed—not the variable name itself. To suppress the expanding nature of the expanding string, escape the variable by using the backtick character (`). When you use the expanding string in this manner, it enables you to avoid concatenating the string and the variable as we did in the DemoForLoop.ps1 script. This is shown here:

"`$i is equal to $i"

The value of $i must be incremented somewhere. Because it was not incremented in the repeat section of the For statement, we have to be able to increment it inside the script block. The DemoForWithoutInitOrRepeat.ps1 script is shown here:

DemoForWithoutInitOrRepeat.ps1

$i = 0
For(;$i -le 5; )
{
 "`$i is equal to $i"
 $i++
}

When we run the DemoForWithoutInitOrRepeat.ps1 script, the output that is displayed resembles the output produced by the DemoForLoop.ps1. You would never be able to tell it was missing two-thirds of the parameters:

Image of output from DemoForWithoutInitOrRepeat.ps1

 

At this point, you may be asking yourself, "Why would I want to do something such as this?" Who knows! Suppose that you were walking along the beach in Aruba, and you saw some umbrellas such as these that I photographed:

Image of umbrellas on a beach in Aruba

 

You may ask, "Why would I want to lounge around on a sandy beach, smear greasy stuff on my face, and get sand in my slippers." Or you might say, "I think I will go take a quiet repose under yonder palm tree." Why ask why? Because you can, because it is there, or just because—it really does not matter why. One day, you may find a need for it. The way my scripting goes, if I did not know I could do something, that is the one technique I would need to make a script work correctly. It is always nice to have options.

Speaking of options, you can put your For statement into an infinite loop by omitting all three sections of the For statement. You must leave the semicolons as position holders. When you omit the three parts of the For statement, the For statement will resemble the following:

for(;;)

Whereas the ForEndlessLoop.ps1 script will create an endless loop, you do not have to do this if this is not your desire. You could use an If statement to evaluate a condition and to take action when the condition was met. We will look at If statements in a later “Hey, Scripting Guy!” article. In the ForEndlessLoop.ps1 script, we display the value of the $i variable, and then increment it by one. The semicolon is used to represent a new line. The For statement could therefore be written on three lines if you wanted to do this. This would be useful if you had a very complex For statement because it would make the code easier to read. The script block for the ForEndlessLoop.ps1 script could be written on different lines and exclude the semicolon. This is seen here:

{
 $i
 $i++
}

ForEndlessLoop.ps1

for(;;)
{
 $i ; $i++
}

When you run the ForEndlessLoop.ps1 script, you are greeted with a long line of numbers. To break out of the endless loop, press Ctrl+C inside the Windows PowerShell prompt. The long line of numbers is shown here:

Image of an endless loop of numbers, which can be ended by pressing CTRL+C

 

CH, you can see that working with Windows PowerShell is all about choices: how do you want to work and what are you trying to achieve? The For statement in Windows PowerShell is very flexible, and maybe one day, you will find just the problem waiting for the solution that you have. We have to return to work on the Scripting Games. They are coming up shortly, and we need to put the finishing touches on some of the events. We will be making an announcement soon. See you tomorrow. Stay cool.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys