Transport Agent: Discard Mailbox-Full type of NDR


Hello folks, me again.
It was some time I didn't have the opportunity to blog about Transport Agents so I thought to write something about this.

This week I have been working with a customer desiring to block specific types of Non-Delivery Reports.
In the example, the idea is to block NDR's such as the one containing the error below.

554 5.2.2 Mailbox Full; STOREDRV.Deliver.Exception:QuotaExceededException.MapiExceptionShutoffQuotaExceeded;

This is rather simple to achieve in Exchange 2016, the release chosen for this development.
It would be possible to easy intercept and block other type of NDR as well, if desired, all it needs is editing the if clause to include the additional patterns to match.

 

What do we use here?

Here the choice to use create a RoutingAgent has been made and this exposes 4 possible events.

The sample shows how to process the MailItem when the OnRoutedMessage event triggers.

The sample contains just the code to handle the OnRoutedMessage event however any other Routing event can be handles in the same way.
If we were to hook into each one of the events this would imply that any given message would be processed - by the same code - up to 4 times which is not optimal and certainly unnecessary.

 

How to identify the messages?

The first thing, in this case, is to check that the property IsSystemMessage of the EmailMessage is set to True; this will ensure we only process a given Non-Delivery report, excluding the possibilities to discard a message that legitimately contains the same string.

At this point it would be necessary to inspect the Body; Unfortunately this is not readily accessible and needs to be read into a String using a StreamReader.

 

How to drop a message?

The last operation consists into discarding the message if all the criteria are matched.
This can be simply achieved by calling the QueuedMessageEventSource.Delete method.

 

Some considerations.

The sample contains also some logging capabilities, this is achieved by simply using a StreamWriter to write to a file.
While this is a great tool for testing and debugging it can be very performance impacting in a busy environment; I'd strongly suggest against using this in a live production environment.

 

Alright, let's install this!

Installing a Transport-Agent is actually straight forward operation which you can find described below.
Here I will be using the folder "C:\NDRAgent" however you could place the agent on another location such as "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\agents\NDRAgent").
NDRAgent, is the name I have chosen for this Trasnport Agent so the folders has been named accordingly.

  1. Build the project.
  2. Create a folder on the server where to store the DLL (i.e. "C:\NDRAgent").
  3. Copy the wanted DLL to the chosen folder.
  4. Make sure that "Exchange Servers" and "Exchange Trusted Subsystem" have Full Access on the chosen folder.
  5. Open the Exchange Management Shell
  6. Run the following commands:
    1. Install-TransportAgent -Name NDRAgent -TransportAgentFactory "NDRAgent.NDRAgentFactory" -AssemblyPath "C:\NDRAgent\NDRAgent.dll"
    2. Enable-TransportAgent NDRAgent
    3. Restart-Service MSExchangeTransport
  7. Close the Exchange Management Shell

 

How do I remove it?

The process is rather similar to the installation one however it needs to be peformed in reverse order.
Please remember that if you wish to remove or replace the DLL, at the end fo the process below, you would need to reboot the server as the file would be locked otherwise.

  1. Open the Exchange Management Shell
  2. Run the following commands:
    1. Disable-TransportAgent NDRAgent
    2. Uninstall-TransportAgent NDRAgent
    3. Restart-Service MSExchangeTransport
  3. Close the Exchange Management Shell

 

Where is the code?

Here you can download the sample code: NDRAgent.

Comments (0)

Skip to main content