Query Details

Quarantined Messages

Query

let query_frequency = 7d;
let query_period = 30d;
let query_wait = 1h;
let _PostDelivery_MovedToQuarantine =
    MessagePostDeliveryEvents
    | where Timestamp between (ago(query_frequency + query_wait) .. ago(query_wait))
    | where Action == "Moved to quarantine"
    | join kind=rightsemi (
        MessagePostDeliveryEvents
        | where Timestamp > ago(query_period)
        ) on TeamsMessageId
    | summarize arg_max(Timestamp, *) by TeamsMessageId
    | where LatestDeliveryLocation == "Quarantine"
    | project 
        TeamsMessageId,
        PostDelivery_LatestDeliveryLocation = LatestDeliveryLocation,
        PostDelivery_ActionTrigger = ActionTrigger,
        PostDelivery_ActionType = ActionType,
        PostDelivery_Action = Action,
        PostDelivery_ThreatTypes = ThreatTypes,
        PostDelivery_DetectionMethods = DetectionMethods,
        PostDelivery_ConfidenceLevel = ConfidenceLevel,
        PostDelivery_ActionResult = ActionResult,
        PostDelivery_IsExternalThread = IsExternalThread,
        PostDelivery_SenderEmailAddress = SenderEmailAddress,
        PostDelivery_RecipientDetails = RecipientDetails
    | as _AuxiliarEvents
    | join kind=leftouter (
        MessageEvents
        | where Timestamp > ago(query_period)
        | where TeamsMessageId in (toscalar(_AuxiliarEvents | summarize make_set(TeamsMessageId)))
        | summarize arg_max(Timestamp, *) by TeamsMessageId, SenderEmailAddress//, RecipientDetails
        ) on TeamsMessageId
    | project-away TeamsMessageId1
    | where isnotempty(DeliveryLocation) and isnotempty(PostDelivery_LatestDeliveryLocation) and DeliveryLocation != PostDelivery_LatestDeliveryLocation
    | join kind=leftouter (
        MessageUrlInfo
        | where Timestamp > ago(query_period)
        | where TeamsMessageId in (toscalar(_AuxiliarEvents | summarize make_set(TeamsMessageId)))
        | summarize Urls = make_set(bag_pack("Url", Url, "UrlDomain", UrlDomain)) by TeamsMessageId
        ) on TeamsMessageId
    | project-away TeamsMessageId1
;
let _MessageEvents_Quarantined =
    MessageEvents
    | where Timestamp between (ago(query_frequency + query_wait) .. ago(query_wait))
    | where DeliveryLocation == "Quarantine" or DeliveryAction in ("Blocked", "Moved to quarantine")
    | where not(DeliveryAction == "Quarantine release")
    | where not(DeliveryAction == "Blocked" and DeliveryLocation in ("Dropped", "Failed"))
    | where not(TeamsMessageId in (toscalar(_PostDelivery_MovedToQuarantine | summarize make_set(TeamsMessageId))))
    | as _SecondAuxiliarEvents
    | join kind=leftouter (
        MessageUrlInfo
        | where Timestamp > ago(query_period)
        | where TeamsMessageId in (toscalar(_SecondAuxiliarEvents | summarize make_set(TeamsMessageId)))
        | summarize Urls = make_set(bag_pack("Url", Url, "UrlDomain", UrlDomain)) by TeamsMessageId
        ) on TeamsMessageId
    | project-away TeamsMessageId1
    | project
        Timestamp,
        LastEditedTime,
        TeamsMessageId,
        IsOwnedThread,
        IsExternalThread,
        ThreadId,
        ThreadName,
        ThreadType,
        ThreadSubType,
        GroupId,
        GroupName,
        ParentMessageId,
        MessageId,
        MessageVersion,
        MessageType,
        MessageSubtype,
        SenderType,
        SenderEmailAddress,
        SenderDisplayName,
        SenderObjectId,
        RecipientDetails,
        Subject,
        DeliveryAction,
        DeliveryLocation,
        Urls,
        ThreatTypes,
        DetectionMethods,
        ConfidenceLevel,
        ReportId
;
union _MessageEvents_Quarantined, _PostDelivery_MovedToQuarantine

Explanation

This query is designed to analyze and summarize email messages that have been moved to quarantine, either during or after delivery, within a specified time frame. Here's a simplified breakdown of what the query does:

  1. Define Time Periods:

    • query_frequency is set to 7 days, query_period to 30 days, and query_wait to 1 hour. These are used to filter the data based on time.
  2. Identify Post-Delivery Quarantine Events:

    • The first part of the query (_PostDelivery_MovedToQuarantine) focuses on messages that were moved to quarantine after being delivered.
    • It filters MessagePostDeliveryEvents to find messages moved to quarantine within the last 7 days, excluding the last hour.
    • It joins this data with events from the last 30 days to ensure the messages are still relevant.
    • It summarizes the most recent event for each message and checks if the latest delivery location is "Quarantine".
    • It projects relevant fields such as message ID, action type, threat types, and sender/recipient details.
    • It further enriches this data by joining with MessageEvents and MessageUrlInfo to include additional details like URLs associated with the messages.
  3. Identify Initial Quarantine Events:

    • The second part of the query (_MessageEvents_Quarantined) focuses on messages initially delivered to quarantine.
    • It filters MessageEvents to find messages delivered to quarantine or blocked within the last 7 days, excluding the last hour.
    • It excludes messages that were released from quarantine or blocked and then dropped/failed.
    • It ensures these messages are not already included in the post-delivery quarantine events.
    • It enriches this data with URL information from MessageUrlInfo.
  4. Combine Results:

    • Finally, it combines (union) the results from both parts to provide a comprehensive view of all messages related to quarantine actions, whether they occurred post-delivery or initially.

In summary, this query helps identify and analyze messages that have been quarantined, providing insights into their delivery actions, associated threats, and other relevant details within a specified timeframe.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: June 4, 2025

Tables

MessagePostDeliveryEventsMessageEventsMessageUrlInfo

Keywords

MessagePostDeliveryEventsTeamsMessageIdLatestDeliveryLocationActionTriggerActionTypeActionThreatTypesDetectionMethodsConfidenceLevelActionResultIsExternalThreadSenderEmailAddressRecipientDetailsMessageEventsDeliveryLocationDeliveryActionMessageUrlInfoUrlUrlDomainTimestampLastEditedTimeIsOwnedThreadThreadIdThreadNameThreadTypeThreadSubTypeGroupIdGroupNameParentMessageIdMessageIdMessageVersionMessageTypeMessageSubtypeSenderTypeSenderDisplayNameSenderObjectIdSubjectReportId

Operators

letbetweenagowhere==joinkind=rightsemionsummarizearg_maxbyprojectaskind=leftouterintoscalarmake_setbag_packproject-awayisnotempty!=ornotunion

Actions