By assigning temporary results into variables you are creating large arrays that must then be enumerated in the next stage of the processing. This _might_ be causing timing issues as you need to collect all the items generated thus far before continuing. I propose a longer pipeline where the collection happens at the very end when it is necessary (at group and sort time). I don't know how much speed up that will provide but it should help some.
I also noticed that you were selecting properties that were not used. I don't think this will have too much of an effect on the execution time but we might as well not select those properties as they are not used.
Get-ExchangeServer | Where-Object -Filter { $_.isHubTransportServer } |
Get-MessageTrackingLog -EventId Deliver -Start '27/07/2010 12:00:00 am' -End '27/07/2010 11:59:59 pm' -ResultSize Unlimited |
Select-Object -Property Sender, TotalBytes |
Group-Object -Property Sender |
Select-Object -Property @(
@{ Name = 'User' ; Expression = { $_.Name } },
@{ Name = 'TotalItemSize(KB)' ; Expression = { [System.Math::Round(($_.Group | Measure-Object -Property TotalBytes -Sum).Sum / 1KB, 2) } }
) | Sort-Object -Property 'TotalItemSize(KB)' -Descending |
Select-Object -First 25