Yes, yes it is, and I’m glad you noticed! X-Microsoft-Antispam is quite new and only started showing up in messages passing through EOP a few months ago. This new header currently contains two published values to help with bulk mail and phishing detection.
The beauty of this header is that it is stamped on incoming messages BEFORE EOP transport rules are evaluated. This means you can write EOP transport rules to trigger based on what’s in this header.
One of the goals behind the new X-Microsoft-Antispam header is to allow customers to decide how sensitive they want EOP to be when it comes to bulk mail detection. Today in the EOP Content Filter there is a bulk mail detection switch that can currently only be set to either on or off.
The problem with this switch only being on or off is that bulk mail is a very grey area. What one user considers as bulk another will not. This is why we are moving beyond the on off switch to a multi-value classification system where customers will be able to set the level that they are comfortable with.
With this new header, you can decide on a scale how sensitive you want the service to be with bulk mail detection. Eventually this will be rolled in to the Advanced Spam Filter options and replace the current bulk on off switch, but for now you can write EOP Transport Rules to take advantage of this and enforce the bulk mail detection level of your choosing.
At MEC this year there was a great presentation titled So how does Microsoft handle my spam? In this presentation, bulk mail detection is discussed between 22:30 to 28:50 and the speakers provide great insight into this topic. The entire session is great, but I would recommend at least listening to the six minutes where they discuss bulk mail.
If you are experiencing unwanted bulk mail today there are some things you can start with.
The following documentation was updated in July 2014 to include information about the new X-Microsoft-Antispam header.
What’s the difference between junk email and bulk email?Anti-spam message headersBulk Complaint Level valuesUse transport rules to aggressively filter bulk email messages
The EOP online quarantine is a wonderful feature that can be easily managed through the Office 365 Portal. However, if you are looking for more functionality and flexibility with quarantine management, you’ll need to turn to PowerShell.
Before I begin I have a quick disclaimer. The PowerShell scripts in this article are not official, nor are they supported by Microsoft. They are just scripts that I have written and use myself in my day to day work with EOP.
For most of the day to day quarantine tasks the Office 365 Portal view will work just fine. This view will allow you to search for messages based on a wide range of criteria and release single messages to either a few or all the intended recipients.
There are a few places where the Office 365 Portal view falls short though.
The following three cmdlets are currently available for quarantine management.
QuarantineMessageThis will retrieve a list of messages in the quarantine which can be filtered with a wide range of search criteria (recipient address, sender address, subject, etc…).
Get-QuarantineMessageHeaderReturns the header of a message in the quarantine. This is the same as highlighting a quarantined message and clicking “View message header…” in the Office 365 Portal.
Release-QuarantineMessageMessages piped to this cmdlet from Get-QuarantineMessage will be released. This cmdlet can be used to release a message to either some, or all of the intended recipients.
See Exchange Online Protection cmdlets for a complete list.
The Get-QuarantineMessage cmdlet returns a number of properties, but there are three that will always be empty unless you specify the Identity parameter when calling this cmdlet. These three properties are as follows.
Let’s look at an example. Here I am using Get-QuarantineMessage by specifying the message subject and not the message identify. Take note of the empty properties.
Now I have used Get-QuarantineMessage to target the same message as above, but instead I have referenced it using its identity. In this case the above three properties all contain data.
We can now see that this message was sent to two recipients and has been released to one of them but not the other.
One more item I’d like to note. Messages can only be released to email address that were on the original recipient list. This means that you cannot release a message to an admin for review unless the admin was one of the intended recipients. This is true for both the portal view as well as with PowerShell.
In the following examples I am not limiting the results returned by Get-Quarantine. In a production environment with a quarantine that contains many messages I would recommend filtering the returned results. For example, to restrict the results returned to a single day the following should be used in the examples in this section.
Get-QuarantineMessage –StartReceivedDate 07/20/2014 –EndReceivedDate 07/21/2014
Further filtering may be required with the PageSize property.
View quarantined items that have not yet been released
When a message is released from the quarantine, it will still remain in the quarantine until it expires. This makes it difficult to tell if a message has been released yet or not. Through the portal, you need to bring up the properties of a message to find this out which can be very cumbersome. This can easily be accomplished with PowerShell.
(Get-QuarantineMessage).identity | ForEach {Get-QuarantineMessage -Identity $_} | Where {$_.QuarantinedUser -ne $null}
Here I am looking at the QuarantinedUser property and unless its empty, the message will be returned by this query.
View items that have already been released
This is similar to the above script except here I’m focusing on messages that have already been relased.
(Get-QuarantineMessage).identity | ForEach {Get-QuarantineMessage -Identity $_} | Where {!$_.QuarantinedUser}
Again I am looking at the QuarantinedUser property, but in this case if it’s empty the message will be returned.
Mass release messages from the quarantine
Let’s say that we’ve created a rule which quarantined all messages sent by joe@contoso.com and we want to mass release them.
Get-QuarantineMessage –SenderAddress joe@contoso.com | Release-QuarantineMessage -ReleaseToAll
Note that this will produce a warning for any message that has already been released but this will not stop the execution of the command.
Export a list of quarantined items to a csv file
Let’s say you want to export a list of quarantined messages to a CSV file for analysis. The following will accomplish this and note that I am specifying the identity parameter to ensure all the properties are returned.
(Get-QuarantineMessage).identity |foreach {Get-QuarantineMessage -Identity $_} |export-csv test.csv -notypeinformation
Connect to EOP PowerShell – If you have EOP only.Connect to Exchange Online PowerShell – If you have Exchange Online.EOP cmdlets
So, you have decided to use the Exchange Online Protection (EOP) quarantine and have enabled End user Spam Notifications (ESN). Great choice! Now, after a couple of days have passed, you are wondering if everything is working as it should. How can you verify that ESNs are being delivered to your users? That is a great question and one that is easy to answer! First though, let’s review what an ESN is.
An ESN is a method by which end users can manage their own spam quarantine. When enabled, ESNs are sent out at most once a day (can be configured to be less frequent) and will contain a digest of messages that have been placed in the users quarantine since the last ESN was sent out. If no messages have been directed to an end users quarantine they will not receive an ESN.
The following is an example of an ESN.
Using the links in the ESN, end users are able to release messages and report them back to Microsoft as “Not Junk.”
Note: Messages that are diverted to the quarantine through a transport rule will not appear in an ESN. Only messages placed in the quarantine by the spam engine will appear in an ESN.
ESNs can be enabled on the Default Content Filter along with any custom Content Filter that is scoped to a domain. ESNs cannot be enabled on custom Content Filters that have been scoped to either individuals or groups.
To enable ESNs, highlight a Content Filter and click the Configure end-user spam notifications link on the right side of the page.
ESNs are always sent from quarantine@messaging.microsoft.com which makes them easy to track. In the Exchange Admin Center, select Mail Flow and then Message Trace. Filter on the ESN sending address like so.
Now run the message trace to see all ESNs that have been delivered in the specified time frame.
EOP spam filters will sometimes mark an ESN as spam based on the contents of the message. If you experience this, create a transport rule that will white list messages from quarantine@messaging.microsoft.com. The rule would look something like this.
This works because ESNs are sent through your tenant and so are subject to EOP transport rules.
When a legitimate message is marked as spam, the first question usually asked is “why?” It can sometimes, but not always, be quite difficult to find the explanation. If an enabled Advanced Spam Filter (ASF) option has caused the spam detection, this will be called out directly in the header. In these cases, finding the “why?” is very easy!
Advanced Spam Filtering options, which are located in the Content Filter, allow you to increase the aggressiveness of the Exchange Online Protection spam detection engine. If one of the ASF options has caused a message to be marked as spam, there will be an additional header present in the message, X-CustomSpam.
This header will spell out in plain text which ASF option caused the message to be marked as spam. If the X-CustomSpam header is not present in a message that was marked as spam, it means that an ASF option did not trigger and was not the reason for the spam detection.
Example: I enabled the ASF option “URL redirect to other port.”
I then sent a message which contained the link "http://www.contoso.com:123" in the body. This message triggered the above ASF in the Content Filter and caused the message to be marked as spam. Looking in the headers of this message I see the following.
X-CustomSpam: URL redirect to other port
This tells me exactly which ASF option caused the message to be marked as spam and I can now think about adding exceptions in place if the message was legitimate.
A complete list of X-CustomSpam entries can be found on TechNet at Advanced Spam Filtering Options.
Except for the last four ASF options, all other options have three configuration states. Off, On, and Test.
To configure how test mode works, scroll to the bottom of the ASF options window and you will see the following.
Test Mode will allow you to evaluate the impact that an ASF option without actually having it officially mark a message as spam. The “Add the default test X-header text” refers to the X-CustomSpam header and “Send a Bcc message to this address” is self-explanatory.
When educating customers on ASF options I often recommend the following.
Anti-Spam message headers
Organizations with on-premises mail environments often will have a primary site and at least one backup site. When Exchange Online Protection is being used to protect those on-premises mail environments, the ideal configuration would have EOP only delivering mail to the primary on-premises site, and only to the backup site if the primary site goes down. In EOP, you can add multiple smart hosts to an EOP outbound connector but cannot add priorities to them.
For EOP to be able to deliver incoming messages to your on-premises mail environment you will need an outbound connector in the cloud that is of type on-premises. This connector will be setup with a smart host, which can be either IPs, Fully Qualified Domain Names (FQDN), or a combination of those two, which will point to your on-premises mail environment.
If you have multiple smart hosts entered, the outbound connector will initially choose one at random to deliver a message, and following that will use round-robin load balancing to distribute subsequent messages among the smart host entries. If the initial smart host does not respond, the connector will try the next one and if none of the entries respond, the message will be put into deferral and retried approximately every five minutes for 48 hours. See Inbound and Outbound connector FAQ for more information.
If you have a primary site and at least one backup site, you most likely want all mail to be delivered to the primary site and only delivered to the backup site if the primary fails. Well, this is indeed a possible setup and can be accomplished with some DNS configuration.
If you remember from my previous article, Outbound Connector Smart Host Behavior, when an FQDN is entered as an outbound connector smart host, the connector will perform an MX lookup on the FQDN and will take MX Priority into account when evaluating the results. Keeping this in mind, here’s an example.
Ex. Contoso.com has three on-premises sites with different public IPs. Note that in this example I’m using private IPs.
Site A – 10.0.0.5Site B – 10.1.0.5Site C – 10.2.0.5
Contoso.com wants EOP to route all incoming mail to site A, but if Site A goes down, then route all mail to Site B. They only want mail delivered to Site C as a last resort if both Site A and Site B are down. The following will need to be configured in DNS.
MX Records
A Records
Now back in EOP, specify onprem.contoso.com as the only smart host in your outbound connector.
From this point on, when EOP needs to deliver mail on-premises, it will look up the MX for onprem.contoso.com and will respect the MX Priority weights that are specified in DNS. Keep in mind that a network hiccup could cause a failover.
Happy failover!