For me, one of the most magical
aspects of scripting is how simple code loops through a set of instructions
and then produces results - in a flash. Sometimes this magic is
hidden, for example Get-Process implies looping as it returns all the
running
processes, in other cases we need foreach to explicitly call for PowerShell
to step through the items.
My mission on this page is to give you simple examples on how to master
the PowerShell foreach loop. As you become more proficient in
PowerShell, so the instructions grow in complexity.
The ForEach loop is for situations where we need to work with one object at
a time. Each loop interrogates an array, which is known as a
collection. During each cycle the foreach operator executes a
{Statement Block} on each individual item.
Note that when working
with PowerShell examples the brackets always carry hidden messages. Observe
that the (array enclosed by parenthesis brackets), while the block statement
is always contained in {Curly brackets}.
One more tiny, but crucial, component of the PowerShell foreach loop is
'in'.
The secret of understanding this PowerShell loop syntax is to absorb each element of
this syntax:
ForEach ($item in $array_collection) {command_block}.
Note 1: By creating these five variations, my aim is to give you
both perspective and experience of the pure, but simple PowerShell foreach
statement.
Note 2: Foreach is at the start of its command
line (unlike ForEach-Object).
Note 3: PowerShell's 'ForEach' is more
complex, and has more arguments than the 'for' and 'Do While' techniques for
stepping through a collection of items.
Guy Recommends: A Free Trial of the Network Performance Monitor
(NPM)
SolarWinds'
Network Performance Monitor
will help you discover what's happening on your network. This
utility will also guide you through troubleshooting; the dashboard will
indicate whether the root cause is a broken link, faulty equipment or
resource overload.
What I like best is the way NPM suggests solutions to network
problems. Its also has the ability to monitor the health of individual VMware
virtual machines. If you are interested in troubleshooting, and creating
network maps, then I recommend that you try NPM now.
In Example 2 we are going to transition from the explicit ($Item in
Collection) {Block Statement} to: Input stuff using Get-ChildItem, then pipe
(|) the output into a {Block Statement}.
Get-ChildItem is just the
vehicle for us to investigate aspects of the PowerShell foreach loop.
I chose the root of the C: drive simply because this example script will work
without modification on most of computers.
Example 2a Explicit ForEach Get-ChildItem
# PowerShell ForEach File Example Clear Host ForEach
($file in Get-Childitem C:\)
{ $file.name }
As usual with scripting PowerShell has dozens of techniques to achieve the
same outcome. The key difference in this example is how the
foreach works with input from PowerShell's piping. The point is that there is
no need for an explicit ($Item in $Collection) clause.
Guy Recommends: A Free Trial of the Network Performance Monitor
(NPM)
SolarWinds'
Network Performance Monitor
will help you discover what's happening on your network. This
utility will also guide you through troubleshooting; the dashboard will
indicate whether the root cause is a broken link, faulty equipment or
resource overload.
What I like best is the way NPM suggests solutions to network
problems. Its also has the ability to monitor the health of individual VMware
virtual machines. If you are interested in troubleshooting, and creating
network maps, then I recommend that you try NPM now.
This pair of examples are just like the above, but introduce slightly
more complex scripting. Example 3a contains Foreach with a ($Item in
Collection) clause; please contrast with example 3b which exploits the
ability of foreach to receive input via the pipe (|).
Note 5: This example uses the same 'If clause' as example
3a, its purpose is to filter just .txt files.
Example
4: PowerShell ForEach Loop With WMI
Once again, observe the basic structure: ForEach (x in y) {script
block}. Where you have more than one drive you need a loop, in this
case the foreach loop.
# ForEach example to display the partitions size [GB] $disk=
Get-WmiObject Win32_LogicalDisk "Drive Ltr: Size [GB]" ForEach ( $drive in $disk ) {
"Drive = " + $drive.Name + ` " Size = " + [int]($drive.Size/1073741824)}
Guy
Recommends: Free WMI Monitor for PowerShell
Windows Management Instrumentation (WMI) is one of the hidden
treasures of Microsoft's operating systems. Fortunately, SolarWinds
have created a
Free WMI Monitor so that you can discover these gems of performance
information, and thus improve your PowerShell scripts.
Take the guess work out of which WMI counters to use when scripting the
operating system, Active Directory, or Exchange Server. Give this WMI monitor a
try - it's free.
Example 4: Another Simple ForEach Using Get-Process
Here is an example using Get-Process. In essence this simple script
filters the running processes. Please feel free to modify. Once
again, note the tiny word 'in'.
# PowerShell example listing processes beginning with Task*
Clear-Host ForEach ($T in Get-Process Task*) {$T.Name}
I have not found it possible to pipe input into loops. Obtaining output was
nearly as difficult, however, I have discovered this trick to assign the output to a variable, which we can then manipulate.
$NumArray = (1..12) $(ForEach ($number in $NumArray ) { $number * 13})
| set-variable 13x $13x # Option research properties by removing # on the next line # $13x |Get-Member
I (Guy) envy /\/\o\/\/'s ability to write tight code. That % sign
means 'foreach'. If you (readers) see anything on the internet by /\/\o\/\/,
then you can be sure that it's top draw code.
For Even More Information about ForEach Loops - Check About_ForEach
The ForEach-Object cmdlet specializes in controlling loops which accept
pipeline
input. One of this cmdlet's interesting features is displaying
start and finish times. It achieves this courtesy of the -begin and -end
parameters.
Confusion: What adds to the confusion is that the
ForEach-Object cmdlet has an alias of foreach. My tip is watch out for
the use of 'in', which is used by foreach the statement, the operator, but
not by Foreach the alias for the cmdlet. The key technical difference
is the ForEach-Object does not have to be the first item in the statement,
and more importantly, it accepts | (pipelining).
Guy Recommends: SolarWinds Engineer's Toolset v10
This
Engineer's Toolset v10 provides a comprehensive console of 50 utilities
for troubleshooting computer problems. Guy says it helps me
monitor what's occurring on the network, and each tool teaches me more about how the
underlying system operates.
There are so many good gadgets; it's like having free rein of a
sweetshop. Thankfully the utilities are displayed logically: monitoring,
network discovery, diagnostic, and Cisco tools. Try the SolarWinds Engineer's Toolset now!
The secret of understanding the PowerShell foreach loop is to study the type of
bracket. For example when defining the constructions elements, (use parenthesis) for the condition and {use braces} for
the command block.
In addition to Take the time to master loops, and thus automate your repetitive tasks.
If you like this page then please share it with your friends
Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.
Windows Management Instrumentation (WMI) is
most useful for PowerShell scripting.
SolarWinds
have produced this
Free WMI Monitor to take the guess work out of which
WMI counters to use for applications like Microsoft Active Directory,
SQL or Exchange Server.