Exchange Rules Quotas

Over the years, some Exchange users have learned the hard way that there is a limit to how many mailbox rules they can define.  The limit is based upon the cumulative size of all the rules associated with a mailbox, rather than the number of rules.  Under Exchange 2003, mailbox rules were capped at 32KB.  With Exchange 2007, that cap has doubled to 64KB, which generally translates to about 100-150 rules, depending upon how big they are (even the size of the rule name counts towards this).  You know you’ve hit that cap when Outlook gives you an error such as the following:

One or more rules could not be uploaded to Exchange server and have been deactivated. This could be because some of the parameters are not supported or there is insufficient space to store all your rules.

So, what is an Exchange user to do when confronted by this? There are two things to try:

  1. First, try to reduce the total size of your rules. This Microsoft KnowledgeBase article provides excellent tips on how to do so.
  2. If that doesn’t do the trick, contact your friendly neighborhood Exchange administrator (for AEMS users, that means going through the Help Desk) and ask him/her to bump up your rules quota. That’s right, Exchange 2007 added the ability for Exchange administrators to modify this quota on a per-user basis*.

“So,” I hear you cry, “given the availability of the second option, why should I bother with the first?”

That is a perfectly valid question, and one for which I can offer an equally valid response: efficiency.  The more mailbox rules you have, the more processing each message in your mailbox must endure. The more rules you have, the more processing and memory overhead is incurred.  Individually, it doesn’t amount to much, but aggregated over thousands of users, it can mean a noticable impact on performance.  Besides, if you have enough rules that you bump into your rules quota, odds are that there is a way to accomplish what you are trying to do more efficiently.

While we are on the subject of server performance, there are two other things that I should point out that can impact performance, not just for you, but for all users on your server:

  1. Don’t keep to many items in your Inbox.  Delete them or file them into another folder. Having many thousands of items in your inbox will seriously degrade server performance.  Keep the Inbox (and all of the other “default” folders in your mailbox) as lean as you practically can.  This is basic mailbox hygiene.
  2. If you use an Outlook add-in and notice that it seems to slow down your connectivity to the server, please remove it. Odds are that it is impacting the experience of other users as well.  I’ve seen Exchange servers brought to their knees by misbehaving Outlook add-ins. It isn’t pretty.

* A note for other Exchange administrators who might be reading this: You might be wondering how to go about changing the rules quota.  It is quite simple, really:

Set-Mailbox someuser -RulesQuota:128KB

Transition Path to Exchange 2010

Ever since I first learned a few months ago that Exchange 2010 will not support Single Copy Clusters (a high-availability model which has served us quite well to date), I’ve been scheming to figure out ways to transition to 2010 in a way that impacts end-users as little as possible, a task made more difficult by the lack of information about upgrade paths which has come out of Microsoft to date. I had even come up with an elaborate transition model built around Standby Continuous Replication (SCR) which would have made the transition almost transparent to end-users, provided that Exchange 2010 supports in-place upgrades from 2007, or that an Exchange 2010 mailbox server can serve as an SCR target for Exchange 2007. Alas, a new webcast from Microsoft has dashed those hopes, as both of those options are explicitly excluded from officially supported upgrade paths.

The Exchange engineers really dropped the ball on this one. Allowing an Exchange 2010 mailbox server to be an SCR target for 2007 would make transitioning quite painless.  Alas, it is not meant to be. (Of course, I understand WHY they couldn’t do this.  Exchange 2010 marks the first time that the ESE database schema for mailbox storage has been changed substantially since the introduction of Exchange. Thus, the 2007 and 2010 mailbox stores are incompatible, so it would do no good to replicate a 2007 database to a 2010 server unless some sort of database format conversion could be done on the fly.)

The supported transition path involves building new Exchange 2010 servers and performing move-mailbox operations on each mailbox, which, fortunately for us, is an easily scripted operation with PowerShell. There is one bright side to this.  Exchange 2010 introduces the concept of “Online Move Mailbox.” In previous versions of Exchange, the move-mailbox operation rendered a mailbox unavailable for the duration of the move operation.  With this enhancement, the mailbox remains continuously available except for a brief interruption when access is handed off from the source server to the destination server.  This online move mailbox feature is supported for moves from Exchange 2007 SP2 (a forthcoming service pack) to Exchange 2010.

Auto-Accept Bug

