Group by Different Properties for Format-Table
For my Windows Installer PowerShell Extensions, I've been simplifying some of the use cases and adding additional formats. One thing I wanted to do was display source list information in a table and group either by the attached ProductCode or PatchCode properties. The format-table cmdlet doesn't support multiple properties and doesn't appear to allow you to condition the label. It also seemed that Display.xml, or *.formats.ps1xml files, didn't natively support grouping by multiple property names.
The help topic about_Display.xml hinted at a CustomControl tag, but examples of this and related tags in the default *.formats.ps1xml files offered little insight about their true power. With some help from a simple user-generated XML schema and some trial and error, I was able to display a label with an appropriate value conditionally, such that the following expressions displayed the partial table shown below.
PS> $packages = get-msiproductinfo | ?{ $_.Name -match "Visual Studio" }
PS> $packages += get-msipatchinfo
PS> $packages | get-msisource | format-table -view package
ProductCode: {388E4B09-3E71-4649-8921-F44A3A2954A7}
Index Type Path
----- ---- ----
0 Network m:\c0367ae0d89851da1a\
1 Network C:\Program Files\Common Files\Microsoft Shared\VSTO\8.0\Micros...
2 Network m:\3d218a0f32f61beaf41a01459217\
PatchCode: {6E52C409-0D0D-4B84-AB63-463438D4D33B}
Index Type Path
----- ---- ----
0 Network m:\ec91ccc92c8f730e8d87188036\
I accomplished this by using a scriptblock to group, but referencing a CustomControl with multiple ExpressionBinding elements as shown in the partial example below.
<Configuration>
<Controls>
<Control>
<Name>PatchOrProductGrouping</Name>
<CustomControl>
<CustomEntries>
<CustomEntry>
<CustomItem>
<Frame>
<LeftIndent>4</LeftIndent>
<CustomItem>
<ExpressionBinding>
<ItemSelectionCondition>
<ScriptBlock><![CDATA[$_.ProductCode -ne $null]]></ScriptBlock>
</ItemSelectionCondition>
<ScriptBlock><![CDATA["ProductCode: " + $_.ProductCode]]></ScriptBlock>
</ExpressionBinding>
<ExpressionBinding>
<ItemSelectionCondition>
<ScriptBlock><![CDATA[$_.PatchCode -ne $null]]></ScriptBlock>
</ItemSelectionCondition>
<ScriptBlock><![CDATA["PatchCode: " + $_.PatchCode]]></ScriptBlock>
</ExpressionBinding>
<NewLine/>
</CustomItem>
</Frame>
</CustomItem>
</CustomEntry>
</CustomEntries>
</CustomControl>
</Control>
</Controls>
<ViewDefinitions>
<View>
<Name>Package</Name>
<ViewSelectedBy>
<TypeName>Microsoft.Windows.Installer.PackageSource</TypeName>
</ViewSelectedBy>
<GroupBy>
<ScriptBlock><![CDATA[
if ($_.ProductCode -ne $null)
{
$_.ProductCode
}
elseif ($_.PatchCode -ne $null)
{
$_.PatchCode
}
]]></ScriptBlock>
<CustomControlName>PatchOrProductGrouping</CustomControlName>
</GroupBy>
<TableControl>
<!-- Omitted for brevity -->
</TableControl>
</View>
</ViewDefinitions>
</Configuration>Hopefully this serves as a good example of more powerful features of formatting in PowerShell.