ForEach


The ForEach statement is used for stepping through a collection of objects. Usually some block of code is executed for each step when the ForEach statement is used. In other words, "take these steps for each thing in the collection of things." Here's the syntax for this statement:

 foreach ($<item> in $<collection>){<command_block>} 

This statement is expecting a variable and a collection in parenthesis. The command block that is contained in the braces will be executed for each variable, each time it goes through the collection. The command block can be as simple as something like this:

 PS C:\> $var=("apple","banana","pineapple","orange") PS C:\> foreach ($fruit in $var) {$fruit} apple banana pineapple orange PS C:\> 

We first create an array of fruits. Remember that an array is a collection. The ForEach statement says that for each fruit variable in the fruit collection ($var), display the value of the fruit variable.

Here's a slightly more involved example:

ForEachFruit.ps1

image from book
 #ForEachFruit.ps1 $var=("apple","banana","pineapple","orange") foreach ($fruit in $var) { $i++ #this is a counter that is incremented by one each time through write-host "Adding" $fruit } write-host "Added" $i "pieces of fruit" 
image from book

When this script is run, it produces the following output:

 Adding apple Adding banana Adding pineapple Adding orange Added 4 pieces of fruit PS C:\> 

We can even nest other logic constructs within a ForEach statement:

ForEachFile.ps1

image from book
 #ForEachFile.ps1 set-location "C:\" $sum=0 foreach ($file in get-childitem) { #$file.GetType()   if (($file.GetType()).Name -eq "FileInfo") {    write-host $file.fullname `t $file.length "bytes"    $sum=$sum+$file.length    $i++    } } write-host "Counted" $i "file for a total of" $sum "bytes." 
image from book

In this script we're using the Get-Childitem cmdlet to return all items in C:\. We can do this because the results of the Get-Childitem cmdlet return a collection object. So even though we don't know the contents of the collection, we can still enumerate on the fly. For each $file variable in the collection, if the object type name is FileInfo, then we display the name and file size (using the length property). We've also added code to calculate a running total of the sum of all the files using $sum and we use $i as a counter that increases by one each time.

When the script is run it generates the following output:

 C:\AUTOEXEC.BAT          0 bytes C:\AVG7QT.DAT    12283633 bytes C:\COMLOG.txt    0 bytes C:\CONFIG.SYS    0 bytes C:\docs.csv      24938 bytes C:\DVDPATH.TXT   55 bytes C:\EventCombMT_Debug.log         854 bytes C:\hpfr5550.xml          488 bytes C:\IALog.txt     271 bytes C:\log.csv       10734 bytes C:\Log.txt       72 bytes C:\mtaedt22.exe          2650696 bytes C:\netdom.exe    142848 bytes C:\new-object.txt        10240 bytes C:\out-grid.ps1          811 bytes C:\out-propertyGrid.ps1          1330 bytes C:\processes.html        118828 bytes C:\servers.txt   19 bytes C:\showprocessinfo.ps1   710 bytes C:\showservices.ps1      477 bytes C:\test.ps1      88 bytes C:\txt.csv       22995 bytes Counted 22 file for a total of 15270087 bytes. PS C:\> 

Finally, we can also use ForEach in a pipeline to process output from a cmdlet or other operation. This is the syntax:

 <command> | foreach {<command_block>} 

For example, you might want to try something like this:

 PS C:\> get-service | foreach {write-host $_.displayname ` "("$_.status")"} Alerter ( Stopped ) Application Layer Gateway Service ( Stopped ) Application Management ( Stopped ) ASP.NET State Service ( Stopped ) Windows Audio ( Running ) AVG7 Alert Manager Server ( Running ) AVG7 Update Service ( Running ) AVG E-mail Scanner ( Running ) #output abbreviated 

When used in this manner we're putting the collection first and pipelining it to ForEach. The script block uses the $_ variable to indicate the current item in the collection. In this case, the collection is a service object, which means we can show its displayname and status.

You might use this technique in a script like this to add some extra features:

ForEachSvc.ps1

image from book
 #ForEachSvc.ps1 get-service | foreach {   if ($_.status -eq "Running") {   write-host  $_.displayname "("$_.status")" -foregroundcolor "Green"   write-host `t "Service Type="$_.servicetype -foregroundcolor "Green"   }   else   {   write-host  $_.displayname "("$_.status")" -foregroundcolor "Red"   } } 
image from book

This is essentially the same command except that we've nested an If statement that says if the service status is running, then display the information in green and also show the service type. Otherwise, display the information in red.

Alias Alert

The ForEach statement is actually an alias for the ForEach-Object cmdlet. This doesn't really change how we use it. However, we're pointing this out in case you find examples using the cmdlet. Using the alias just means a little less typing.



Windows PowerShell. TFM
Internet Forensics
ISBN: 982131445
EAN: 2147483647
Year: 2004
Pages: 289

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net