Table of Contents
Report Who Released a Quarantined Message
The question was asked on Twitter about whether it is possible to notify end users when administrators release outbound messages from the quarantine. Most of the time, email ends up in quarantine when Exchange Online Protection decides that inbound messages contain spam or malware, but it’s possible to direct outbound email to quarantine using mail flow rules or actions invoked by Microsoft Purview DLP policies. Exchange Online can certainly quarantine problematic messages but as far as end users are concerned, outbound messages intercepted in this way go into a black hole.
Some good suggestions resulted. My initial response was to use the Get-QuarantineMessage cmdlet to periodically check messages in quarantine and detect released items on that basis. Michel de Rooij came up with a better solution to use a mail flow rule to look for the X-MS-TrafficTypeDiagnostic or X-MS-Exchange-Generated-Message-Source email headers to see if they were related to quarantine releases. That’s quite an innovative approach. However, in both cases, the problem exists that you don’t have all the information about a quarantined message following its release.
Check the Audit Log
Which brings me to the unified audit log. Exchange Online generates audit events for most operations, including when an administrator releases a message from quarantine. Administrators can search the unified audit log by running the Search-UnifiedAuditLog cmdlet to look for QuarantineReleaseMessage events. For example:
$StartDate = (Get-Date).AddDays(-90)
$EndDate = (Get-Date).AddDays(1)
[array]$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Formatted -ResultSize 1000 -Operations QuarantineReleaseMessage
If (!($Records)) { Write-Host "No audit records found for quarantine release - exiting" ; break }
This search finds all events logged over the last 90 days when someone released a message from quarantine. The problem is that the information captured in audit log records tells us who released a message but doesn’t tell us anything about the message. For instance, the audit record doesn’t capture the direction of the message (inbound or outbound), the sender, its recipients, and the message subject.
That information is available in the data recorded for quarantined messages. It is therefore possible to capture information about quarantined messages periodically and store the data in a repository that can be checked to retrieve message details. To prove the point, I created a PowerShell list and populated it with details of quarantined messages. Here’s the code I used:
[array]$QM = Get-QuarantineMessage
$QMData = [System.Collections.Generic.List[Object]]::new()
ForEach ($Item in $QM) {
$DataLine = [PSCustomObject] @{
Received = $Item.ReceivedTime
MessageId = $Item.MessageId
Direction = $Item.Direction
Sender = $Item.SenderAddress
Recipients = $Item.RecipientAddress -Join ", "
Subject = $Item.Subject
Type = $Item.Type
Expires = $Item.Expires
Identity = $Item.Identity
Id = $Item.Identity.Split("\")[0]}
$QMData.Add($DataLine)
} # End ForEach Item
Creating a Composite View of Quarantine Message Release
Now that we have data for quarantined messages, let’s use it to create the information needed to communicate with users. This code creates another PowerShell list and then loops through the audit records retrieved earlier. The code checks each audit record against the data for quarantined messages to see if a match exists. If it does, we grab the information about the message and combine it with the information from the audit record to generate a composite view about the release from quarantine.
$QMInfo = [System.Collections.Generic.List[Object]]::new()
ForEach ($Rec in $Records) {
$AuditData = $Rec.AuditData | ConvertFrom-Json
[array]$QMFound = $QMData | Where-Object {$_.Id -eq $AuditData.NetworkMessageId}
If ($QMFound) {
ForEach ($Item in $QMFound) {
$DataLine = [PSCustomObject] @{
MessageId = $AuditData.NetworkMessageId
Received = $Item.Received
Sender = $Item.Sender
Recipients = $Item.Recipients
Subject = $Item.Subject
Type = $Item.Type
Expires = $Item.Expires
Releasedby = $AuditData.UserId
ReleasedAt = $Rec.CreationDate }
$QMInfo.Add($DataLine)
} # End ForEach $QMFound
} # End If
} # End ForEach $Records
Figure 1 shows examples of the composite records generated by the code.

After generating the composite data, it’s then a matter of deciding how to notify end users.
A Directional Oddity
One oddity I noticed is that PowerShell reported a quarantined message as “Outbound” (going out of the tenant) while the Microsoft 365 Defender admin center was certain that the message was “Inbound” (coming into the tenant). Figure 1 shows what Defender reports.

And here’s what Get-QuarantineMessage reported. The other message properties indicate that the message is definitely inbound, so I have no idea why PowerShell thinks otherwise.
Identity : 2a008698-201e-497f-3dee-08dad2e835e2\7129d58d-ca5e-7e32-a4f8-676d082ba9af
ReceivedTime : 30/11/2022 15:33:20
Organization : a662313f-14fc-43a2-9a7a-d2e27f4f3478
MessageId : <PA4PR06MB7264B28C1D73C9EB547DDC5AB8159@PA4PR06MB7264.eurprd06.prod.outlook.com>
SenderAddress : missf0rtune@hotmail.co.uk
RecipientAddress : {tony.redmond@xxx.com}
Subject : Document 49KB (tony.redmond@xxx.com)
Size : 93651
Type : High Confidence Phish
PolicyType : HostedContentFilterPolicy
PolicyName : Default
TagName : AdminOnlyAccessPolicy
PermissionToBlockSender : True
PermissionToDelete : True
PermissionToPreview : True
PermissionToRelease : True
PermissionToRequestRelease : False
PermissionToViewHeader : False
PermissionToDownload : True
Released : False
ReleaseStatus : NOTRELEASED
SystemReleased : False
RecipientCount : 1
QuarantineTypes : HighConfPhish
Expires : 15/12/2022 15:33:20
RecipientTag : {Priority Account}
DeletedForRecipients : {}
QuarantinedUser : {}
ReleasedUser : {}
Reported : False
Direction : Outbound
Looking Everywhere for Data
Often people become dismayed when they look for information and discover that a source doesn’t deliver all the detail they need. It’s often the case inside Microsoft 365 that you can combine data from different sources to come up with an answer. It would be nice if Microsoft captured all the relevant message for a quarantined message release in the audit records, but at least we can find the data.
Learn more about how the Office 365 applications really work on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.
3 Replies to “Checking the Release of Quarantined Messages”