views:

76

answers:

5

Is it possible to sort the output of the Format-List cmdlet by property name?
Suppose that I have an object $x with two properties "A" and "B", and when I run Format-List with it I get

(PS) > $x | Format-List
B : value b
A : value a

I would like to have

(PS) > $x | Format-List 
A : value a
B : value b

NOTE: I should have specified from the beginning that, unlike in the example with "A" and "B" properties, the real object I have to deal with has quite a lot of properties, and new ones could be added in the future, so I don't know all the property names in advance.

A: 

I feel sure that you can achieve the desired output. I suggest that you experiment with both Sort-Object (or plain Sort) and also Group-Object (plain Group)

My idea is to place the sort, or group before | format-list

Thus $x | sort-object -property xyz | Format-List

Guy Thomas
This approach will sort the objects based on the value of property xyz but it won't sort the poperties for each individual object.
Keith Hill
+3  A: 

AFAIK, Format-List does not provide such an option.

For your particular example this should work:

$x | Select-Object A, B | Format-List

If the property set is not fixed/known then the procedure will be more tricky with use of Get-Member and some preprocessing making sorted parameter array for Select-Object.

EDIT:

Here it is (let's use $host instead of $x):

$host | Select-Object ([string[]]($host | Get-Member -MemberType Property | %{ $_.Name } | Sort-Object)) | Format-List

Christopher is right, Select-Object is not absolutely needed:

$host | Format-List ([string[]]($host | Get-Member -MemberType Property | %{ $_.Name } | Sort-Object))
Roman Kuzmin
A: 

If you are dealing with a small number of properties, you can specify their order with the -Property parameter.

Here is an example:

Format-List -Property Owner, Path

If you have a lot of properties, I am not sure there is any easy way to sort them in Format-List, like Roman said.

Christopher
+2  A: 

The closest I can think of is to create a new psobject based off the old one but with the properties sorted e.g.:

$x | %{$obj = new-object psobject; `
       $_.psobject.properties | Sort Name | `
           %{Add-Member -Inp $obj NoteProperty $_.Name $_.Value}; $obj} | fl

You could get fancier and give the new psobject a typename that matches the old one, etc.

Keith Hill
I like this solution too... +1
Paolo Tedesco
+1  A: 

This seems to work OK (edited so it accepts pipeline input):

function Format-SortedList
{
    param (
        [Parameter(ValueFromPipeline = $true)]
        [Object]$InputObject,
        [Parameter(Mandatory = $false)]
        [Switch]$Descending
    )

    process
    {
        $properties = $InputObject | Get-Member -MemberType Properties

        if ($Descending) {
            $properties = $properties | Sort-Object -Property Name -Descending
        }

        $longestName = 0
        $longestValue = 0

        $properties | ForEach-Object {
            if ($_.Name.Length -gt $longestName) {
                $longestName = $_.Name.Length
            }

            if ($InputObject."$($_.Name)".ToString().Length -gt $longestValue) {
                $longestValue = $InputObject."$($_.Name)".ToString().Length * -1
            }
        }

        Write-Host ([Environment]::NewLine)

        $properties | ForEach-Object { 
            Write-Host ("{0,$longestName} : {1,$longestValue}" -f $_.Name, $InputObject."$($_.Name)".ToString())
        }
    }
}

$Host, $MyInvocation | Format-SortedList
$Host, $MyInvocation | Format-SortedList -Descending
George Howarth