Unfortunately, as of PowerShell 7.2.x, arrays do not sort meaningfully as-is, unless they happen to be composed of strings only.
The reason is that [array] instances are in effect compared by their PowerShell-specific stringification, which is the space-concatenated list of their stringified elements.
Workaround for [int[]] arrays of arbitrary length:[1]
# -> '<100 42>', '<99 42>' - note the -Descending
(99, 42), (100, 42) |
Sort-Object -Descending { $_.ForEach({ '{0,11}' -f $_ }) } |
ForEach-Object { "<$_>" }
The above converts each number in each input array to a left-space-padded string of fixed length (based on the max. length of an [int] value expressed as a string[2]), which in effect converts each input array to a string array whose lexical sorting then equals how numerical sorting would work based on the original array's elements, based on PowerShell's array stringification.
Workaround for arrays of up to 8 elements:
Array-like types that (also) implement the System.IComparable interface, such as tuples (System.Tuple) and value tuples (System.ValueTuple), are compared via that interface by Sort-Object. This is what the workaround that Santiago Squarzon suggests in his comment on the question relies on; while there is a way not to have to enumerate the array elements one by one, the workaround is limited to arrays with at most 8 elements, based on the constructor overloads available:
# Works for arrays of up to 8 elements.
# -> '<1 2 3 4 5 6 7 10>', '<1 2 3 4 5 6 7 9>'
(1..7 + 9), (1..7 + 10) |
Sort-Object -Descending { [ValueTuple]::Create.Invoke($_) } |
ForEach-Object { "<$_>" }
Potential future improvement:
As of PowerShell 7.2.x, only input objects that implement the System.IComparable interface are compared via that interface, (unfortunately) not also collection objects that (only) implement the System.Collections.IStructuralComparable interface, such as .NET arrays (although many other array-like collection types do not).
GitHub issue #18389 requests that Sort-Object honor input objects whose types implement (only) System.Collections.IStructuralComparable too.
[1] Strictly speaking, a PowerShell array literal such as 99, 42 is an [object[]] array whose elements happen to be [int] instances. Similarly, the collection type that the intrinsic .ForEach() method emits is an array-like collection of type [System.Collections.ObjectModel.Collection[psobject]], but in terms of PowerShell stringification it behaves the same as an array.
[2] Verify with "$([int]::MinValue)".Length, which yields 11. See also: -f, the format operator
((101,43),(101,42),(99,42),(100,42)) | Sort-Object { $_[0] }, { $_[1] } | ForEach-Object { "[$_]" }. A Tuple would also work((101,43),(101,42),(99,42),(100,42)) | Sort-Object { [Tuple]::Create($_[0], $_[1]) } | ForEach-Object { "[$_]" }