Query Details
// Rule : M365 - Massive File / Item Deletion Across All Workloads
// Severity : High
// Tactics : Impact, DefenseEvasion
// MITRE : T1485 (Data Destruction), T1070.004 (Indicator Removal: File Deletion),
// T1565.001 (Data Manipulation: Stored Data Manipulation)
// Freq : PT30M / Period: PT1H
// Purpose : Detect a single user performing a high volume of delete operations across
// Exchange Online, SharePoint, OneDrive, or Teams within a rolling 30-minute
// window. Pattern is consistent with ransomware staging, insider sabotage,
// or post-exfiltration cleanup. Baseline comparison suppresses known recycle
// operations.
//==========================================================================================
let LookbackWindow = 1h;
let BinWindow = 30m;
let HardDeleteThreshold = 50; // hard/permanent deletes — always serious
let SoftDeleteThreshold = 200; // recycle-bin or soft deletes — higher threshold
OfficeActivity
| where TimeGenerated > ago(LookbackWindow)
| where Operation in (
// Files & folders
"FileDeleted",
"FolderDeleted",
"FileVersionsAllDeleted",
"FileRecycled",
"FilePermanentlyDeleted",
// Exchange
"SoftDelete",
"HardDelete",
"MoveToDeletedItems",
"PurgeMessage",
// Teams
"ChannelDeleted",
"TeamDeleted",
"MessageDeletedAll",
// SharePoint pages
"PageDeleted",
"WikiPageDeleted")
| extend
IsHardDelete = Operation in (
"FilePermanentlyDeleted", "HardDelete",
"PurgeMessage", "FileVersionsAllDeleted"),
Workload = case(
RecordType in ("ExchangeAdmin","ExchangeItem"), "Exchange",
RecordType in ("SharePoint","SharePointFileOperation"), "SharePoint",
RecordType in ("OneDrive","OneDriveFileOperation"), "OneDrive",
RecordType == "MicrosoftTeams", "Teams",
"Other"),
ObjectName = coalesce(SourceFileName, ObjectId, TeamName)
| summarize
TotalDeletions = count(),
HardDeleteCount = countif(IsHardDelete),
SoftDeleteCount = countif(not(IsHardDelete)),
Workloads = make_set(Workload, 5),
DeletedItems = make_set(ObjectName, 30),
EarliestDelete = min(TimeGenerated),
LatestDelete = max(TimeGenerated)
by UserId, bin(TimeGenerated, BinWindow), ClientIP
| extend
DurationMinutes = datetime_diff("minute", LatestDelete, EarliestDelete),
AlertSeverity = case(
HardDeleteCount >= HardDeleteThreshold, "High",
TotalDeletions >= SoftDeleteThreshold, "High",
"Medium"),
IsAdminBulkDelete = UserId has_any ("admin", "service", "svc", "backup")
| where HardDeleteCount >= HardDeleteThreshold
or TotalDeletions >= SoftDeleteThreshold
| project
UserId,
ClientIP,
EarliestDelete,
LatestDelete,
DurationMinutes,
TotalDeletions,
HardDeleteCount,
SoftDeleteCount,
Workloads,
AlertSeverity,
IsAdminBulkDelete,
DeletedItems
| sort by HardDeleteCount desc, TotalDeletions desc
This query is designed to detect suspicious activity involving a high volume of file or item deletions across Microsoft 365 services like Exchange Online, SharePoint, OneDrive, and Teams. Here's a simple breakdown of what it does:
Time Frame: It looks at activities within the last hour, focusing on 30-minute intervals.
Deletion Types: It tracks different types of deletions, distinguishing between "hard" (permanent) deletions and "soft" (recycle-bin) deletions.
Thresholds:
Activity Source: It identifies which Microsoft 365 service (Exchange, SharePoint, OneDrive, Teams) the deletions are coming from.
User and IP Tracking: It records the user ID and IP address associated with the deletions.
Alert Generation:
Output: The query outputs details like the user ID, IP address, time of first and last deletion, total deletions, counts of hard and soft deletions, involved workloads, alert severity, whether it's an admin action, and a list of deleted items.
Sorting: Results are sorted by the number of hard deletions and total deletions in descending order, highlighting the most severe cases first.
Overall, this query helps identify potential malicious activities such as ransomware staging, insider threats, or cleanup after data exfiltration by monitoring unusual deletion patterns.

David Alonso
Released: March 18, 2026
Tables
Keywords
Operators