A colleague asked me if I had any script in my repository that will create him a detailed report of users, mailboxes and their quota limits. I didn’t have one, so I told him I’d write it for him.
The first thing that came into my mind was the Get-MailboxStatistics PowerShell cmdlet. But then he said that the environment he needed the script for, was a Windows 2003 Domain with Exchange 2003. So I decided I’d do it VBS style.
The details he needed for the report were not only from the Exchange Mailbox but also from the Active Directory:
|Property||Where to get it from|
|Account Name||Active Directory: samAccountName|
|User Principal Name||Active Directory: userPrincipalName|
|Display Name||Active Directory: displayName|
|Email Address||Active Directory: mail|
|Issue Warning||Active Directory: mDBStorageQuota *|
|Prohibit Send||Active Directory: mDBOverQuotaLimit *|
|Prohibit Send and Receive||Active Directory: mDBOverHardQuotaLimit *|
|Limit Status||Exchange: StorageLimitInfo|
|Mailbox Size||Exchange: Size|
|Total Items||Exchange: TotalItems|
|Mailbox Location||Exchange: ServerName + StorageGroupName + StoreName|
For each server, a WMI query to the Exchange_Mailbox Class under the /root/MicrosoftExchangeV2 namespace to get the StorageLimitInfo, Size, TotalItems, ServerName, StorageGroupName, StoreName and the MailboxDisplayName.
And for each mailbox, query the Active Directory for the additional required details (samAccountName, userPrincipalName, displayName, mail, mDBStorageQuota, mDBOverQuotaLimit and the mDBOverHardQuotaLimit). I used the legacyExchangeDN to match the mailbox to the user account in Active Directory.
(&(ObjectClass=user)(ObjectCategory=person)(legacyExchangeDN=” & legacyExchangeDN & “))
* But then, It got to me that the user may not have specific quota limits set to his user in the Active Directory, and that those settings would be inherited from the mailbox store.
So I added an ADSI query to get the information from the Mailbox Stores,
and put the needed values (mDBStorageQuota, mDBOverQuotaLimit and mDBOverHardQuotaLimit) into to a key-paired Dictionary Object (like a Hashtable). Then, when a user had the mDBUseDefaults set to true, I’d pull the information from the dictionary using his homeMDB property. Actually what I used was the value of:
GetObject(“LDAP://” & oRs.Fields(“homeMDB”)).cn
After a few dry runs, I came across mailboxes that failed to be fully reported. I did some debugging (wscript.echo this and wscript.echo that), and noted that I forgot to handle disconnected mailboxes. So by checking if the DateDiscoveredAbsentInDS property had a value I was able to separate the “connected” from the “disconnected” mailboxes.
The script could still be tweaked for better performance and could use a bit more of logging, but I think it’s good enough to share here and definitely meets my colleague needs.
Just remember to run it using the cscript engine:
cscript //NoLogo ExchMailBoxStats.vbs
- You will need administrative rights on the Exchange Server to connect to it using WMI.
- The CSV report will be created in the format of ExchMailBoxStats.yyyyMMdd.csv and located on the same folder as the ExchMailBoxStats.vbs is on.