Exchange 2013 and Quotas

In a previous article I noted an easy way to set Quotas via PowerShell. Now, I explore reporting on quotas and mailboxes that are over the quota that was set for it. One of the attributes I look for While researching some information for this article I ran into an interesting KB article on this. KB 2819389, titles “Empty StorageLimitStatus field when you run the Get-MailboxStatistics cmdlet in an Exchange Server 2013 environment” notes the following:

Symptoms
When you run the Get-MailboxStatistics cmdlet to verify the status of a mailbox quota in a Microsoft Exchange Server 2013 environment, the StorageLimitStatus field in the results is empty.

Cause
This behavior is by design.

Unlike versions of Exchange Server Information Store earlier than Exchange Server 2013 Information Store, the Exchange Server 2013 Information Store does not cache the values of mailbox quotas. Therefore, the Information Store makes frequent calls to Active Directory to retrieve the values of mailbox quotas for each mailbox that is specified in the Get-MailboxStatistics cmdlet. Because of the frequent calls to Active Directory, you may experience poor performance in Exchange Server. To avoid poor performance in Exchange Server, the default Get-MailboxStatistics cmdlet does not retrieve the mailbox quotas and does not display a value in the StorageLimitStatus field.


So what does this tell us? Basically if you were hoping to generate a report with accurate data on the Storage Limit Status of all mailboxes in an environment, you are out of luck. A sample examination of an Exchange 2013 Server with the issue looks like this:

MissingLimits
Notice the multiple blank lines for the Storage Limit Status. What to do? How do we generate a report of these values? PowerShell.

$array = @()
$array2 = @()
$mailboxes = get-mailbox
# This section gets the mailbox size and formats it to MB
foreach ($line in $mailboxes) {
	$user = $line.alias
	$size2 = get-mailboxstatistics $user -erroraction silentlycontinue
	if ($size2 -ne $null) {
		$size = $size2.TotalItemSize.Value.ToMB() 
	}
	$array += @(,($user,$size))
}
# This section gets the Prohibit Send Receive Quota and formats it to MB
foreach ($line in $array) {
	$user = $line[0]
	$size = $line[1]
	If ($user -notmatch 'DiscoverySearch') {
		$quota2 = get-mailbox $user
		$quotapsr = $quota2.ProhibitSendReceiveQuota
		if ($quotapsr -ne "unlimited") {
			$quotapsr = $quota2.ProhibitSendReceiveQuota.Value.ToMB()
			if ($size -gt $quotapsr) {
				$quotacheckpsr = "Over"
			} else {
				$quotacheckpsr = "Under"
			}
		} else {
			$quotacheckpsr = "NoChecking"
		}
		$quotaiw = $quota2.IssueWarningQuota
		if ($quotaiw -ne "unlimited") {
			$quotaiw = $quota2.IssueWarningQuota.Value.ToMB()
			if ($size -gt $quotaiw) {
				$quotacheckiw = "Over"
			} else {
				$quotacheckiw = "Under"
			}
		} else {
			$quotacheckiw = "NoChecking"
		}
		$quotaps = $quota2.ProhibitSendQuota
		if ($quotaps -ne "unlimited") {
			$quotaps = $quota2.ProhibitSendQuota.Value.ToMB()
			if ($size -gt $quotaps) {
				$quotacheckps = "Over"
			} else {
				$quotacheckps = "Under"
			}
		} else {
			$quotacheckps = "NoChecking"
		}
		$array2 += @(,($user,$size,$quotacheckiw,$quotaiw,$quotacheckps,$quotaps,$quotacheckpsr,$quotapsr))
	}
}
# Display Over the limit for Issue Warning Quota
foreach ($line in $array2) {
	if ($line[2] -eq "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Issue Warning Quota, " -ForegroundColor red -nonewline
	} else {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "UNDER the Issue Warning Quota, " -ForegroundColor green -nonewline
	}
	if ($line[4] -eq "Over") {
		write-host "OVER the Prohibit Send Quota," -ForegroundColor red -nonewline
	} else {
		write-host "UNDER the Prohibit Send Quota," -ForegroundColor green -nonewline
	}
	if ($line[6] -eq "Over") {
		write-host " and " -nonewline
		write-host "OVER the Prohibit Send Receive Quota." -ForegroundColor red
	} else {
		write-host " and " -nonewline
		write-host "UNDER the Prohibit Send Receive Quota." -ForegroundColor green
	}
}

The resulting report should look something like this:

Notice the users who are over the Issue Warning Quota:
QuotaReport1a
Users who are over the Send Quota:
QuotaReport2
Users that are over all three quotas:
QuotaReport3
Alternatively, the script could be modified to display only those users who are over their quotas if the report needed to be simpler. Modify lines 55-76:

