PowerShell 4.0 Where and ForEach Method Syntax
Introduction
Microsoft Windows PowerShell version 4.0 introduced the ability to filter an array of objects using the Where( ) method. Additionally, by using the new ForEach( ) method, you can perform a series of operations over each object within an array.
These new methods work very similarly to the Where-Object and ForEach-Object commands that have existed in PowerShell since the beginning. They merely provide an alternate syntax for PowerShell developers who are hoping to use a fluent-style syntax in their code. In some sense, the Where( ) method is similar to the Where LINQ extension method in the C# language. There doesn't seem to be a LINQ extension method that is similar to the ForEach( ) method in PowerShell version 4.0.
Where Method
The Where( ) method allows you to filter an array of objects in PowerShell, very similar to the Where-Object command.
Any time that you run a command — for instance Get-Process — and can be returned one or more objects (or $null), it's important to ensure that you are working with an array, and not a single object. If you fail to do this, then you will receive an error when trying to call the Where() method, because it only works on arrays. If it's possible for a command to return a single object, then as a best practice, you should wrap the command in @() to ensure that PowerShell treats the results as an array, even if only a single object is returned.
The Where( ) method accepts a single argument, which is a PowerShell ScriptBlock that returns a boolean value. Each object returned by the original command will be evaluated against the expression in the ScriptBlock, and based upon the result, it will either be returned or discarded. You can refer to the "current object" by using the $_ or $PSItem automatic variables.
@(Get-Process).Where({ $PSItem.Name -eq 'notepad'; });
@(Get-Process).Where({ $_.Name -match 'powershell'; });
ForEach Method
The ForEach( ) method allows you to perform an operation for each object in the PowerShell pipeline, very similar to the ForEach-Object command.
Similar to the Where( ) method, you will need to ensure that you are always working with an array of objects, when using the ForEach( ) method. To do this, wrap your command in @().
The ForEach( ) method accepts a PowerShell ScriptBlock as its parameter. This ScriptBlock is executed once for each object in the pipeline. Within this ScriptBlock, the "current object" can be referred to using the $_ or $PSItem automatic variables.
@(Get-Process -Name notepad).ForEach({ $PSItem.Kill(); });
@(Get-Service -Name wuauserv).ForEach({ $_.Stop(); });
Chaining ForEach and Where
You can use the ForEach and Where methods together in a sort of "chaining" fashion. For example, you can run a command to get an array of objects, filter the array using the Where method, and finally perform an operation against those objects using the ForEach method. Again, the concept is very similar to using the PowerShell pipeline with the Where-Object and ForEach-Object commands, but we are simply replacing the pipeline syntax with method syntax.
@(Get-Process).Where({ $PSItem.Name -eq 'notepad'; }).ForEach({ $_.Kill(); });