One nice feature of Exchange 2007 is the introduction of specific mailbox types, especially room resource mailboxes, which we create manually on AEMS at the request of departments outside of the EID system (since the associated Active Directory account is disabled for resource mailboxes).  Resource mailboxes can be configured to automatically accept meeting requests, and, if configured with the “AllowConflicts” parameter set to “$true”, can automatically accept conflicting appointments.  This can be handy for group out-of-office or vacation calendars.

Unfortunately, when a recurring item is submitted to such a calendar, specific instances which conflict with other items are declined, despite “AllowConflicts” being enabled.  According to Microsoft, this bug is by design. The only workaround is to create discrete one-time items, or to create a single event which spans multiple days.

AutoDiscover, AutoConfiguration, and Availability Service

With the combination of Outlook 2007 and Exchange 2007, several new services have been introduced which are designed to simplify the end-user experience, although there are “gotchas” to be aware of. These features are called AutoDiscover, AutoConfigure, and the Availability Service.  The latter two are built around the first.

AutoDiscover is an XML-based service used by the client to locate and connect to other web-based Exchange services, including AutoConfigure, Availability Service, and Exchange Web Services (a new API for programmatically accessing Exchange).  The client (which can be Outlook 2007, Windows Mobile, the upcoming Entourage EWS, or an EWS-based program or script) passes the user’s e-mail address and credentials to the AutoDiscover service as a SOAP query (after first checking to see if the desired information is available in Active Directory). If the credentials are valid, and depending upon the type of request, AutoDiscover will pass back a SOAP response with the requested information, such as what server the client should be configured to point to, the URL for downloading the Offline Address Book, the URL for Exchange Web Services, or the URL for the Availability Service.

AutoConfiguration is an Outlook 2007 feature which uses the AutoDiscover service to configure the Outlook profile (if the user chooses not to configure their profile manually).  There are several caveats to be aware of:

  1. By default, AutoConfiguration will set the Outlook profile to cached mode, which we don’t generally recommend for our clients.  Cached mode and been known to cause major problems such as inconsistent views of shared calendars and mailbox data loss due to corruption of the OST.
  2. The upcoming Entourage EWS (which is currently in beta) adds autoconfiguration functionality, but returns the name of a specific domain controller for the directory server (rather than the directory.austin.utexas.edu NetScaler alias).  This is problematic for off-campus users, as the DCs are not routed off-campus.
  3. When attempting to perform an autoconfiguration, the client will parse the e-mail address provided by the user and use that to construct an address to query for the AutoDiscover server (assuming that it cannot pull this info from the Service Connection Point in Active Directory).  For example, for username@mydomain.com, the client will look for the AutoDiscover service at autodiscover.mydomain.com. However, suppose that the mydomain.com Exchange server is hosting another SMTP address space, such as for an acquired company.  In this example, the user’s e-mail address is username@otherdomain.com.  The client will look for the AutoDiscover info at autodiscover.otherdomain.com.  For this scenario, either the user should  specify a “mydomain.com” address, or the network admins should add a CNAME entry to DNS pointing autodiscover.otherdomain.com to autodiscover.mydomain.com.

The Availability Service is a SOAP/XML mechanism by which Outlook 2007 retrieves free/busy information from the Exchange server.  The client uses the AutoDiscover service to locate the SOAP URL for the Availability Service, then uses SOAP queries to pull the relevant free/busy information.  This is all well and good except for one fundamental design flaw in Outlook 2007.  For authenticating against the Availability Service, Outlook uses the credentials that were used to login to the workstation, not those provided for mailbox access.  This is problematic for client systems which are not joined to the domain.  The only workaround is to join the client to the domain.  For off-site usage, this generally requires using a VPN service to join the system to the domain and to authenticate, even though the Availability Service itself simply uses web protocols.

Enumerating Sharing Permissions via EWS Managed API in PowerShell

The following PowerShell script enumerates the sharing DACLS on the Inbox and Calendar of the user under whom the script is running.  I’ve not yet attempted to enumerate the permissions for a different user. I included the “$perms[$i].UserID | fl *” line to illustrate why I use an IF-THEN construct.  The default permission throws an odd wrinkle into the mix.


#---------------------------------- ews_get_perms.ps1 ------------------------
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)

$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$uri=[system.URI] " https://YOUR.EWS.FQDN/ews/exchange.asmx"
$service.Url = $uri

