Let's say you have a collection of objects, and you wish to perform the same action over each object in that collection.
Seems like a ForEach job, right? Let's use this as an starting point:
$myArray = @('Here', 'are', 'some', 'things')
$myArray | ForEach-Object `
-Begin { $i = 0 } `
-Process { $i++ } `
-End { Write-Host $i }In this example, we go through each object, increment i, and finally output the value of $i to the console.
4Not particularly helpful, but it is going over each element at least. In a real-world scenario however, we probably want to do something with each value in the collection.
We can grab the value of the object using $_ :
$myArray = @('Here', 'are', 'some', 'things')
$myArray | ForEach-Object `
-Begin { Write-Host "Start!" } `
-Process { Write-Host $_ } ` -End {Write-Host "Finished!"}Start!
Here
are
some
things
Finished!Rewriting as a function
What if we wanted to do something a bit more involved than writing everything out to the screen?
We could create a function, and run it inside the Process section, passing in the parameter. Or, we could create a function that iterates through the collection itself.
Let's consider the above example, writing it as a function:
$myArray = @('Here', 'are', 'some', 'things')
function DoStuff
{
Begin { Write-Host "Start!" }
Process { Write-Host $_ }
End { Write-Host "Finished!" }
}
# Run DoStuff on every element in myArray
$myArray | DoStuffHere, we've taken the -Begin, -Process and -End arguments, and placed them inside the function. This allows us to pipe the $myArray variable simply with the function name:
$myArray | DoStuffStart!
Here
are
some
things
Finished!Of course, in this example we didn't even need the Begin and End steps. These can be omitted:
$myArray = @('Here', 'are', 'some', 'things')
function DoStuff
{
Process {
# Assume this is a long, complex method
Write-Host $_
}
}
$myArray | DoStuffHere
are
some
thingsWriting functions like this makes it much easier to iterate over them, whilst keeping the code readable.
Iterating over objects
In these examples, the object is simply a string.
If the object has properties, then we can get the property from $_:
function DoStuff
{
# Get the Name from the object only Process { Write-Host $_.Name } }
$objectA = [PSCustomObject]@{ Name = 'Here' }
$objectB = [PSCustomObject]@{ Name = 'are' }
$objectC = [PSCustomObject]@{ Name = 'some' }
$objectD = [PSCustomObject]@{ Name = 'things' }
$myArray = @($objectA, $objectB, $objectC, $objectD)
$myArray | DoStuff