Automating repetitive tasks is what scripting is all about. Therefore, each scripting language needs at least one method for cycling, or looping through a block of instructions.
PowerShell provides a rich variety of looping techniques. However, because loops can go spectacularly wrong, I recommend you test a simple PowerShell 'foreach' loop before graduating to more complex constructions in your production scripts.
Examples of the PowerShell Foreach Loop
The PowerShell 'Foreach' loop is more complex, and has more arguments than the 'for' and 'Do While' loops. The key feature is that loop interrogates an array, known as a collection. It then applies a {Statement Block} to each iteration. In addition to the position and the type of bracket, observe the tiny, but crucial keyword - 'in'.
The secret of PowerShell loops is to absorb each element of this syntax:
Foreach ($item in $array_collection) {command_block}.
[tab:Example 1]
Example 1: PowerShell Foreach with Pure Math
# Simple PowerShell foreach statement foreach ($number in 1,2,3,4,5,6,7,8,9,10) { $number * 7}
# PowerShell Foreach Example Clear-Host foreach ($number in 1..10 ) { $number * 7}
$NumArray = (1,2,3,4,5,6,7,8,9,10) foreach ($number in $NumArray ) { $number * 7}
foreach ($number in 1,2,3,4,5,6,7,8,9,10) { $number * 7}
$NumArray = (1..10) foreach ($number in $numArray ) { $number * 7}
Learning Points
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: (1..12) is a convenient method of representing a sequence.
[tab:Example 2]
Example 2: PowerShell Foreach to Display Files
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 script will work without modification on 99.9% of computers.
Example 2a Explicit Foreach Get-ChildItem
# PowerShell Foreach File Example Clear Host Foreach ($file in Get-Childitem C:\) { $file.name }
Example 2b - Foreach Piping | Directly Into the {block statement}
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.
# PowerShell Foreach File Example Clear Host $Path = "C:\Windows\System32\*.dll" Get-ChildItem $Path | Foreach { Write-Host $_.Name }
Learning Points
Note 3: To help modify my scripts to suit your project I have introduced a $Path variable.
[tab:Example 3]
Example 3a - A More Complex Foreach Example
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 (|).
# PowerShell foreach loop to display files in C:\Program files $Path = "C:\Program Files\" "{0,10} {1,-24} {2,-2}" -f ` " Size", "Last Accessed", "File Name " Foreach ($file in Get-Childitem $Path -recurse -force) {If ($file.extension -eq ".txt") { "{0,10} {1,-24} {2,-2}" -f ` $file.length, $file.LastAccessTime, $file.fullname } }
Example 3b - Foreach piping | directly into the {block statement}
# PowerShell foreach loop piping into block statement Clear-Host $Path = "C:\Program Files\" Get-Childitem $Path -recurse -force | Foreach { If ($_.extension -eq ".txt") { Write-Host $_.fullname } }
Note 4: This example uses the same 'If clause' as example 3a, its purpose is to filter just .txt files.
[tab:Example 4]
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.
Basic Example
$disk= Get-WmiObject Win32_LogicalDisk Foreach ( $drive in $disk ) { "Drive = " + $drive.Name}
Example Incorporating Extra Maths
# 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)}
Example 4b - 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}
[tab:Example 5]
Example 5 - Active Directory
This example conforms to the PowerShell ForEach (condition) {Code Block}; however, there is a preamble of 16 lines where the script connect to Active Directory. Moreover, the {Code Block} is spread over several lines.
N.B. Find $Dom on line 7 and change the value to that of your domain, including the extension.
# ForEach_AD.ps1 # Illustrates using PowerShell ForEach loop to interrogate AD # IMPORTANT change $Dom 'value' # Author: Guy Thomas # $Dom = 'LDAP://DC=YourDom;DC=YourExt' $Root = New-Object DirectoryServices.DirectoryEntry clear-Host # Create a selector and start searching from the Root of AD $selector = New-Object DirectoryServices.DirectorySearcher $selector.SearchRoot = $root # Filter the users with -like "CN=Person*". Note the ForEach loop $adobj= $selector.findall() ` | where {$_.properties.objectcategory -like "CN=Person*"} ForEach ($person in $adobj) { $prop=$person.properties Write-host "First name: $($prop.givenname) " ` "Surname: $($prop.sn) User: $($prop.cn)" } write-host "`nThere are $($adobj.count) users in the $($root.name) domain"
Learning Points
Note 5: ` on its own means word-wrap. `n means new line and `t means tab.
[tab:For Loop]
PowerShell For Loop (Also know as the for statement)
One use of the PowerShell 'For loop' is to iterate an array of values and then work with a subset of these values. Should you wish to cycle through all the values in your array, consider using a foreach construction.
Here is the syntax:
for (<init>; <condition>; <repeat>) {<command_block>}
Example
for ( $i = 7; $i -le 84; $i+=7 ) { $i }
[tab:Loop Trick]
PowerShell Loop Output Trick
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 * 7}) | set-variable 7x $7x # Option research properties by removing # on the next line # $7x |Get-Member
Dejan Milic's Method (Better)
$NumArray = (1..12) $7x = @() foreach ($number in $NumArray ) { $7x+=$number * 7} $7x
/\/\o\/\/'s Method (Fantastic)
$7x = 1..12 |% {$_ * 7 } $7x
[tab:END]
SOURCE | LINK | LANGUAGE | ENGLISH |