So here’s the problem: I am connected to my Exchange 2010 server via a remote PS session. I run the Get-MailboxFolderStatistics
cmdlet to get a list of the folders and their sizes for a mailbox, piping it into Format-Table to get a tabular view.
1 2 3 4 5 6 7 8 9 |
PS> Get-MailboxFolderStatistics rakhesh | ft Identity,FolderSize Identity FolderSize -------- ---------- rakhesh Top of Information Store 864 B (864 bytes) rakhesh !Info 15.08 MB (15,813,182 bytes) rakhesh Calendar 21.63 MB (22,678,811 bytes) rakhesh Contacts 6.895 KB (7,060 bytes) ... |
By default this is sorted by the folder name. I want to sort it by folder size instead, so I pipe it to the Sort-Object
cmdlet.
1 2 3 4 5 6 7 8 9 10 11 |
PS> Get-MailboxFolderStatistics rakhesh | Sort-Object -Property FolderSize | ft Identity,FolderSize Identity FolderSize -------- ---------- ... rakhesh Notes 1.366 KB (1,399 bytes) rakhesh Sync IssuesConflicts 1.684 MB (1,765,967 bytes) rakhesh Inboxx_ServicedeskLondon 1.826 MB (1,915,139 bytes) rakhesh Inboxx_ITMiddleEastSCOM Alert 12.11 MB (12,697,314 bytes) rakhesh Recoverable Items 13.79 MB (14,457,076 bytes) ... |
Not good, it is sorting by the folder size but seems to be considering it as a string and totally ignoring whether the figure is in KB or MB.
This seems to be because I am doing a remote PS session. Notice the results of Get-Member
below:
1 2 3 4 5 6 |
PS> Get-MailboxFolderStatistics rakhesh | get-member FolderSize TypeName: Deserialized.Microsoft.Exchange.Management.Tasks.MailboxFolderConfiguration Name MemberType Definition ---- ---------- ---------- FolderSize Property System.String {get;set;} |
As suspected, the type of FolderSize is string. And this is because the object is being serialized-deserialized (i.e. converted to XML) when being passed from the remote PS session to my local one. If I were to run this cmdlet within EMS on the server, Sort-Object
will work as expected, but since I am running remotely the deserialization is messing things up.
Gotta work around this.
Via a blog post on sorting I discover the Sort-Object can take expressions to define the property used for sorting. The expression can be a string – selecting the property based on which sorting happens, and whether it’s sorted ascending or descending – or it can be an expression. The latter is what we are interested in.
Try the following:
1 2 3 |
Get-MailboxFolderStatistics rakhesh | ` sort-object @{ Expression = {$tmp = $_.FolderSize -replace ".*\((.+) bytes\)","`$1"; [int]$foldersize = $tmp -replace ",",""; $foldersize }; Ascending=$false } | ` ft Identity,FolderSize |
Let’s break this down to see what I am doing here. The key bit is the code within the Expression block, so let’s focus on that:
1 2 3 |
$tmp = $_.FolderSize -replace ".*\((.+) bytes\)","`$1"; [int]$foldersize = $tmp -replace ",",""; $foldersize |
What I do is (1) define a temp variable that takes the FolderSize
property and extracts the number using a regular expression. This number is actually stored as a string, mind you, considering it has commas and all, so (2) I remove the commas and convert the number to an integer and (3) output this number – which is what gets used by Sort-Object
as the property to sort on. (If I skip outputting the number Sort-Object
ignores the Expression block).
It’s probably not a good idea to use the [int]
data type for folder size as users could have large folders and easily exceed the limit. So best to use an unsigned 64-bit integer. (Thanks to this post on the info about unsigned integers and its limits).
Putting it all together, I can finally sort the folders by size:
1 2 3 4 5 6 7 8 9 10 11 |
PS> Get-MailboxFolderStatistics rakhesh | ` sort-object @{ Expression = {$tmp = $_.FolderSize -replace ".*\((.+) bytes\)","`$1"; [uint64]$foldersize = $tmp -replace ",",""; $foldersize }; Ascending=$false } | ` ft Identity,FolderSize Identity FolderSize -------- ---------- rakhesh Deletions 154.4 MB (161,936,866 bytes) rakhesh Inbox 23.9 MB (25,064,673 bytes) rakhesh Calendar 21.63 MB (22,678,811 bytes) rakhesh !Info 15.05 MB (15,782,397 bytes) ... |
Yaay!
Update 6th July 2021: Fixed the regex thanks to a reader Youdgin.