Search code examples
powershellsort-object

Need help sorting the output of a powershell function by folder/file size


(Sorry if the title isn't the best, I had no idea how to write what I meant)

Hello, I'm somewhat new to PowerShell but I wanted to create a function that I could run whenever I wanted to see the sizes of every Folder in the current directory. I found the following code which looked exactly like what I needed.. however, no matter where I place the Sort-Object it won't sort anything. I'm sure it's user error since I've never really used Sort-Object before and since I haven't found much online I decided to just ask instead.


function Print-Sizes {
    $colItems = Get-ChildItem $startFolder | Where-Object {$_.PSIsContainer -eq $true}
    foreach ($i in $colItems)
    {
    $subFolderItems = Get-ChildItem $i.FullName -recurse -force | Where-Object {$_.PSIsContainer -eq $false} | Measure-Object -property Length -sum | Select-Object Sum
    '{0:N2}' -f ($subFolderItems.sum / 1MB) + ' MB' + '     |   ' + $i.Name
    }
}

This is placed on the Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 file.

As I've somewhat mentioned, I've tried adding Sort-Items -Property Length but no matter where I insert it, it never sorts what Powershell prints.

Am looking to know what I did / am doing wrong.

Thank you in advance!


Solution

  • Since the foreach loop in your code outputs formatted strings, there are no objects with a property Length to sort on anymore.

    Assuming your variable $startFolder is defined somewhere before you call the function, I would change it into something like below

    function Print-Sizes {
        $colItems = Get-ChildItem -Path $startFolder -Directory
        # loop over the subfolders and collect objects with properties Size and Name
        $result = foreach ($folder in $colItems) {
            $size = (Get-ChildItem -Path $folder.FullName -Recurse -Force -File | 
                     Measure-Object -Property Length -Sum).Sum
            # output a custom object for each subfolder
            [PsCustomObject]@{ 
                Size = [Math]::Round($size / 1MB, 2)  # store numerical [double] values, not formatted strings
                Name = $folder.Name 
            }
        } 
        # sort on Size property
        $result | Sort-Object -Property Size
    }
    

    The output will look like

       Size Name                                     
       ---- ----                                     
      44,83 Folder1                               
     125,99 Folder2   
     277,82 Folder3           
     841,24 Folder Etcetera          
    5520,33 PowerShell  
    

    P.S. my system is Dutch, so the decimal point here is a comma