foreach ($line in $array2) {
	if ($line[2] -eq "Over" -and $line[4] -ne "Over" -and $line[6] -ne "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Issue Warning Quota." -ForegroundColor red
	}
	if ($line[2] -eq "Over" -and $line[4] -eq "Over" -and $line[6] -ne "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Issue Warning Quota and OVER the Prohibit Send Quota." -ForegroundColor red
	}
	if ($line[2] -eq "Over" -and $line[4] -eq "Over" -and $line[6] -eq "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Issue Warning Quota, OVER the Prohibit Send Quota and OVER the Prohibit Send Receive Quota." -ForegroundColor red
	}
	if ($line[2] -ne "Over" -and $line[4] -eq "Over" -and $line[6] -ne "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Prohibit Send Quota." -ForegroundColor red -nonewline
	}
	if ($line[2] -ne "Over" -and $line[4] -ne "Over" -and $line[6] -eq "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Prohibit Send Receive Quota." -ForegroundColor red
	}
	if ($line[2] -ne "Over" -and $line[4] -eq "Over" -and $line[6] -eq "Over") {
		write-host "The mailbox for"$line[0]"is " -nonewline
		write-host "OVER the Prohibit Send Quota and OVER the Prohibit Send Receive Quota." -ForegroundColor red
	}
}

Hope this helps someone looking for simple quota reports. There are some bugs, yellow warning messages, and red warnings that occur when I run the script. Look for an updated script in a week. Also, if your environment has over 1000 mailboxes, you may need the ‘-resultsize unlimited’ option on some commands in the script.

Advertisements

4 thoughts on “Exchange 2013 and Quotas

  1. Pingback: Intersting things i see on the internet, September 25th | 503 5.0.0 polite people say HELO
  2. Hi
    when I run the script (in 2013) I get errors below – can you help?
    Is the script downloadable?
    Thanks

    At C:\ps\size.ps1:17 char:24
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    You must provide a value expression on the right-hand side of the ‘-notmatch’ operator.
    At C:\ps\size.ps1:17 char:25
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Unexpected token ‘&’ in expression or statement.
    At C:\ps\size.ps1:17 char:25
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Missing closing ‘)’ after expression in ‘If’ statement.
    At C:\ps\size.ps1:17 char:46
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
    At C:\ps\size.ps1:14 char:27
    + foreach ($line in $array) {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\ps\size.ps1:17 char:52
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Unexpected token ‘)’ in expression or statement.
    At C:\ps\size.ps1:20 char:26
    + if ($quotapsr -ne "unlimited") {
    + ~
    You must provide a value expression on the right-hand side of the ‘-ne’ operator.
    At C:\ps\size.ps1:20 char:27
    + if ($quotapsr -ne "unlimited") {
    + ~
    Unexpected token ‘&’ in expression or statement.
    At C:\ps\size.ps1:20 char:27
    + if ($quotapsr -ne "unlimited") {
    + ~
    Missing closing ‘)’ after expression in ‘if’ statement.
    At C:\ps\size.ps1:20 char:42
    + if ($quotapsr -ne "unlimited") {
    + ~
    Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
    Not all parse errors were reported. Correct the reported errors and try again.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : ExpectedValueExpression

  3. Hi
    I get errors below:
    Can you help? Is the script downloadable?
    Thanks

    At C:\ps\size.ps1:17 char:24
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    You must provide a value expression on the right-hand side of the ‘-notmatch’ operator.
    At C:\ps\size.ps1:17 char:25
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Unexpected token ‘&’ in expression or statement.
    At C:\ps\size.ps1:17 char:25
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Missing closing ‘)’ after expression in ‘If’ statement.
    At C:\ps\size.ps1:17 char:46
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
    At C:\ps\size.ps1:14 char:27
    + foreach ($line in $array) {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\ps\size.ps1:17 char:52
    + If ($user -notmatch "DiscoverySearch") {
    + ~
    Unexpected token ‘)’ in expression or statement.
    At C:\ps\size.ps1:20 char:26
    + if ($quotapsr -ne "unlimited") {
    + ~
    You must provide a value expression on the right-hand side of the ‘-ne’ operator.
    At C:\ps\size.ps1:20 char:27
    + if ($quotapsr -ne "unlimited") {
    + ~
    Unexpected token ‘&’ in expression or statement.
    At C:\ps\size.ps1:20 char:27
    + if ($quotapsr -ne "unlimited") {
    + ~
    Missing closing ‘)’ after expression in ‘if’ statement.
    At C:\ps\size.ps1:20 char:42
    + if ($quotapsr -ne "unlimited") {
    + ~
    Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
    Not all parse errors were reported. Correct the reported errors and try again.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : ExpectedValueExpression

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s