Quota madness

During my MVP Summit session the other day, we talked about mailbox quotas and PowerShell a bit. We ran out of time to do a full demo of some useful oneliners around quotas, but I figure it'll be just as useful to go over the details here.

Mailbox size quotas in Exchange 2007 work just like they do in Exchange 2003 -- there are individual quota settings on each mailbox (IssueWarningQuota, ProhibitSendQuota, and ProhibitSendReceiveQuota) which are matched to the same settings available on the mailbox database holding the mailbox. There's a boolean "UseDatabaseQuotaDefaults" available on the mailbox to determine whether the mailbox database quota settings are used, or whether the mailbox quota settings are used. This is identical in both Exchange 2003 and in Exchange 2007.

For example: If I have set the mailbox database to 1gb "IssueWarningQuota" and a given mailbox to 2gb, it makes no difference that the mailbox is higher if the UseDatabaseQuotaDefaults value is set to $true on the mailbox.

Note: Setting the IssueWarningQuota (or any of the other quota values) on the mailbox does NOT toggle the UseDatabaseQuotaDefaults value on the mailbox.

So, why does this cause a problem? Well, it means you can't do a simple "show me all of the mailboxes with IssueWarningQuota set to >2gb" and get back valid results. Why not? Well, because you'd get back all of the mailboxes who have their quota set to >2gb directly on the mailbox... but you would NOT get back mailboxes who get their 2gb+ mailbox quota value by inheritance from the mailbox store value. Plus, you'd get back mailboxes where the value is set to >2gb directly on the mailbox, but which are configured to use the store value instead. Ouch!

Ok, so we need a slightly more complex one-liner to get back accurate results for this query.

Let's break it down. Here's what we need for the example above (>2gb IssueWarningQuota):

  • All of the mailboxes where the value is explicitly set to >2gb and NOT using Database Quota Defaults.
  • All of the mailboxes on any store where the store value is set to >2gb and the mailboxes on the store ARE using Database Quota Defaults.

... which translates into a one-liner like this:

Get-Mailbox -ResultSize unlimited | where { ( ( $_.IssueWarningQuota -gt 2gb -and $_.UseDatabaseQuotaDefaults -eq $false) -or ( ( Get-MailboxDatabase $_.Database).IssueWarningQuota -gt 2gb -and $_.UseDatabaseQuotaDefaults -eq $true ) ) }

As usual, let's run through what we're doing here:

  1. Get all the mailbox objects (-ResultSize unlimited to make sure we get them all!)
  2. Client-side filter on the two parts of our query listed above
    • Is IssueWarningQuota from each mailbox >2gb and we're not using the database value?
    • Is the IssueWarningQuota value from each mailbox's listed database set to >2gb and we ARE using the database value as the mailbox quota?

Pretty straight-forward logic... and I hope it's useful to you!