Collecting Mailbox Counts per Database Using LDAP

Recently I have been gathering a lot of mailbox data for a customer running Exchange 2010 that is in the process of upgrading from Exchange 2007.  One of the more frequent requests has been for mailbox numbers, often broken out by database.  It’s key to know the current state of your environment, especially during an upgrade where mailboxes seem to never stop moving.  For my customer this is how we track which databases are full and keep tabs on the current mailbox load balancing procedure.

Typically you can just run a command similar to ‘Get-Mailbox –ResultSize Unlimited | group database’ to quickly see how the databases look.  However, when you have an environment with tens/hundreds of thousands of mailboxes, the Get-Mailbox command will take a long time to finish.  Sometimes it’s just not fast enough, and I saw this as a great opportunity to see just how fast I could gather a count of mailboxes per database.  After testing a few different methods (including –asjob, start-job, etc) I found the fastest method was LDAP interrogation.

The idea is pretty straight forward as every AD user with an Exchange mailbox will have a homeMDB attribute pointed to the mailbox’s database.  First, let’s pull back a list of databases and retrieve the distinguishedName of the database, then perform an LDAP query for that DN in the homeMDB attribute of the user accounts.  This is a simple example but could be adapted to different environments.  For example, in my lab I tag ‘SLA-1’ into the ‘extensionAttribute1’ attribute for all my Tier 1 SLA users.  I could modify this script to include ‘extensionAttribute1=SLA-1’ in my LDAP filter to make sure these users are all on DB1 which has more database copies than my other databases.

Disclaimer: By no means do I think this is ‘better’ than Get-Mailbox or other native commands.  In some cases, specifically when pulling a small amount of data from a large set of users, this method is simply faster.

 

Script Execution

Enough talk, let’s see the script run in a lab environment.  Between each test, I reboot the DC to flush any cached LDAP results.  Here are the details of my virtualized lab:
One Domain Controller with dynamic memory up to 3GB, 2 virtual CPU.
One Exchange 2010 SP3 (RU3) server with 4GB RAM, 2 virtual CPU.
All disks share the same set of Raid 0 disks.
~20,000 mailboxes
20,000 mail-enabled users
20 mailbox databases

As a baseline, let’s execute a typical ‘Get-Mailbox’ cmdlet.

DatabaseCountGetMBX1
Here we see the cmdlet finish in 3.9 minutes – not bad for 20,000 mailboxes.  But we can go faster!  Here’s the script in action:

DatabaseCountLDAP1

DatabaseCountLDAP2
Once it’s complete, we see that it took 16.9 seconds to run, That’s over 14x faster!

The script can be found on the Script Repository here.

Stay tuned for more PowerShell/automation scripts and tips…

Comments

  • Anonymous
    January 01, 2003
    This is pretty awesome. This will greatly simply several processes I use almost daily. Thanks.
  • Anonymous
    January 16, 2014
    You are awesome!
  • Anonymous
    February 20, 2014
    Wow, I think this guy is really on to something here, real genius at work!
  • Anonymous
    June 30, 2014
    In the first section of this two part series, I will discuss caching objects to disk in PowerShell, and