Jérôme
Jérôme

Reputation: 27027

Default sort property

Using PowerShell, I'm trying to understand the concept of default sort property.

According to this example, provided for the Sort-Object command :

PS C:\>get-childitem | sort-object

Because no properties are specified, Sort-Object uses the default sort property for objects of type file and directory, which is Name.

Is there a way to know, for any given type, which is its default sort property ?

Upvotes: 8

Views: 769

Answers (3)

nmbell
nmbell

Reputation: 611

The default sort property is defined in the types.ps1xml file (in the $PSHOME directory). From the online help for Sort-Object:

The Sort-Object cmdlet sorts objects based on properties specified in the command or the default sort properties for the object type. Default sort properties are defined using the PropertySet named DefaultKeyPropertySet in a types.ps1xml file. For more information, see about_Types.ps1xml.

You can update the DefaultKeyPropertySet value for the current session using Update-TypeData. I've provided a couple of examples below.

Note: in these examples Sort-Object is being applied before Select-Object so that sorting is applied to the objects coming out of Get-ChildItem rather than those coming out of Select-Object.

Update with command parameters

This technique only allows setting the values once per session.

# Inspect the current sort properties: not set
PS C:\Test>Get-TypeData -TypeName System.IO.FileInfo | Select-Object -ExpandProperty DefaultKeyPropertySet

# See Get-ChildItem results before a change is made: sorting on name
PS C:\Test>Get-ChildItem -File | Sort-Object | Select-Object FullName,CreationTime

FullName      CreationTime
--------      ------------
C:\Test\A.txt 18-Apr-2021 17:09:22
C:\Test\B.txt 10-Apr-2021 19:44:59
C:\Test\C.txt 31-Mar-2021 12:53:01

# Update the sort properties
PS C:\Test>Update-TypeData -TypeName 'System.IO.FileInfo' -DefaultKeyPropertySet 'CreationTime','FullName'
PS C:\Test>Get-TypeData -TypeName System.IO.FileInfo | Select-Object -ExpandProperty DefaultKeyPropertySet

ReferencedProperties     IsHidden
--------------------     --------
{CreationTime, FullName}    False

# See the results after a change is made: sorting on creation time
PS C:\Test>Get-ChildItem -File | Sort-Object | Select-Object FullName,CreationTime

FullName      CreationTime
--------      ------------
C:\Test\C.txt 31-Mar-2021 12:53:01
C:\Test\B.txt 10-Apr-2021 19:44:59
C:\Test\A.txt 18-Apr-2021 17:09:22

# Update the sort properties again: error
PS C:\Test>Update-TypeData -TypeName 'System.IO.FileInfo' -DefaultKeyPropertySet 'FullName','CreationTime'
Update-TypeData : Error in TypeData "System.IO.FileInfo": The member DefaultKeyPropertySet is already present.
At line:1 char:1
+ Update-TypeData -TypeName 'System.IO.FileInfo' -DefaultKeyPropertySet ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Update-TypeData], RuntimeException
    + FullyQualifiedErrorId : TypesDynamicUpdateException,Microsoft.PowerShell.Commands.UpdateTypeDataCommand

Update with custom xml file

This technique allows setting the values multiple times per session. With an xml file, types_test.ps1xml, containing the following:

<?xml version="1.0" encoding="utf-8" ?>
<Types>
  <Type>
    <Name>System.IO.FileInfo</Name>
    <Members>
      <MemberSet>
        <Name>PSStandardMembers</Name>
        <Members>
          <PropertySet>
            <Name>DefaultKeyPropertySet</Name>
            <ReferencedProperties>
              <Name>CreationTime</Name>
              <Name>FullName</Name>
            </ReferencedProperties>
          </PropertySet>
        </Members>
      </MemberSet>
    </Members>
  </Type>
</Types>
# Inspect the current sort properties: not set
PS C:\Test>Get-TypeData -TypeName System.IO.FileInfo | Select-Object -ExpandProperty DefaultKeyPropertySet

# See Get-ChildItem results before a change is made: sorting on name
PS C:\Test>Get-ChildItem -File | Sort-Object | Select-Object FullName,CreationTime

FullName      CreationTime
--------      ------------
C:\Test\A.txt 18-Apr-2021 17:09:22
C:\Test\B.txt 10-Apr-2021 19:44:59
C:\Test\C.txt 31-Mar-2021 12:53:01

# Update the sort properties
PS C:\Test>Update-TypeData -PrependPath 'D:\types_test.ps1xml'
PS C:\Test>Get-TypeData -TypeName System.IO.FileInfo | Select-Object -ExpandProperty DefaultKeyPropertySet

ReferencedProperties     IsHidden
--------------------     --------
{CreationTime, FullName}    False

# See the results after a change is made: sorting on creation time
PS C:\Test>Get-ChildItem -File | Sort-Object | Select-Object FullName,CreationTime

FullName      CreationTime
--------      ------------
C:\Test\C.txt 31-Mar-2021 12:53:01
C:\Test\B.txt 10-Apr-2021 19:44:59
C:\Test\A.txt 18-Apr-2021 17:09:22

# In types_test.ps1xml, switch the order of the elements under the <ReferencedProperties> tag

# Update the sort properties again: 
PS C:\Test>Update-TypeData -PrependPath 'D:\types_test.ps1xml'
PS C:\Test>Get-TypeData -TypeName System.IO.FileInfo | Select-Object -ExpandProperty DefaultKeyPropertySet

ReferencedProperties     IsHidden
--------------------     --------
{FullName, CreationTime}    False

Upvotes: 3

campbell.rw
campbell.rw

Reputation: 1386

For this question specifically, I believe the default items are defined here in the path: C:\Windows\System32\WindowsPowerShell\v1.0\FileSystem.format.ps1xml

Upvotes: 0

JPBlanc
JPBlanc

Reputation: 72640

In my understanding the default property is taken from the .ps1XML file for the predefined types. But I found nothing about that in about_Format.PS1XML

Upvotes: 1

Related Questions