Query Details

HUNT 15 M365 Compliance E Discovery Full Audit 90d

Query

// Hunt    : M365 - eDiscovery and Compliance Search Activity History (90d)
// Purpose : Full chronological inventory of all compliance center search and export
//           activities over 90 days. Surfaces who performed searches, what content
//           was scoped, and especially which searches were followed by an export.
//           Start-to-export chains are key evidence in insider threat and compromised
//           admin investigations. Also reveals audit log searches that could indicate
//           an attacker checking what has been logged about their own activities.
// Tables  : OfficeActivity
// Period  : P90D
//==========================================================================================

let LookbackDays = 90d;

OfficeActivity
| where TimeGenerated > ago(LookbackDays)
| where RecordType in (
    "SecurityComplianceCenter",
    "ComplianceManager",
    "OfficeSecurityComplianceCenter")
| where Operation in (
    "SearchCreated",
    "SearchStarted",
    "SearchExported",
    "SearchPreviewed",
    "SearchPurged",
    "CaseCreated",
    "CaseMemberAdded",
    "CaseMemberRemoved",
    "HoldCreated",
    "HoldUpdated",
    "New-ComplianceSearch",
    "Start-ComplianceSearch",
    "New-ComplianceSearchAction",
    "Get-ComplianceSearch",
    "New-eDiscoveryCase",
    "New-UnifiedAuditLogRetentionPolicy",
    "AuditLogSearchStarted",
    "AuditLogSearchExported",
    "ContentSearchExportDownloaded")
| extend Params = tostring(Parameters)
| extend
    SearchName         = tostring(extract(@"Name.*?:([^\s,]+)", 1, Params)),
    ContentSources     = tostring(extract(@"(ExchangeLocation|SharePointLocation|OneDriveLocation).*?:([^\n]+)", 2, Params)),
    IsExport           = Operation in (
        "SearchExported", "New-ComplianceSearchAction",
        "ContentSearchExportDownloaded", "AuditLogSearchExported"),
    IsAuditLogSearch   = Operation in ("AuditLogSearchStarted", "AuditLogSearchExported")
// Build a timeline per user
| summarize
    TotalActions     = count(),
    ExportActions    = countif(IsExport),
    AuditLogSearches = countif(IsAuditLogSearch),
    SearchPurges     = countif(Operation == "SearchPurged"),
    Operations       = make_set(Operation, 15),
    SearchNames      = make_set(SearchName, 10),
    ClientIPs        = make_set(ClientIP, 5),
    FirstAction      = min(TimeGenerated),
    LastAction       = max(TimeGenerated)
    by UserId
| extend RiskIndicator = case(
    SearchPurges >= 1 and ExportActions >= 1, "Export + Purge Chain — Critical",
    ExportActions >= 3,                        "Repeated Exports — High",
    AuditLogSearches >= 1,                     "Audit Log Self-Review — Suspicious",
    ExportActions >= 1,                        "Export Performed",
    "Informational")
| sort by ExportActions desc, TotalActions desc
| project
    UserId,
    TotalActions,
    ExportActions,
    AuditLogSearches,
    SearchPurges,
    Operations,
    SearchNames,
    ClientIPs,
    RiskIndicator,
    FirstAction,
    LastAction

Explanation

This query is designed to analyze and summarize activities related to searches and exports in the Microsoft 365 compliance center over the past 90 days. Here's a simple breakdown of what it does:

  1. Data Source: It examines records from the OfficeActivity table, focusing on activities related to security and compliance.

  2. Time Frame: It looks at activities that occurred within the last 90 days.

  3. Activity Types: The query filters for specific operations, such as creating or starting searches, exporting search results, and managing compliance cases.

  4. Extracted Information: It extracts details like search names and content sources from the activity parameters.

  5. Activity Classification: It identifies whether an activity involved exporting data or searching audit logs.

  6. User Activity Summary: For each user, it summarizes:

    • Total number of actions performed.
    • Number of export actions.
    • Number of audit log searches.
    • Number of search purges.
    • Types of operations performed.
    • Names of searches conducted.
    • Client IP addresses used.
    • The first and last action timestamps.
  7. Risk Assessment: It assigns a risk indicator to each user based on their activities:

    • "Export + Purge Chain — Critical" for users who both exported and purged searches.
    • "Repeated Exports — High" for users with multiple export actions.
    • "Audit Log Self-Review — Suspicious" for users who searched audit logs.
    • "Export Performed" for users who performed at least one export.
    • "Informational" for users with no significant risk indicators.
  8. Sorting and Presentation: The results are sorted by the number of export actions and total actions, and then presented with key details for each user.

Overall, this query helps identify potentially risky behavior related to data searches and exports, which can be crucial for insider threat investigations and monitoring compromised admin activities.

Details

David Alonso profile picture

David Alonso

Released: March 18, 2026

Tables

OfficeActivity

Keywords

OfficeActivity

Operators

letagoinextendtostringextractsummarizecountcountifmake_setminmaxbycasesortdescproject

Actions