ForEach-Object cmdlet (alias = ForEach) acts on each object coming through the pipeline. ForEach returns a set of objects to the pipeline for further processing
This is different to the ForEach enumerator, which is your normal loop (for x in y)… The enumerator doesn’t return objects to the pipeline.
3 parameters, each is a script block
- -Begin{} things to do once (open connection etc)
- -Process{} things to do for each item on the pipeline. Can use $_ in here to represent the current object being processed. This is the default parameter, so if you don’t specify any param name, its assumed you are doing a -Process on each item
- -End{}
Within foearch, you can use semicolon to separate lines
Format options
At end of pipeline, powershell decides how to display the objects that have been output based on their type.
Display rules are defined in files in the powershell dir ( $pshome\DotNetTypes.format.ps1xml ), which defines how to format each kind of object. Important to note that the default display will not necessarily show all properties etc for an object, it just depends what has been set up in the format rules. To get a full list of properties and methods, always best to use Get-Member for discovery.
If no special rules found for an object, it uses defaults, which are:
If <5 properties, display table. If >=5, display a list.
Can override default display, e.g. to show more properties, with the following:
- Format-Table – shows columns, with property names as headings
- Format-List – shows key-value pairs
- Format-Wide
- Format-Custom
Each format option has some common features:
- choose properties to show
- group
- auto-size (e.g. for table might resize column widths based on content to be more efficient)
- alternate views
Format-Table
– when using -GroupBy , you need to sort the input first
-Wrap will wrap text for longer entries
How to know what alternate views are available? Just use the -view parameter of Format-Table, and specify a junk name. The error message will tell you the available names.
Format-Wide
Multi-column output, can specify number of columns like this
1 |
Format-Wide -Column 4 |
or use max
1 |
Format-Wide -Autosize |
Output options
Try Get-command -verb out to get a list of output options
Out-File
Outputs a file of the objects
use -NoClobber if you don’t want to overwrite exsting file.
-Append appends to the file.
Out-Gridview
Interactive graphical representation of output. Use -Passthru to enable a “ok” button, which when pressed passes the selected objects back to the pipeline, where the command /script can carry on processing things on those objects. Can use it as an object picker. -OutputMode can be multiple or single
Out-Printer
can use this to select PDF writer and generate PDFs
Tee-object
this sends output to a file whilst also passing them to the pipeline for further processing.
Parameter binding
Look at the help for a command’s parameter. It will say whether it “Accept pipeline input”. If so, it will say whether it takes it’s input by value or by property name. If it accepts both, the default is by value.
If the object coming in to a cmdlet has property names that match the parameters for the command, it automatically binds the property values to the parameters. If the object coming down the pipeline needs a new property adding (or renaming) to make it feed into the next command and have a value bound to it, you can create a custom property with the right name, e.g. below creates a property called Runtime calculated on the fly from the process start time. This could be fed into a cmdlet that takes a parameter called Runtime and the values would automatically be populated, easing chaining of cmdlets.
1 2 3 |
Get-Process | Sort cpu -Descending | select -first 10 -property ID,Name,CPU,StartTime, @{Name=“Runtime”;Expression={(Get-Date)–$_.starttime}} |