In order to sort dictionary (hashtable) an explicit GetEnumerator is required. For example:
> $a = @{a=1;b=2;c=3;d=4}
> $a|sort Name
Name Value
---- -----
c 3
d 4
b 2
a 1
(doesn't work)
> $a.GetEnumerator()|sort Name
Name Value
---- -----
a 1
b 2
c 3
d 4
(works fine)
Make a change so that
> $a|sort Name
works as expected. Current behavior benefits nobody.
While it may be surprising, [hashtable] instances have always been treated as a _single object_ in the pipeline, and changing that now would be a massively breaking change.
Think of [hashtable] instances as _single objects_, whose _properties_ (hashtable entries) you wouldn't expect to be enumerated in the pipeline either.
At first it's really surprising and confusing. Then it starts to make sense. However maybe there should be friendlier way than using a method which is very rarely used even by .NET developers.
I agree that it's not obvious, but the need for it is too rare to warrant a dedicated operator for it in PowerShell, I think.
Note that your specific scenario is at least explicitly documented in the conceptual about_Hash_Tables topic.
Also note that, as stated in the linked topic, you're not sorting the hashtable itself (which is impossible); instead, you're outputting a sorted array of key-value pairs.
P.S.: A simple alternative is to cast to System.Collections.SortedList:
PS> $ht = @{ zz = 1; gg = 2; aa = 3 }; [System.Collections.SortedList] $ht
Name Value
---- -----
aa 3
gg 2
zz 1
Most helpful comment
While it may be surprising,
[hashtable]instances have always been treated as a _single object_ in the pipeline, and changing that now would be a massively breaking change.Think of
[hashtable]instances as _single objects_, whose _properties_ (hashtable entries) you wouldn't expect to be enumerated in the pipeline either.