Blog Post

Exchange Team Blog
4 MIN READ

Finding High Item Count Folders Using the Exchange Management Shell

The_Exchange_Team's avatar
The_Exchange_Team
Platinum Contributor
Dec 08, 2009

 

EDIT 06/18/2010: Few post changes to match the newest version of the script.

Working in Exchange Customer Service and Support, we often see cases where user performance, or overall server performance, is impacted because of a high number of items in critical folders within user's mailboxes. This issue has already been documented in multiple places, including the following articles:

Understanding the Performance Impact of High Item Counts and Restricted Views
http://technet.microsoft.com/en-us/library/cc535025.aspx

Using PFDAVAdmin to get the item count within the folders on an exchange server
http://msexchangeteam.com/archive/2007/04/24/438170.aspx

For the past few months, I have been using a simple Exchange Management Shell command to find all folders that have more than a certain number of items. The shell command is as follows:

Get-Mailbox | Get-MailboxFolderStatistics | Where {$_.ItemsInFolder -gt 5000} | Sort-Object -Property ItemsInFolder -Descending | fl Identity, ItemsInFolder

The above command finds all folders in the Organization that have more than 5,000 items, sorts them in descending order, and then gives the full Folder Path and Item Count. By modifying the Get-Mailbox portion of the command, you can target the command to obtain mailboxes from specific Servers or Databases.

Since there are different folder item limits for each version of Exchange, I thought it might be beneficial to write a script that could analyze folders on all versions, and determine if they were over their limit. The limits are as follows:

Version

Folder Item Limit

Exchange 2000/2003

5,000

Exchange 2007

20,000

Exchange 2010

100,000

It should be noted that these numbers are just the Microsoft recommended limits. Actual numbers could vary greatly depending on how many users are over the limit, the way mailboxes are being accessed (i.e. Outlook Cached Mode, Outlook Online Mode, via Mobile Phone, etc.) as well as certain 3rd party application integration.

The script is called HighItemFolders.ps1. It can be used against the entire organization, a single server, or a single database. It has the option to search all folders, or only critical folders. It can find folders above the Microsoft recommended limits, or above a specified value. And it can send the results solely to the screen, or export the results to a CSV file.

Parameters

The script has the following parameters, which are all optional:

 

-CriticalFoldersOnly: Specifies whether to check only Critical Folders, which are Calendar, Contacts, Inbox, and Sent Items, or to check all folders. Should be specified as either $true or $false. If omitted, the default value is $true.

-Database: Specifies the target database to retrieve mailboxes from. This switch overrides the -Server switch if both are used.

-DomainController: Specifies the Domain Controller to use for all mailbox and folder tests. If omitted, the default value is $null.

-FormatList: Writes output to the screen in list format instead of table format. Should be input as either $true or $false. If omitted, the default value is $false.

-ItemCount: Ignores the Microsoft recommended item limits, and finds folders with the specified item count.

-OutputFile: Specifies the file to output the results to. This should be a .CSV file.

-ResultSize: Specifies the maximum number of mailboxes to check. If omitted, the default value is unlimited.

-Server: Specifies the target Exchange server to retrieve mailboxes from.

 

Examples

Obtains all users in the organization, and checks only critical folders over the Microsoft recommended item counts:

C:\> .\HighItemFolders.ps1

Obtains all users on a specified database, checks all folders, and outputs to a CSV file:

C:\> .\HighItemFolders.ps1 -Database "e2k7-1\First Storage Group\Mailbox Database" -CriticalFoldersOnly $false -OutputFile output.csv

Obtains all users on a specific Exchange server with more than 1000 items in any folder:

C:\> .\HighItemFolders.ps1 -Server "e2k3-5" -ItemCount 1000

Output

The script always writes output to the screen. If the -OutputFile switch is used, it will write to a file in addition to the screen.

Screen Output:

CSV Output:

Script

The script can be downloaded as an attachment to this blog post, and then executed from the Exchange Management Shell.

Notes

1. In some cases, the CSV file does not separate the columns properly when opening it directly with Excel. To format the columns correctly, do the following (with Excel 2007):

  • Open Excel
  • Choose Open, and browse to the CSV file
  • Choose Delimited as the format. Hit Next
  • Use Tab as the Delimiter. Hit Finish.

2. Error detection has been included in the script to determine if any of the mailboxes reside on a database or server that is inaccessible. If so, that database or server will be skipped so we don't have a lengthy timeout for each mailbox. However, this detection only works on Exchange 2007 and higher. Exchange 2003 mailboxes still time out individually if they are inaccessible, and can cause the script to take a very long time to run.

Hope you find this useful!

- Mike Hendrickson 

Updated Apr 29, 2020
Version 3.0

20 Comments

  • Is there any reasons why the administrators have to run such a script like this? How many of you are using some .ps script to see whose mailboxes are full and send email based of that information for the users?

    Why the Exchange does not do this automatically, if this is so markable issue? Or why Outlook does not report for the user, "Your Outlook performance has been decreased because of number of the items in these folders, recommended actions:..."

    In my mind this is not the enterprise way to do work.
  • Hey Ted,
    I can't seem to reproduce this in my lab, however it looks like you are failing while trying to read the ExchangeVersion attribute on a mailbox. On one of these problem mailboxes, can you try running "Get-Mailbox MBXNAME | FL Name, ExchangeVersion"? See if anything shows up for ExchangeVersion.

    However, I think I can make this script more resilient by calling "(Get-Mailbox 2k7mbx1).ExchangeVersion.ExchangeBuild.Major" instead of using a more complicated function.

    Pax,
    Thanks for the comment. That would indeed be a good switch to add. I'll go ahead and work on that for the next update.

    Thanks!
  • Nice script. But maybe adding -domaincontroller would be great for different domains?

    My largest user-inbox has 220291 items... well... I think it's time for user-education...
  • Great script :-)

    However it generates an error message for every mailbox it finds:

    Exception calling "ToDouble" with "1" argument(s): "Input string was not in a c
    orrect format."
    At D:tedHighItemFolders.ps1:334 char:36
    +     return ([System.Convert]::ToDouble <<<< ($temp2))
       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
       + FullyQualifiedErrorId : DotNetMethodException

    The command used was:

    .HighItemFolders.ps1 -database "servernamesgnamedbname" -ItemCount 5000
  • I apologize if this is not the correct place for this question, but is there any way to intentionally corrupt a mail item in a mailbox?
    We would like to test a 3rd party tool that includes a feature to  "Skip Corrupt Items per mailbox" when moving a mailbox or exporting it to a pst file.
  • This is great, perfect timing as I am helping a client move from 2003 to 2007 now and they have quite a few folks that ar between 5000 and 20,000 items in a folder that should see better performance but some that are WAY higher that need some helping learning how to file and archive!
  • Damn, one script more to keep administrators be heavily busy for running and looking for the results. Why an earth this has not been made by more cleaver way?

    Why you have not asked Outlook team (and you for the OWA) add a feature on the client side which recognize such a problem and report valid methods to fix the problem? Or do it the same way than quota limitation check has been done,

    Why the administrators has to run the script and find such a users.
  • Awesome, can't wait to try it out!
  • Thanks for the comment Cole. I'm working on an update for the script right now. In the meantime, you are correct in that you can modify the Get-Mailbox portions of the script (there are three different Get-Mailbox commands that can be run), and append "-ResultSize Unlimited" to the end of them.

    Thanks.
  • One thing I found in running the script is that the result size is limited to the first 1000 mailboxes.  Adding the -resultsize unlimited to the get-mailbox command gets around this issue for those of us with a large number of mailboxes on one server.
    Cheers.