Question Details

No question body available.

Tags

powershell sorting filesystems powershell-core

Answers (2)

May 4, 2026 Score: 0 Rep: 67,139 Quality: Medium Completeness: 60%

Sort-Object is doing what is expected, sorts the strings lexicographically, meaning that it compares the strings character-by-character from left to right alphabetically. Their length is only taken into account when one of the strings is a suffix of the other.

What you can do to get the expected output is sort them by their .Length:

$data = @' MassiveAttack MassiveAttack/Collected MassiveAttack&MadProfessor MassiveAttack&MadProfessor/NoProtection MassiveAttack/Mezzanine MassiveAttack/Protection '@ -split '\r?\n'

$data | Sort-Object { $.Length }

And, if you want to be extra careful, by .Length first then lexicographically:

$data | Sort-Object { $.Length }, { $ }

Which will be useful in cases like this one, where Collected should've come before Mezzanine for example:

$data = @' MassiveAttack/Protection MassiveAttack/Mezzanine MassiveAttack&MadProfessor MassiveAttack MassiveAttack/Collected MassiveAttack&MadProfessor/NoProtection '@ -split '\r?\n'

$data | Sort-Object { $.Length }

MassiveAttack

MassiveAttack/Mezzanine

MassiveAttack/Collected

etc...

$data | Sort-Object { $.Length }, { $ }

MassiveAttack

MassiveAttack/Collected

MassiveAttack/Mezzanine

etc..

Another trick that should work is to add left padding to all strings so they have the same length, this isn't particularly recommended and is more sort of a hack that works because we know all the strings have length lower than 100... It isn't recommended for big data sets because it has to create new strings which is expensive and consumes more memory.

$data | Sort-Object { $_.PadLeft(100) }
May 4, 2026 Score: 0 Rep: 401 Quality: Low Completeness: 40%

You can do your own recursion, returning the objects in the order you require:

Function Get-ChildDirRecurse {
[CmdletBinding()]
Param([Parameter(ValueFromPipeline=$true)]$Path)
    Process {
        $Path | Get-ChildItem -Directory | ForEach-Object {
            $
            $ | Get-ChildDirRecurse
        }
    }
}

$tree = Get-ChildDirRecurse -Path "/Music" | Select-Object -ExpandProperty FullName $tree