PowerShell Scripting: EWS and IPM.Configuration.Owa.UserOptions

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

So, to start off, I should explain how this script came about and why it’s, currently, in a ‘legacy’ status.

There was an issue in Exchange 2010 (that, has since, been fixed), where the save method for the IPM.Configuration.Owa.UserOptions item was in an infinite loop due to corruption. This corruption didn’t come into fruition until long after RTM and SP1. (My thoughts are that SP1 was the introduction of the “bad code”, but it’s not really important when it was introduced.)

What would happen is that the Mailbox Assistants would become flooded/backlogged with events, in the event history table – which is kept in memory. The only signs of reproduction of the issue was that OOFs and RBAs would not fire, in response to emails or meeting requests, respectively. This became a tedious issue to deal with because it also caused other problems, during initial attempts of remediation.

For example, mailbox moves would fail, as the Mailbox Replication Service would successfully move the mailbox but the assistants were still churning away at the mailbox. After the failure, and if the new mailbox on the target database was – now – oriented to the user’s object, the new database (a.k.a.: the target database) would quickly fall into repro.

Restarting the service and having it rebuild the event history table in memory was not a viable avenue for remediation, because the table would rebuild with the infinite corruption loop – once the assistants had read in the event history table, tagged the IPM item change to be processed, and the event was interesting to the assistant[s].

The method we would use to find these users, with the affected IPM item, is to use ExMon to see which user was consuming the most CPU. We could, then, use ExTra to obtain an ETL – targeting the ALL of the assistant flags. Then, we could use a program to port the ETL to CSV and see just what those assistants were chomping down on. [The ExTra method was my preferred method, as it provided two things: significant proof of repro and the user we needed to fix.]

Sadly, our only method of remediation (until SP2 + RU2 + IU) was to copy the user’s configuration settings (Get-MailboxMessageConfiguration) and, then, purge the item from the mailbox store. More often, than not, this was done with MFCMAPI and we would pass a hard delete, to prevent the corrupted item from going into the dumpster.

Then, I got a novel idea: if we use EWS, we can poke into the mailbox store and obtain the item for deletion, since it’s at the root level of the container. And the rest is, as they say, history.

I thought, even though this is legacy, it might prove note-worthy or that someone could learn from the interop of .NET with PowerShell. [All of the EWS calls are in C#.NET.] Unless we have a repro of this particular issue in the nigh to immediate future (for those who are concerned, it’s been over a year since this was fixed), the propensity of it ever being used again is $null. (Little PS humor, for ya, there…)

Delete-IPMConfigurationOWAUserOptions.ps1

C# + EWS: Autodiscover Test (Exchange and O365)

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In times of troubleshooting client-side issues, it may become necessary to query for the autodiscover response the user is receiving from either Exchange on-premises or Exchange in O365 – or, in the case of a redirection, both on-premises and O365 Exchange. This is a sample C#.NET Console Application, which will query for the Autodiscover response and use the TraceListener class to write the response to files.

There are two things the code doesn’t take into account for:

1. The condition wherein the user’s SMTP address and UPN are different.
2. ALL of the possible returns from Autodiscover for the UserSettings.

 

Thus, I have included the the source code for two reasons:

1. Promotion of writing .NET programs for both on-premises Exchange and O365 Exchange.
2. Customization of both the UserSettings one is targeting and the target delivery folder for which the files should be saved.

 

If you have any problems, questions, or concerns, feel free to reach out to me and I’ll try to address them as soon as possible.

The source code can be found here: http://gallery.technet.microsoft.com/C-EWS-Autodiscover-Test-870b4a8e

O365 & EWS: EmailMessage.SetExtendedProperty() Introduces Undesirable Behavior for Cloud

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In Office 365, there is a known issue where Item.SetExtendedProperty() will prevent ResponseMessage.SendAndSaveCopy() from working correctly. Instead of sending the messaging and placing the item in the ‘Sent Items’ folder, the message will be sent and remain in the ‘Drafts’ folder.

This issue can be corrected by changing the source code of the EWS application in either of the following two ways:

1. Specify the ‘Sent Items’ folder via passing ‘SENTFOLDEREWSID‘ in the method (Note: WellKnownFolderName.SentItems will not work for this case):

var messageToSend = responseMessage.Save();

// This is our method that is introducing our repro scenario in O365.
messageToSend.SetExtendedProperty(newExtendedPropertyDefinition(newGuid(“{00000000-0000-0000-0000-000000000000}”), “<String>”, MapiPropertyType.String), 1);

// Send and save a copy of the replied email mesage in the default Sent Items folder.
messageToSend.SendAndSaveCopy(SENTFOLDEREWSID);

 

2. Use Item.Update() before the SendAndSaveCopy() method:

 var messageToSend = responseMessage.Save();

// This is our method that is introducing our repro scenario for the cloud.
messageToSend.SetExtendedProperty(newExtendedPropertyDefinition(newGuid(“{00000000-0000-0000-0000-000000000000}”), “<String>”, MapiPropertyType.String), 1);

// We update the item before sending it.
messageToSend.Update(ConflictResolutionMode.AlwaysOverwrite);

// Send and save a copy of the replied email mesage in the default Sent Items folder.
messageToSend.SendAndSaveCopy();

 

With this, you should be able to work-around this EWS issue until a fix is found. Happy coding!

 

Attached, you will find the repro code with the fix (Program.cs).

Program.cs

EWS: Obtaining Mail Item from List

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In troubleshooting an issue for a customer, I ran into a problem: I could obtain the data from the MAPI store (via EWS) but I was unable to figure out how to cast from the list of items obtained to an actual message to action against.

For example, here’s where I was attempting to obtain the items from the MAPI container:

Console.WriteLine(“Connecting to EWS endpoint…”);
ExchangeService ExService = newExchangeService(ExchangeVersion.Exchange2007_SP1);
ExService.Credentials = new WebCredentials(targetMBX, passWord);
ExService.AutodiscoverUrl(targetMBX, RedirectionUrlValidationCallback);

// Obtain the message to reply to.
ItemView iv = new ItemView(3);
FindItemsResults<Item> zeitem = ExService.FindItems(WellKnownFolderName.Inbox, iv);

As you can see, we’re calling FindItems and returning it as a collection of Items. I thought a cast would have to occur, to convert the Item back into an EmailMessage. Instead, as one would be happy to find out  as I was, the Item is an encapsulation of the EmailMessage and we can ‘extract’ it via an array call:

var item = zeitem.Items[0];

From this, we can further action against the mail items via EWS:

if (item is EmailMessage)
{

      Console.WriteLine(“Working with the first item found.”);

   // Reply to the message
ResponseMessage responseMessage = message.CreateReply(replyToAll);
string myReply = “This is a test of the EWS responseMessage method[s].”;
responseMessage.BodyPrefix = myReply;
var messageToSend = responseMessage.Save();

// Send and save a copy of the replied email message in the default Sent Items folder.
messageToSend.SendAndSaveCopy();
}

Using the EWS API, one can do many powerful and important administrative tasks in Exchange. You can read more about it, here.