Forum Discussion

JohnBromilow's avatar
JohnBromilow
Copper Contributor
Sep 11, 2023

Help with Group-Object not working as expected

I am trying to count the number of messages stuck in quarantine for specified recipients. I can return the data fine but when I try to group it using Group-Object it returns a strange answer.

 

Here is my code:

 

 

$messages = Get-QuarantineMessage -RecipientAddress $recipients | Format-Table -Property RecipientAddress
$messages
$messages | Group-Object -Property RecipientAddress -NoElement

 

 

This returns:

As you can see the variable '$messages' contains two recipient addresses and 16 rows.

But when I pipe this through the Group-Object command it returns a blank group with a count of 20.

I am expecting Group-Object to return two rows, one for each recipient address and the count should be 11 and 5.

 

Can anyone see what is going wrong here?

 

3 Replies

  • JohnBromilow's avatar
    JohnBromilow
    Copper Contributor

    I have done some more investigation and have read that the Format-Table command can cause problems. I have modified the code as follows (removed the Format-Table command):

    $messages = Get-QuarantineMessage -RecipientAddress $recipients
    $messages | ft -Property RecipientAddress
    $messages | Group-Object -Property RecipientAddress | Format-Table -Wrap

     and the output is now

    Which is still wrong but seems to be getting closer

    • LainRobertson's avatar
      LainRobertson
      Silver Contributor

      JohnBromilow 

       

      Group-Object isn't going to help you with this - at least not unless you do some more preparation with the recipients array such as convert it to a string first. Even then - as shown below, if the recipient ordering is different for the same set of users, they won't match.

       

       

      We can see that all four inner arrays have the same people in them (which is analogous to your example), yet Group-Object isn't geared to figure that out.

       

      What we might hope for here is a count of 4 for a single group, but we get everything except that. And were I to convert the inner arrays to strings first, I'd still get two groups of 2 rather than a single group of four.

       

      Cheers,

      Lain

  • LainRobertson's avatar
    LainRobertson
    Silver Contributor

    JohnBromilow 

     

    Hi, John.

     

    Strictly speaking, there's nothing wrong and this is expected. But this will only make sense if you're familiar with .NET since Group-Object relies on the Equals() method.

     

    What you're trying to group on is an array type, and the over-simplified explanation here is that you cannot compare two arrays just by going (pseudo logic):

     

    if ($array1 -eq $array2) then ... end;

     

    Looking at this, you could be excused for thinking that the contents of $array1 is being compared to the contents of $array2. In fact, nothing of the sort is happening. The only time $array1 will equal $array2 is if you do this:

     

    $array1 = $array2;

     

    This is because we're telling $array1 to point to the same area of memory as $array2, meaning what we're actually comparing is the value of each array's pointer, not the contents of the array. This is why each row from your first table is being treated as 20 distinct rows, since where you see two recipient sets as being the same, .NET sees two unrelated sets because their pointers point to separate spots in memory.

     

    Getting back to what you're trying to achieve, while it's technically possible, it'd require more complex coding and Group-Object will be of no help in this regard.

     

    So, again, there's nothing wrong with the command. It's just not capable of doing what you are hoping it can do.

     

    Cheers,

    Lain

Resources