EOP Field Notes

Exchange Online Protection: Notes from the field

Quarantine and PowerShell

Quarantine and PowerShell

  • Comments 11
  • Likes

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.

Current Limitations of the Office 365 Portal

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.

  1. There is currently no way to mass release messages from the quarantine. For example, let’s say there are hundreds of quarantined messages from a particular sender in the quarantine and you would like to release all of them. Through the Office 365 Portal you can only release one at a time which is very cumbersome.

  2. The portal will only show a maximum of 500 entries and there is no “next page” button.” If you have a large quarantine in excess of 500 messages, you will need to use the filtering options to limit your search criteria.

  3. There is currently no way to see if a message has been released unless you double click the message to bring up the properties. If “Release to…” is greyed out, then the message has already been released.


PowerShell cmdlets

The following three cmdlets are currently available for quarantine management.

QuarantineMessage
This 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-QuarantineMessageHeader
Returns 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-QuarantineMessage
Messages 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.


Technicalities

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.

  • RecipientAddress
  • QuarantinedUser
  • ReleasedUser

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.

Examples

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


Resources

Connect to EOP PowerShell – If you have EOP only.
Connect to Exchange Online PowerShell – If you have Exchange Online.
EOP cmdlets

Comments
  • Nice, thanks for this Andrew. I can see it coming in handy!

  • No problem at all! I have a PowerShell section in my OneNote where I keep tidbits like this :)

  • I'm trying to run the command to export all the quarantined messages but its not working for me. I receive a "cannot validate argument on parameter 'Identity" error. What am I doing wrong??

  • Hi Scott, based on that error I'm not sure. I just tried running the the following against my Exchange Online tenant and didn't have any issues.

    (Get-QuarantineMessage).identity |foreach {Get-QuarantineMessage -Identity $_} |export-csv test.csv -notypeinformation

    I have seen some strange PowerShell issues that ended up being attributed to either a group policy or a firewall issue when run from a corporate network. Do you have issues with any other Exchange Online PowerShell commands? Maybe try running on a machine that doesn't have a GPO being applied and that has a pure internet connection.

  • result of the Get-QuarantineMessage is not returning all the message in the quarantine area.

  • Hi there Siddiq. If you have a lot of messages in your quarantine, you will have to use the -Page & -PageSize properties of the Get-QuarantineMessage cmdlet. The default PageSize is 1000, but configurable up to 5000. See http://technet.microsoft.com/en-us/library/jj200726.aspx for more information on these properties.

  • Yeah, same issue as Scott

    Cannot validate argument on parameter 'Identity'. The argument is null or empty.

    (Get-QuarantineMessage -SenderAddress xyz@domain.com).Identity returns $null (with or without the SenderAddress parameter), which explains the exception.

    Get-QuarantineMessage -SenderAddress xyz@domain.com | select Identity returns the expected result set.

    Also, if I dump all quarantined messages into a list (Get-QuarantineMessage -senderaddress xyz@domain.com), the RecipientAddress, QuarantinedUser and ReleasedUser properties are all $null - it's not until I retrieve individual quarantined messages using their respective Identity property that those field are populated.

    Therefore, this works, but takes FOREVER (essentially same logic, just not a one-liner):
    $qm = Get-QuarantineMessage -senderaddress xyz@domain.com
    $qm | ForEach {Get-QuarantineMessage -Identity $_.Identity} | ? {$_.QuarantinedUser -ne $null}


    Also, doesn't matter whether I connect to

    https://ps.protection.outlook.com/powershell-liveid/ or
    https://outlook.office365.com/powershell-liveid/

    so, I'm surprised it works for you, Andrew :)

  • Thanks for sharing Lars, that is very interesting. Without seeing the environments I can't say why you are having issues getting it to work. My test environments have a very small amount of messages in the quarantine which may be playing in to this.

  • Very helpful Andrew - that limit of 500 in the GUI had me scratching my head..
    nice one

  • I'm running the ' Get-QuarantineMessage –SenderAddress joe@contoso.com | Release-QuarantineMessage -ReleaseToAll ' and it runs great on the first 20 - 50 items and then stops. Anyway to use the -resulteSize unlimited to have the script check all the quarantined items?

  • Hi Tim, good question. I don't have a large enough quarantine in my test tenant to be able to test this so I'm not sure. If you have a lot of messages you may need to modify the script to run more of a loop rather than doing the whole release with a single line of PowerShell.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment