Jaa


How to suppress delivery- and read-receipts in Exchange 2007

For remote domains (Organization Configuration - Hub Transport) there are options for blocking delivery reports and non-delivery reports to remote domains.

As described in the online help the option for blocking delivery reports does ONLY affect read receipts.There's also no option for disabling relay notifications "Delivery to these recipients or distribution lists is complete, but delivery notification was not sent by the destination:" (*)

However, these settings are only for remote domains. And there's no option to disable delivery receipts and read receipts originating from the internet or sent internally.
For messages entering or leaving the Exchange organization via SMTP DSNs are requested using certain fields of the P2 header, such as

X-Confirm-To
Return-Receipt-To
Disposition-To-Notification
Receipt-Request-To

One approach to suppress such notifications is to remove these header fields using transport agents on ht and/or cas servers. But this does not fully solve the problem. If we assume that there are already agents present which remove the 4 header fields we see the following results:

(1) Messages from internal to external users:
 
Delivery receipts and read receipts are blocked, but notifications such as (*) are still being sent

(2) Message from external to internal users:
Both delivery receipts and read receipts are blocked.

(3) Message sent internally:

Read receipts and delivery receipts are still being sent.

Removing the header fields from internal messages does not help, as the request for receipts is "done" using MAPI properties.
 

To totally suppress delivery receipts and read receipts we can use a routing agent. The idea is to register it for the OnSubmittedMessage event wich occurs after the message is taken off the submitg queue.

The sample agent described in this article checks the message type and deletes messages of the following types:

Report.IPM.Note.DR (Delivery Receipt)
Report.IPM.Note.IPNRN (Read Receipt)
Report.IPM.Note.Relayed.DR (Relay Notification)

It also logs an event when deleting a message.

Setting up Visual Studio 2007 and creating the agent:

 1.) Create a C# project (dll/library type)
 2.) Copy the following DLLs from the C:\Program Files\Microsoft\Exchange Server\Public directory
     of an Exchange 2007 server to the debug directory of your new C# project:
     a) Microsoft.Exchange.Data.Common.dll
     b) Microsoft.Exchange.Data.Transport.dll
 3.) Add references to the two DLLs to the C# project using the Visual Studio solution explorer
 4.) Add the following code to your project:
 

//==============================================================================
// THIS IS SAMPLE CODE AND IS ENTIRELY UNSUPPORTED. THIS CODE AND INFORMATION
// IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO AN IMPLIED WARRANTY OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
//==============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Email;
using Microsoft.Exchange.Data.Transport.Smtp;
using Microsoft.Exchange.Data.Transport.Routing;
using Microsoft.Exchange.Data.Common;
 
namespace MyRoutingAgent
{
   public class SampleRoutingAgentFactory : RoutingAgentFactory
   {
      public override RoutingAgent CreateAgent(SmtpServer server)
      {
         RoutingAgent myAgent = new ownRoutingAgent();

         return myAgent;
      }
   }
}

 

public class ownRoutingAgent : RoutingAgent
{
   public ownRoutingAgent()
   {
      // Subscribe to events

      base.OnSubmittedMessage += new
      SubmittedMessageEventHandler(ownRoutingAgent_OnSubmittedMessage);
   }

   void ownRoutingAgent_OnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
   {

      if (e.MailItem.Message.MapiMessageClass == "Report.IPM.Note.DR" ||
      e.MailItem.Message.MapiMessageClass == "Report.IPM.Note.Relayed.DR"||
      e.MailItem.Message.MapiMessageClass == "Report.IPM.Note.IPNNRN")

      {
         try
         {
            source.Delete();
            EventLog.WriteEntry("MyRoutingAgent", "Deleted Message:\r\n" +
            "Type: " + e.MailItem.Message.MapiMessageClass + "\r\n"
            + "Subject: " + e.MailItem.Message.Subject + "\r\n"
            + "From: " + e.MailItem.Message.Sender.SmtpAddress + "\r\n",
            EventLogEntryType.Information, 666 );
         }

         catch (Exception except)
         {
            EventLog.WriteEntry("My Routing Agent", except.Message,
            EventLogEntryType.Error);
         }
      }
   }
}

 5.) Compile the DLL
 6.) Copy the DLL to the HT server
 7.) Install the transport agent using the Exchange Management Shell:
     Install-TransportAgent -Name "OwnTestAgent" -TransportAgentFactory "MyRoutingAgent.SampleRoutingAgentFactory" -AssemblyPath "Path to DLL"
 8.) Enable the transport agent using the Exchange Management Shell:
     Enable-TransportAgent "OwnTestAgent"
 9.) IMPORTANT:
     Exit Powershell
10.) IMPORTANT:
     Restart the MSExchangeTransport service
11.) Verify that the agent was successfully enabled / registered by running
     Get-Transportagent
12.) Give the network service account full control to the following registry key:
     HKLM\System CCS\services\Eventlog
     (only necessary when writing to the event log)

Tips:

  • To live debug the dll you need to attach to edgetransport.exe.
  • To recompile after a change
    • detach from edgetransport
    • stop the transport service (otherwise Visual studio won't be able to overwrite the file) 
      (only if you registered the dll from the \debug folder
  • Sometimes messages remain in the outbox until the mail submission service is restarted
     

How can you test if relay notifications are suppressed as well?
Need to generate such messages in the test environment. The question is - how?

- Configure SMTP service on a Windows 2003 server (or XP, Vista, ...) to accept messages for a certain domain (e.g. tailspintoys.com)
- Create send connector pointing to this machine
- Send a test message asking for DR
- No DR will be sent, but message is successfully deliverd to drop directory
- Telnet to W2K3 machine and sending EHLO shows that DSNs are supported
- Switch off ESMTP verb DSN in metabase (262168 How to turn off 8BITMIME in Windows 2000 and in Windows Server 2003 SMTP service)
- Repeat the telnet test to confirm that DSN is no longer advertised
- Send another test message - this time Exchange generates the relay notification

Comments

  • Anonymous
    January 01, 2003
    In VS you can specify the platform target in the project settings. But I never tried.

  • Anonymous
    August 07, 2009
    When enabling or uninstalling a transport agent you should supply the name parameter in quotes but without the -Name switch.  The enable-TransportAgent command above does not run as written.

  • Anonymous
    August 11, 2009
    Thanks for letting me know! I'll correct the article.

  • Anonymous
    February 18, 2010
    Can this be compiled on a 32-bit OS?

  • Anonymous
    January 14, 2011
    Sorry for being a newbie, but I get everything up until the last step: "Give the network service account full control to the following registry key: HKLMSystem CCSservicesEventlog" How do I do this? Thanks, Cam