2

If I write this small function :

function Foo {
    Get-Process | % { $_ } 
} 

And if I run

Foo

It displays only a small subset of properties:

PS C:\Users\Administrator> foo

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     86      10     1680        412    31     0,02   5916 alg
    136      10     2772       2356    78     0,06   3684 atieclxx
    123       7     1780       1040    33     0,03    668 atiesrxx
...
...

But even if only 8 columns are shown, there are plenty of other properties (as foo | gm is showing).

What is causing this function to show only this 8 properties?

I'm actually trying to build a similar function that is returning complex objects from a 3rd party .Net library. The library is flatting a 2 level hierarchy of objects :

function Actual {

    $someDotnetObject.ACollectionProperty.ASecondLevelCollection | % { $_ }

}

This method is dumping the objects in a list form (one line per property).

How can I control what is displayed, keeping the actual object available?

I have tried this :

function Actual {

    $someDotnetObject.ACollectionProperty.ASecondLevelCollection | % { $_ } | format-table Property1, Property2

}

It shows in a console the expected table :

Property1  Property2
---------  ---------
     ValA       ValD
     ValB       ValE
     ValC       ValF

But I lost my objects. Running Get-Member on the result shows :

   TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

Name                                    MemberType Definition                                                                              
----                                    ---------- ----------                                                                              
Equals                                  Method     bool Equals(System.Object obj)                                                          
GetHashCode                             Method     int GetHashCode()                                                                       
GetType                                 Method     type GetType()                                                                          
ToString                                Method     string ToString()                                                                       
autosizeInfo                            Property   Microsoft.PowerShell.Commands.Internal.Format.AutosizeInfo autosizeInfo {get;set;}      
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}                            
groupingEntry                           Property   Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry groupingEntry {get;set;}    
pageFooterEntry                         Property   Microsoft.PowerShell.Commands.Internal.Format.PageFooterEntry pageFooterEntry {get;set;}
pageHeaderEntry                         Property   Microsoft.PowerShell.Commands.Internal.Format.PageHeaderEntry pageHeaderEntry {get;set;}
shapeInfo                               Property   Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo {get;set;}            


   TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData

Name                                    MemberType Definition                                                                          
----                                    ---------- ----------                                                                          
Equals                                  Method     bool Equals(System.Object obj)                                                      
GetHashCode                             Method     int GetHashCode()                                                                   
GetType                                 Method     type GetType()                                                                      
ToString                                Method     string ToString()                                                                   
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property   System.String ClassId2e4f51ef21dd47e99d3c952918aff9cd {get;}                        
groupingEntry                           Property   Microsoft.PowerShell.Commands.Internal.Format.GroupingEntry groupingEntry {get;set;}
shapeInfo                               Property   Microsoft.PowerShell.Commands.Internal.Format.ShapeInfo shapeInfo {get;set;}        

Instead of showing the 2nd level child object members. In this case, I can't pipe the result to functions waiting for this type of argument.

How does Powershell is supposed to handle such scenario?

2 Answers 2

1

This is actually controlled by format files. From powershell help about_Format.ps1xml:

The Format.ps1xml files in Windows PowerShell define the default display of objects in Windows PowerShell. You can create your own Format.ps1xml files to change the display of objects or to define default displays for new object types that you create in Windows PowerShell.

When Windows PowerShell displays an object, it uses the data in structured formatting files to determine the default display of the object. The data in the formatting files determines whether the object is rendered in a table or in a list, and it determines which properties are displayed by default.

The formatting affects the display only. It does not affect which object properties are passed down the pipeline or how they are passed.

As per your example, get-process returns System.Diagnostics.Process, which (format of output) is defined in DotNetTypes.format.ps1xml:

    <Name>process</Name>
    <ViewSelectedBy>
        <TypeName>System.Diagnostics.Process</TypeName>
    </ViewSelectedBy>
    <TableControl>
        <TableHeaders>
            <TableColumnHeader>
                <Label>Handles</Label>
                <Width>7</Width>
                <Alignment>right</Alignment>
            </TableColumnHeader>
            <TableColumnHeader>
                <Label>NPM(K)</Label>
                <Width>7</Width>
                <Alignment>right</Alignment>
            </TableColumnHeader>
(output omitted)
4
0

Try something like this:

... | ForEach-Object {
  Write-Host $_.Something
  $_
}

The trailing $_ inside the code block passes the object.

2
  • Won't this double the output? Both the property and the object itself?
    – Steve B
    Sep 4, 2012 at 15:52
  • Try $foo = ... | % { Write-Host $_.Something; $_ } or ... | % { Write-Host $_.Something; $_ } > output.txt. The output of Write-Host always goes directly to the host, it's not processed any further. Sep 4, 2012 at 15:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .