Using Exchange EWS To Delete Corrupt OOF


Daya Patil discusses the solution to one of her recent engagements where the OOF rule in some mailboxes experienced corruption.


One of our customers faced an interesting issue with Out Of Office (OOF) rules. This was was during the holiday season when most of the staff went on vacation and set their OOF. 

When returning to the office, users turned their OOF messages off.  However even though the OOF was turned off, senders were still receiving OOF messages.  The automatic replies were still processing messages even though they were disabled.

 

We went through multiple troubleshooting steps to work through the issue.  The sequence is outline below.

  

Attempt # 1 – Disabling OOF Using OWA/Outlook

Turning off OOF from OWA/Outlook did not help.  The same behaviour persisted.

 

Attempt # 2 – Disabling OOF Using PowerShell

Disabling and then checking OOF configuration using Exchange Management Shell did not change the behaviour.  For example to check OOF configuration using the Exchange Management Shell we could run:

Get-Mailbox ABC | Get-MailboxAutoReplyConfiguration | ft identity, auto*, *message -AutoSize

Identity                                           AutoReplyState                 ExternalMessage            InternalMessage

------------                                            --------------                          ---------------                      ---------------

corp.contoso.com/ABC                     Disabled

 

However it didn’t fix the issue for the mailbox in question…

 

Attempt # 3 – Move Mailbox To New Server/Database

Tried moving problematic mailbox --the issue remained.

 

Attempt # 4 – MFCMAPI

Removing corrupt OOF rule with MFCMapi worked.  Yay!

 

However, since multiple users were affected by the issue, correcting mailboxes one by one using sing MFCMAPI was not a realistic solution. 

Time to get PowerShell out and to automate a fix…..

 

Attempt # 5 – PowerShell And EWS

The Exchange Web Services (EWS) API is able to access many message properties. Objects and properties relating to OOF are no exception!

The valid classes for OOF messages are:

  • IPM.Note.Rules.OofTemplate.Microsoft
  • IPM.Note.Rules.ReplyTemplate.Microsoft

The below screenshot shows the property names used in the script to correct the OOF  issue. 

Table Of OOF Property Names

 

Here is the final script that I have tested it in my environment.Note that THIS SCRIPT DELETES OOF RULE for all of the mailboxes it processes.    The below is considered sample code, and you will need to thoroughly test it. 

This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment.  THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.  We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute the object code form of the Sample Code, provided that You agree: (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise or result from the use or distribution of the Sample Code.

Please note: None of the conditions outlined in the disclaimer above will supersede the terms and conditions contained within the Premier Customer Services Description.

This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at https://www.microsoft.com/info/cpyright.htm.

 

Few things to note:-

1. User account with which you are running script needs to have full access (permission) on other mailboxes which you are calling in the script.

2. Script does backup any OOF rules.  OFF rules are deleted.  Ensure you have valid and tested backups of the environment prior o proceeding any further. 

 

 

## Load EWS DLL

Import-module "C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll" 

                $ErrorActionPreference = "silentlycontinue"

## Set Exchange Version 

                $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1 

                <#$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

               $user = [ADSI]"LDAP://<SID=$sid>"

               $Service.AutodiscoverUrl($User.Properties.mail) #>

               $Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion) 

               $Uri=[System.URI] "https://exch2010-1.contoso.com/ews/exchange.asmx

               $Service.Url = $Uri

               $mailboxname = "fsadministrator@contoso.com"

# Setup Basic EWS Properties for Message Search - Used to locate Hidden Forwarding Rule

$SearchFilterForwardRule         = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM", [Microsoft.Exchange.WebServices.Data.ContainmentMode]::Prefixed, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::Exact)

$itemViewForwardRule             = New-Object Microsoft.Exchange.WebServices.Data.ItemView(30, 0, [Microsoft.Exchange.Webservices.Data.OffsetBasePoint]::Beginning)

$itemViewForwardRule.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, [Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject)

$itemViewForwardRule.Traversal   = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Associated

# Properties for Hidden Delegate Forwarding Rule

$PID_TAG_RULE_MSG_PROVIDER1    = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EB,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)

$PID_TAG_RULE_MSG_PROVIDER2   = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EC,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)

# Property Set for Delegate Forward Rule

$propertySetForwardRule1 = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, $PID_TAG_RULE_MSG_PROVIDER1)

$propertySetForwardRule2 = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, $PID_TAG_RULE_MSG_PROVIDER2)

$forwardRuleExists = $false

$rfRootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)

               $rfRootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$rfRootFolderID)

$findResults = $rfRootFolder.FindItems($searchFilterForwardRule, $itemViewForwardRule)

If ($findResults.TotalCount -gt 1)

{

Foreach ($item in $findResults.Items)

{

                              $item.Load($propertySetForwardRule1)

                              $value = $item.extendedproperties|foreach {$_.value}

                              if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "Microsoft Exchange OOF Assistant"))

                                {     $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if ($item.Itemclass -eq "IPM.Note.Rules.OofTemplate.Microsoft")

                                {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "MSFT:TDX OOF Rules"))

                                {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                              if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "Microsoft Exchange OOF Assistant"))

                              {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if ($item.Itemclass -eq "IPM.Note.Rules.ExternalOofTemplate.Microsoft")

                               {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                              if (($item.Itemclass -eq "IPM.ExtendedRule.Message") -and ($value -eq "Microsoft Exchange OOF Assistant"))

                              {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

               $item.load($propertySetForwardRule2)

               $value = $item.extendedproperties|foreach {$_.value}

                              if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "Microsoft.Exchange.OOF.InternalSenders.Global") )

                              {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "Microsoft.Exchange.OOF.AllExternalSenders.Global"))

                              {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if (($item.Itemclass -eq "IPM.Rule.Message") -and ($value -eq "MSFT:TDX OOF Rules"))

                              {     $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)}

                               if (($item.Itemclass -eq "IPM.ExtendedRule.Message") -and ($value -eq "Microsoft.Exchange.OOF.KnownExternalSenders.Global"))

                              {    $Item.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)} 

}

}

 



Published by MSPFE editor Rhoderick Milne.  This is brought to you by the letter Z, number 3 and mobile Internet.