Let’s say I have the results of a call to Select-String in a variable $mat, parsing a regular expression from file contents:
$mat = cat errors.txt | Select-String "'(?<code>\w+)'.+ID (?<id>[^:]+)"
According to the output of $mat | Get-Member the result contains a Matches property of type Match[].
When I execute the following I get all the matches of my regular expression output:
PS > $mat | Select-Object -Property Matches
Matches
-------
{'ACCFWD', ID 16}
{'EQASIAN', ID 448}
Why doesn’t this next block of code using foreach to select the Matches have the same output:
PS > $mat | ForEach { $_.Matches }
Groups : {'ACCFWD', ID 16, ACCFWD, 16}
Success : True
Captures : {'ACCFWD', ID 16}
Index : 20
Length : 15
Value : 'ACCFWD', ID 16
Groups : {'EQASIAN', ID 448, EQASIAN, 448}
Success : True
Captures : {'EQASIAN', ID 448}
Index : 20
Length : 17
Value : 'EQASIAN', ID 448
When displaying properties, PowerShell auto-formats the properties of types that do not have a display format defined in a
*.format.ps1xmlfile as a table for up to 4 properties. 5 or more properties displays as a list. When you select the Matches property withSelect-Object, you are selecting a single property of theMicrosoft.PowerShell.Commands.MatchInfoobject. WithForeach-Objectyou are displaying all of the properties for aSystem.Text.RegularExpressions.Matchobject.Using
Select-Object -ExpandProperty Matcheswill cause the output to look the same as theForeachbecause it will outputRegularExpressions.Matchobjects.If you place
Get-Memberafter both of your examples that produce output you will see that they output different types of objects.Edit: Here is an explanation of the formatting that happens for each command.
The output of
Select-Stringis aMicrosoft.PowerShell.Commands.MatchInfoobject which has 8 properties. These properties are not displayed by default because the display format forMatchInfois defined inPowerShellCore.format.ps1xmlto show the result ofMatchInfo‘sToString()method.In this case, the output of
Select-Objectis a customSelected.Microsoft.PowerShell.Commands.MatchInfoobject with theMatchesproperty that was copied from theMatchInfoobject. Since there is no default display format defined for theSelected.Microsoft.PowerShell.Commands.MatchInfotype, PowerShell auto formats it as a table since it has less than 5 properties (In this caseMatchesis the only property).In the
Foreach-ObjectScriptBlock, theMatchesproperty of theMatchInfoobject is being output. TheMatchesproperty is aSystem.Text.RegularExpressions.Matchwhich has 6 properties. Since there is no default display format defined for theSystem.Text.RegularExpressions.Matchtype, theMatchobjects are displayed as a list because there are more than 4 properties.