$inbox= [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

$perms = $inbox.permissions

"`nPermissions on Inbox:"

for ($i=0;$i -le ($perms.Count - 1);$i++) {
if ($perms[$i].UserId.DisplayName -eq $null) {$user=$perms[$i].UserId.StandardUser}
Else {$user=$perms[$i].UserId.DisplayName}
$perms[$i].UserID |fl *
"User : $user"
"CanCreateItems : $($perms[$i].CanCreateItems)"
"CanCreateSubFolder : $($perms[$i].CanCreateSubFolders)"
"IsFolderOwner : $($perms[$i].IsFolderOwner)"
"IsFolderVisible : $($perms[$i].IsFolderVisible)"
"IsFolderContact : $($perms[$i].IsFolderContact)"
"EditItems : $($perms[$i].EditItems)"
"DeleteItems : $($perms[$i].DeleteItems)"
"ReadItems : $($perms[$i].ReadItems)"
"PermissionLevel : $($perms[$i].PermissionLevel)"
"DisplayPermissionLevel : $($perms[$i].DisplayPermissionLevel)"
"-----------------------------------------------"
}

$cal=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar)

$perms = $cal.permissions

"`nPermissions on Calendar:"

for ($i=0;$i -le ($perms.Count - 1);$i++) {
if ($perms[$i].UserId.DisplayName -eq $null) {$user=$perms[$i].UserId.StandardUser}
Else {$user=$perms[$i].UserId.DisplayName}
$perms[$i].UserID | fl *
"User : $user"
"CanCreateItems : $($perms[$i].CanCreateItems)"
"CanCreateSubFolder : $($perms[$i].CanCreateSubFolders)"
"IsFolderOwner : $($perms[$i].IsFolderOwner)"
"IsFolderVisible : $($perms[$i].IsFolderVisible)"
"IsFolderContact : $($perms[$i].IsFolderContact)"
"EditItems : $($perms[$i].EditItems)"
"DeleteItems : $($perms[$i].DeleteItems)"
"ReadItems : $($perms[$i].ReadItems)"
"PermissionLevel : $($perms[$i].PermissionLevel)"
"DisplayPermissionLevel : $($perms[$i].DisplayPermissionLevel)"
"-----------------------------------------------"

Misleading NDR Notifications

Background: About a month ago, we ran into a peculiar situation where store.exe on one of our mailbox servers was repeatedly crashing, with Event ID 9673 being generated in the Application Event Log from MSExchangeIS.  Per KnowledgeBase article 959135, the appropriate fix for this was to apply the recently-released Rollup 7 for Exchange 2007 SP1.  That didn’t fix the issue, but instead the crash rate increased.  After a marathon consultation with Microsoft Premier Support, we discovered that, in addition to the installation of the rollup, it was necessary to create a registry key called “Search Folder Nesting Level” in HKLM\System\CCS\Services\MSExchangeIS\ParamtersSystem and set it to a value of 10 (down from its default value of 20). At the time of the incident, the need for this registry setting was not yet mentioned in the KB article.

Continue reading

Using the EWS Managed API via PowerShell

As part of the rollout of the Exchange 2010 beta, Microsoft has released a beta API library for working with Exchange Web Services which can also be used in conjunction with an Exchange 2007 server. As with any .NET library, this can be invoked from PowerShell. There is an example here of retrieving the number of unread messages in the Inbox, as well as some attributes from the last message received. Unfortunately, the API documentation doesn’t give PowerShell examples, so figuring out how to invoke the calls requires a bit of trial and error. Here is a script I cobbled together which simply sends an email message:
Continue reading

Fun With Custom PSObjects

I was recently asked to generate a report on mailbox usage by a specific subset of AEMS users.  The tricky part is that the various pieces of info that I need are returned by two distinct Exchange Management Shell commands.  In order to merge properties from two different returned objects, I found it expedient to tack the values from those properties into a new PSObject:

#initializing an array to hold the constructed PSObjects
[array]$users = $null          

#  iterate through all members of myGroup
Get-DistributionGroupMember “myGroup” | ForEach-Object {    
# some info needed from Get-Mailbox
$mb=get-mailbox  $_.samaccountname    
# some from Get-MailboxStatistics
$mbstats = get-mailboxstatistics $_.samaccountname   

# create PSObject into which we will merge results
$user = New-Object PSObject   

# Now we add the desired properties into the PSObject
$user | Add-Member NoteProperty Name $mb.DisplayName
$user | Add-Member NoteProperty Usage $mbstats.TotalItemSize.Value.ToMB() 
$user | Add-Member NoteProperty Quota $mb.ProhibitSendQuota
$user | Add-Member NoteProperty Account $mb.SamAccountName 

# skipping users for whom no data is returned because they’ve never logged in
if ($mb.DisplayName -ne $NULL){$users += $user}

}

# Now, export the report as a CSV file:
$users | export-csv -path .\myGroup-Users.csv