Powershell format-table or select-object only show top results

15.5k views Asked by At

I am trying to find users that have been sending the most emails. But in the end I only want to display the top 10 (or n number) of senders. Is there a way to only show the top results using select-object or format-table

$Messages = Get-ExchangeServer * | where{$_.ServerRole -eq "HubTransport"} | %{get-messagetrackinglog -server $_.name -EventID "SEND" -Start (get-date -format G).AddDays(-1) -ResultSize unlimited}) 2>&1 | out-null

$messages | where{$_.sender -like "*@OurDomain.com*"} | select sender | group sender | sort count -Descending | ft count,name

Is there a way to make this only display the top results?

The only way I can think of would be storing them in a variable and outputting them in a for loop

2

There are 2 answers

0
Eris On BEST ANSWER

Before the ft, add:

select -first 10

Replacing the 10 with how many you want.

So the full command would be:

$messages | where{$_.sender -like "*@OurDomain.com*"} | select sender | group sender | sort count -Descending | select -first 10 | ft count,name
0
user2736738 On

This is asked a long time ago. But I got surprised by one thing, that you were using select and didn't look at this thing. Well in case you are thinking this is a rude answer - no it won't be. The point is you were this close to the solution. So few days back (by the way I don't know powershell much) I was asked this question and I had to display things only the first few. So the first thing I did was get-help *display* thinking that it would somehow show me something which would let me display some stuff. I was wrong, and realized I need to look for something. Then I look for the action words or the verbs. I checked get-Verb and then I could see the verbs that are relevant.

And I found select. It sounds reasonable, and then I opened help for select. get-help select -ShowWindow. And I checked the parameters and found this


    -First <Int32>
        Gets only the specified number of objects. Enter the number of objects to get.

        Required?                    false
        Position?                    named
        Default value                False
        Accept pipeline input?       False
        Accept wildcard characters?  false

And that's it. I don't know anything about power shell but I guess this can still be found with some workout like this.

For you, you knew that it would be select so you could have easily checked the parameters to solve it. In fact even the examples on how to do stuff is helpful. For example right after discovering First I got this example which made me clear about the syntax.

PS C:\>Get-Process | Sort-Object -Property WS | Select-Object -Last 5 

    Handles  NPM(K)    PM(K)      WS(K) VS(M)   CPU(s)     Id ProcessName
    -------  ------    -----      ----- -----   ------     -- -----------
    2866     320       33432      45764   203   222.41   1292 svchost
    577      17        23676      50516   265    50.58   4388 WINWORD
    826      11        75448      76712   188    19.77   3780 Ps
    1367     14        73152      88736   216    61.69    676 Ps
    1612     44        66080      92780   380   900.59   6132 INFOPATH

Yes this can be first as well and I did that and got the result.

PS C:\WINDOWS\system32> Get-Process | Sort-Object -Property WS | Select-Object -First 5

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
      0       0       60          8                 0   0 Idle
    841      39    22988          8       0.69   2540   3 SystemSettings
    538      38    17900         36       0.97  12636   3 WinStore.App
    452      29    16568         44       0.81  25724   3 Video.UI
    181      11     1800        832       0.08   6544   0 GoogleCrashHandler

Note: The previous answer is awesome and showed everything that the OP needed. I am just showing my way of solving the same thing.