arrayspowershellsortingpscustomobject

Sort an array of PSCustomObject by values of a property


I need help for my sorting issue with Powershell. What I want is simple, but I'm unable to find a solution. I do have in Powershell an array @() of PSCustomObjects like code below. First I fill the array in a loop with objects and try later to order the array. The following simple sample should demonstrate the challange.In the real world, I receive the array from another web service.

$products = @()
for ($i -eq 1; $i -lt 50; $i++){
   $code = -join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_})

   $value = [PSCustomObject]@{ }
   $value | Add-Member -MemberType NoteProperty -Name ProductId -Value $i
   $value | Add-Member -MemberType NoteProperty -Name ProductCode -Value $code
   $products += $value
}

# other try
# for ($i -eq 1; $i -lt 50; $i++){
#     $code = -join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_})
#     $value = [PSCustomObject]@{ ProductId=$i; ProductCode="$code"}
#     $products += $value
# }

Write-Host $products | Sort-Object -Property ProductCode

I expect a result like this, sorted by ProductCode:

@{ProductId=4; ProductCode=ashku} @{ProductId=1; ProductCode=Ahjju} 
@{ProductId=3; ProductCode=bBhhg} @{ProductId=2; ProductCode=qtras} 
@{ProductId=5; ProductCode=yYfgh}

Has anyone the solution for me? Thanks in advance.

Tino


Solution

  • CLARIFICATION: Write-Host doesn't send its output to the Success Stream but directly to the Host(usually the terminal) so Sort-Object receives nothing to sort.

    Original:
    As explained in the comments: the problem is Write-Host converting the elements to strings before sorting them.
    Also Write-Host is specifically used to send information to the user through the console, but it's mostly meant for strings.
    You might want to pipe the results to Format-Table or Format-List instead.

    Here a working example(with optimized production of the example code because your was really inefficient)

    $products = foreach ($i in 1..50) {
        $code = -join ((65..90) + (97..122) | Get-Random -Count 5 | ForEach-Object { [char]$_ })
        [PSCustomObject]@{ 
            ProductId   = $i
            ProductCode = $code
        }
    }
    
    $products | Sort-Object -Property ProductCode | Format-List
    

    this will return

     ProductId ProductCode
     --------- -----------
                
            36 AdmCc
            42 BhQpU
            37 BVSbw
            24 cusnH
            35 DsSrp
            27 EWokb
            30 fiuKF
             5 gBmPA
            21 gxnOe
            39 HDgyr
            48 hEwHA
             8 hHSXE
             6 HoTsJ
             3 iLMUv
            10 IWCru
            14 iySPg
            15 JgVyp
            20 JlziB
            18 jRfGo
            44 JuAcq
            33 kmZRO
            43 KZTHp
            47 lgumS
            29 lKyZg
            40 LqKFc
            28 McGjW
            16 mHvhg
            38 nGBLm
            32 nmekO
            12 NRJvw
            11 oZnRc
            23 pbMvq
             2 PLDgT
            19 PoeXl
            41 pSiDN
             7 ptUfA
            26 qxQSv
             9 rCwnE
            13 RMqFT
             1 SPJrz
            22 TDvWC
            50 UFbuM
            34 uVCIA
            49 VvflM
            25 vzpwT
            45 wPJtp
            31 WxcTk
             4 XgFIG
            17 xGrRz
            46 XRTnr