I don’t know if this is common knowledge but I only just discovered it after multiple years using ForEach-Object; it supports Begin and End script blocks as parameters.
Some details and examples below;
I’ve used Begin and End script blocks in functions I’ve created that take input from the pipeline. What they allow you to define is a block of code that runs only once; either before the first object is passed from the pipeline or after the last object is passed. They allow you to create working variables, before clean up or present data.
What I didn’t realise (though it’s pretty logical if you think about it) is that some standard PowerShell cmdlets like ForEach-Object support it too. So I can greatly simplify some of the commands I’ve used in the past.
Here’ a simple example;
gci c:\source -recurse | % -Begin {$Count=0} -Process {if ($_.Name -like "*alpha*{$Count+=1}} -End {$Count}
So what this does is look at all the files and directories under C:\source and count all the items that have “alpha” in their name. Some notes;
% is the PowerShell alias for ForEach-Object
gci is the PowerShell alias for Get-ChildItem
-Begin defines the script block that runs before the first item is processed in For-EachObject‘s pipeline. This sets the count to 0 before the first object is processed from the list of files and directories provided by gci.
-Process defines the script block that runs on each object in the pipeline. In this case it checks each object’s name and see if it matches “*alpha*”.
-End defines the script block that runs after the last object is processed in the pipeline. In this case we we output the final contents of $Count.