Recently I had the opportunity to dig into an interesting failure with the Exchange Legacy Backup API (ESEBCLI2.DLL). A backup vendor was seeing a reproducible error when they tried to remotely backup certain Exchange servers from their backup software when running on Windows Server 2008. They found that their call to HrESEBackupReadFile was returning 0xC7FF1004 instead of the expected S_OK but they could not figure out why.
Let me start by pointing out that the Legacy Backup API is a technology that is on its way out. Exchange 2010 no longer supports legacy API backups, and there are many caveats to using the API against Exchange 2007. With all that said up front, there are still quite a few backup applications that make use of this interface.
At its core, the legacy backup API uses Remote Procedure Calls to connect to the Exchange server and control the flow of backups and restores. When you actually go to read a file, it does something a bit different though. Instead of trying to package the data up and deliver it via returns to RPCs, the server actually creates a TCP socket connection back to the Backup Client.
If something prevents the return socket connection, such as the Windows Firewall, Network Address Translation or an External Firewall, you will receive the 0xC7FF1004 result code when you call HrESEBackupReadFile. In this particular case, we ruled out all of these “external” factors, but still were seeing the error. Furthermore, looking at a Netmon trace of the issue showed that the server was never even attempting (on the wire at least) to connect back to the client.
The mechanism by which this return socket connection is established relies on an address that is provided by the client. This would seem to be a valid process, but the introduction of changes to support IPv6 in Exchange Server 2007 SP1, and the inclusion of an IPv6 aware network stack on Windows Server 2008 collided to induce a failure.
The simplified sequence of events is:
From here, you will see an Event logged in the Exchange Server’s Application Log that reads:
Source: ESE BACKUP Event ID: 909 Description: Information Store (PID) Backup data transfer method is RPC
Source: ESE BACKUP
Event ID: 909
Description: Information Store (PID) Backup data transfer method is RPC
And subsequently when the client calls HrESEBackupReadFile, the result you get back is 0xC7FF1004, which is a generic ESE backup error code.
So how do you fix it? One way is to follow the instructions in the following KB article to really disable IPv6 on the backup client:
It is not sufficient to unbind IPv6 from the interface or disable IPv6 through other means. Note that the DisabledComponents Value should be 0xFFFFFFFF to completely disable IPv6.
This method has been noted previously in relation to MAPI issues with IPv6, and it appears that it is relevant here as well. Remember that you have to reboot for these changes to take effect, and also that changes to your network configuration may impact the Windows Firewall, as well as Network Location Awareness. Since 0xC7FF1004 is the same error that will occur if your backup client blocks the return socket connection, make certain that this change doesn’t end up blocking the return socket connection for a different reason (Such as a network connection that was previously identified as Private or Domain defaulting to Public).
The other day I was working on a case where the customer was using VBScript and CDO 1.21 to make some changes in some mailboxes, and I couldn’t help but feel that we were working in the past. Don’t get me wrong, there’s a lot of tried and tested VBScript and CDO 1.21 code out there, but I found myself wondering what the “new” way to do this would be.
I started looking at using Powershell to automate a .Net HttpWebRequest to post to an EWS endpoint, and just build the SOAP requests myself (or leverage an XmlDocument), but while I was researching this I stumbled upon something slightly more interesting.
The version of Powershell that is included with the Windows 7 Beta includes a new cmdlet called new-webserviceproxy and it does exactly what it sounds like. You can point it at a wsdl file, and it auto-generates a proxy in a way that seems very similar to the Visual Studio auto-generated proxies.
The following is the result of a good deal of trial and error, but what you end up with is a output that displays some basic information about all of the emails in your inbox.
<# Untested sample code, use at your own risk! #>
## Setup the Exchange Service Binding
$uri = "https://exchangeserver/ews/exchange.asmx"
$exchangeservicebinding = new-webserviceproxy -NameSpace "EWS" -URI $uri -UseDefaultCredential -Class EWS
$exchangeservicebinding.RequestServerVersionValue = new-object EWS.RequestServerVersion
$exchangeservicebinding.RequestServerVersionValue.Version = [EWS.ExchangeVersionType]::Exchange2007_SP1
$exchangeservicebinding.Url = $uri
## Create and Populate the Parent Folder ID Collection
[EWS.DistinguishedFolderIdType]$parentfolderid = new-object EWS.DistinguishedFolderIdType
$parentfolderid.Id = [EWS.DistinguishedFolderIdNameType]::inbox
[EWS.BaseFolderIdType]$parentfolderids = $parentfolderid
## Create an ItemShape and set it to return All Properties
[EWS.ItemResponseShapeType]$itemshape = new-object EWS.ItemResponseShapeType
$itemshape.BaseShape = [EWS.DefaultShapeNamesType]::AllProperties
## Create the FindItemType object and populate with the Parent Folder Ids and Item Shape
[EWS.FindItemType]$finditemtype = new-object EWS.FindItemType
$finditemtype.ParentFolderIds = $parentfolderids
$finditemtype.ItemShape = $itemshape
## Make the call to the webservice
[EWS.FindItemResponseType]$finditemresponses = $exchangeservicebinding.FindItem($finditemtype)
## Loop through the returned messages and print some basic info
foreach($messagetype in $finditemresponses.ResponseMessages.Items.RootFolder.Item.Items)
Write-Host "From: " $messagetype.From.Item.Name
Write-Host "Subject: " $messagetype.Subject
Write-Host "Received: " $messagetype.DateTimeReceived.Date
Write-Host "ItemId: " $messagetype.ItemId.Id
<# download code here #>
The above code obviously has no error handling, but hopefully it shows a basic example of how this new cmdlet can be used.
If you want to dig in further, make use of the get-member cmdlet to examine objects of the types that are generated by the proxy, and you can also inspect the object using format-custom (alias fc) as follows (This can be done for any of the object types in the above code):
1: $exchangeservicebinding | get-member
2: $exchangeservicebinding | fc
Now, many companies have gone outside of the “supported” realm and made these types of changes anyway, and hopefully they do their own testing to make sure that they aren’t introducing errors. Unfortunately this isn’t quite enough. Prior to Exchange Server 2007 SP1 RU5, the update installer would not update files that had been altered. This meant that if you made a change to a file such as logon.aspx, the file wouldn’t get replaced with the latest version. For many installations, this behavior simply meant that the customizations would “stick” through the update. The note above about being in an untested configuration still applies, and you have the added consequence of negating any testing that you did when you initially made the change. Things can get worse though. There were some changes made to OWA with SP1 RU3 that depend on an updated logon.aspx file. If you had made changes to that file prior to SP1 RU3 and you apply RU3 or RU4, OWA ceases to function. This behavior is noted in the release notes for SP1 RU3 and SP1 RU4, and documented in KB 956582. Exchange Server 2007 SP1 RU5 changed this behavior to always replace files even if they have been changed, so that an update doesn’t cause OWA to stop working, but this means that modified files can be replaced.
So, what are the supported ways to customize OWA? The short answer is: “If you can find documentation about how to do it on MSDN or Technet, then it is supported.”
Here’s some information on the supported scenarios:
Outlook Web Access Customization Architecture – Overview of how OWA Customization works.
Outlook Web Access User Interface Customization – You can add elements to the navigation bar and the “New” dropdown.
Outlook Web Access Forms Registry – You can register new custom forms to be used for specific item classes (Note: this only works for the default mail folder view in OWA, and won’t work for other folders like the Calendar).
How to Create a Theme for Outlook Web Access – You can customize the look and feel of the OWA client, including the logon and logoff pages*.
* A special note for branding of the logon and logoff pages: These changes are limited to the image files and the logon.css file in the Base theme directory. This is necessary because without a logged in session, the server has no way to check what theme or experience (Basic or Premium) it should use. Updates to Exchange create a new version-based folder for themes and the modified files should be copied forward. You should plan to test logon and logoff screen customizations after an update to make sure that the non-modified files haven’t changed in a way that causes a problem with your customizations.
Many of our customers are still using MAPI for programmatic access to Exchange mailboxes. The documentation for MAPI was recently relocated on MSDN, so we’re trying to get the word out about where to start.
MAPI Documentation on MSDN (http://msdn.microsoft.com/en-us/library/cc765775.aspx)
For more details on the change in content and organization, head over to the Office Client Developer Content Blog.
If you were at the Professional Developer Conference in L.A. this week, then you're probably exhausted, suffering from a bit of information overload, and either on your way home or getting ready to head that way. There was a ton of information on so many topics, and thankfully even if you weren't in L.A., you can still watch the sessions online.
I wanted to call out a few sessions that might be of interest to Messaging Developers:
Exchange Web Services Managed API: Unified Communications Development for Exchange - If you use EWS, are thinking about using EWS, or got scared away from EWS by terms like SOAP and WS-*, then you have to watch this session. Jason Henderson lays out the details of a new managed API that will greatly simplify developing code that integrates with Exchange.
Office Business Applications: Enhanced Deployment - The title of this one doesn't capture all of the interesting topics that Saurabh covered. In the process of covering the deployment scenario, he also hit on a lot of the changes that are coming to Office Business Application development (AKA: VSTO) in the next version of Visual Studio, including the removal of runtime dependencies on Primary Interop Assemblies (PIA's).
Microsoft Office Communications Server and Exchange: Platform Futures - This session talked about the future of extensibility for Office Communications Server and Office Communicator as well as the UC functionality of Exchange Server.
There's a ton of other great content available at: https://sessions.microsoftpdc.com