// question

Suspiciously, the recycle bin appears empty system-wide. Determine which command was executed on Windows to clear the system's recycle bin directory, including any switches and environment variables.

Reference KQL answer and model-by-model comparison.

f723d13d-48dc-4317-9990-cf43a9ac0bf2
question id
12/23
models correct
1
valid answer
52%
success rate
// reference answer

Human-validated correct answer for this question.

rd /s /q %systemdrive%\$RECYCLE.BIN
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine has "Clear-RecycleBin" or ProcessCommandLine has "$Recycle.Bin"
| project Timestamp, DeviceName, AccountName, InitiatingProcessCommandLine, ProcessCommandLine
pass19.87s0.0040
gpt-35-turbo
no answer
no query generatedfail50.00s0.0110
gpt-4-turbo-2024-04-09
'cmd.exe /c rd /s /q %systemdrive%\\$RECYCLE.BIN'
DeviceProcessEvents
| union DeviceLogonEvents
| where (ProcessCommandLine contains "cmd.exe" or ProcessCommandLine contains "powershell") and (ProcessCommandLine contains "/c" and ProcessCommandLine contains "rd /s /q" and ProcessCommandLine contains "$Recycle.Bin" or ProcessCommandLine contains "Clear-RecycleBin")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc
pass113.47s0.0549
gpt-4.1
cmd.exe /c rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where ProcessCommandLine has_any ("$Recycle.Bin", "Recycler", "Clear-RecycleBin", "Remove-Item $", "shell:RecycleBinFolder", "rd /s /q", "del /s /q", "empty Recycle Bin")
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessAccountName, FileName, ProcessCommandLine, InitiatingProcessCommandLine
| order by TimeGenerated desc
pass28.96s0.0244
gpt-4.1-finetuned
no answer
no query generatedfail50.00s0.0390
gpt-4.1-mini
no answer
no query generatedfail50.00s0.0077
gpt-4.1-nano
no answer
no query generatedfail50.00s0.0016
gpt-4o
cmd.exe /c rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where ProcessCommandLine matches regex @'(?i)\b(rd|del)\b.*(\/s|\/q).*(\$Recycle\.Bin|RecycleBin)'
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, FolderPath, InitiatingProcessAccountName, InitiatingProcessCommandLine
pass413.01s0.0369
gpt-5-high
rd /s /q %systemdrive%\$RECYCLE.BIN
let decode_ps_encoded = (cmd:string) {
  let b64 = extract(@"(?i)\s-(?:e|enc|encodedcommand)\s+([A-Za-z0-9+/=]+)", 1, cmd);
  iff(isnotempty(b64), replace_string(base64_decode_tostring(b64), "\u0000", ""), "");
};
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| extend pcl = tostring(ProcessCommandLine)
| extend ps_decoded = decode_ps_encoded(pcl)
| extend EffectiveCmd = iff(isnotempty(ps_decoded), strcat(pcl, " | decoded: ", ps_decoded), pcl)
// Look for explicit Recycle Bin deletion or commands that typically empty it
| where EffectiveCmd has "$Recycle.Bin"
      or EffectiveCmd matches regex @"(?i)\bClear-RecycleBin\b"
      or (FileName =~ "cleanmgr.exe" and EffectiveCmd has_any ("/SAGERUN", "/SAGESET", "/VERYLOWDISK", "/AUTOCLEAN", "/LOWDISK"))
      or EffectiveCmd has "Q2xlYXItUmVjeWNsZUJpbg" // base64 for Clear-RecycleBin
| extend Method = case(
      EffectiveCmd matches regex @"(?i)\bClear-RecycleBin\b", "PowerShell Clear-RecycleBin",
      EffectiveCmd matches regex @"(?i)\bRemove-Item\b.*\\?\$Recycle\.Bin", "PowerShell Remove-Item $Recycle.Bin",
      EffectiveCmd matches regex @"(?i)\b(?:rd|rmdir)\b.*\\?\$Recycle\.Bin", "cmd rd/rmdir $Recycle.Bin",
      EffectiveCmd matches regex @"(?i)\bdel\b.*\\?\$Recycle\.Bin", "cmd del $Recycle.Bin",
      FileName =~ "cleanmgr.exe", "cleanmgr (Disk Cleanup)",
      "Other")
// Try to extract the actual sub-command passed to cmd /c or PowerShell -Command
| extend ExecutedCommand = coalesce(
      extract(@"(?i)(?:/c|/k)\s+(.+)$", 1, EffectiveCmd),
      extract(@"(?i)-Command\s+(.+)$", 1, EffectiveCmd),
      EffectiveCmd)
| project Timestamp, DeviceName, AccountDomain, AccountName, FileName, FolderPath, Method, ExecutedCommand, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
pass1118.66s0.0707
gpt-5-mini-high
cmd.exe /c rd /s /q %systemdrive%\$RECYCLE.BIN
let pattern = @"(?i)(Clear-RecycleBin|Remove-Item\s+[^\n]*\$Recycle\.Bin|rd\s+[^\n]*\\\$Recycle\.Bin|rmdir\s+[^\n]*\\\$Recycle\.Bin|del\s+[^\n]*\\\$Recycle\.Bin|%SYSTEMDRIVE%\\\$Recycle\.Bin|\$env:SYSTEMDRIVE\\\$Recycle\.Bin|\\\$Recycle\.Bin|recycler)"; 
let pathPattern = @"(?i)\$Recycle\.Bin|recycler|%SYSTEMDRIVE%\\\$Recycle\.Bin|\$env:SYSTEMDRIVE\\\$Recycle\.Bin"; 
union DeviceProcessEvents, DeviceEvents, DeviceFileEvents
| extend Cmd = coalesce(tostring(ProcessCommandLine), tostring(InitiatingProcessCommandLine), tostring(AdditionalFields))
| extend PathField = coalesce(tostring(FolderPath), tostring(PreviousFolderPath), tostring(FileName), tostring(PreviousFileName))
| where isnotempty(Cmd) or isnotempty(PathField)
| where (isnotempty(Cmd) and Cmd matches regex pattern) or (isnotempty(PathField) and PathField matches regex pathPattern)
| extend MatchedFragment = case(isnotempty(Cmd) and Cmd matches regex pattern, extract(pattern, 0, Cmd), extract(pathPattern, 0, PathField))
| extend EnvVars = extract_all(@"(%[A-Za-z0-9_]+%|\$env:[A-Za-z0-9_]+)", Cmd)
| project TimeGenerated, DeviceName, DeviceId, AccountName, InitiatingProcessAccountName, FileName, InitiatingProcessFileName, ProcessId, InitiatingProcessId, Cmd, MatchedFragment, EnvVars, FolderPath, PathField, ActionType, ReportId, SourceSystem
| order by TimeGenerated desc
| take 500
pass2364.67s0.0147
gpt-5-mini-low
no answer
no query generatedfail50.00s0.0325
gpt-5-mini-medium
"cmd.exe" /c rd /s /q %systemdrive%\$RECYCLE.BIN
// Suspicious Recycle Bin clearing - search for commands targeting Recycle Bin paths and common deletion cmdlets
let recyclePatterns = dynamic(["\\$Recycle.Bin","Recycle.Bin","\\$RECYCLE.BIN","Clear-RecycleBin","Remove-Item","rd /s /q","rd /q /s","rmdir /s /q","del /f /s /q","del /s /q","del /f /q","forfiles /p","cleanmgr","cipher /w","EmptyRecycleBin","shell:RecycleBinFolder","\\%systemdrive%\\$Recycle.Bin","$env:systemdrive","%systemdrive%","$Recycle"]);

// Helper to test if any pattern is in the given string (case-insensitive)
let containsAny = (s:string){
    tolower(s)
};

// 1) Query process events for suspicious command lines
let proc_matches = DeviceProcessEvents
| where isnotempty(ProcessCommandLine) or isnotempty(InitiatingProcessCommandLine)
| extend combinedCmd = strcat(ProcessCommandLine, " ", InitiatingProcessCommandLine)
| where combinedCmd has_any ("$Recycle.Bin","Recycle.Bin","Clear-RecycleBin","Remove-Item","rd /s /q","rmdir /s /q","del /f /s /q","del /s /q","Remove-Item -Recurse","EmptyRecycleBin","$env:systemdrive","%systemdrive%")
| extend MatchedPattern = iff(combinedCmd has_cs "$Recycle.Bin" or combinedCmd has_cs "$RECYCLE.BIN" or combinedCmd has_cs "Recycle.Bin", "Recycle.Bin",
                    iff(combinedCmd has_cs "Clear-RecycleBin", "Clear-RecycleBin",
                    iff(combinedCmd has_cs "Remove-Item", "Remove-Item",
                    iff(combinedCmd has_cs "rd /s /q" or combinedCmd has_cs "rmdir /s /q", "rd/rmdir /s/q",
                    iff(combinedCmd has_cs "del /f /s /q" or combinedCmd has_cs "del /s /q", "del /s/q", "other")))))
| project TimeGenerated, DeviceName, AccountName, AccountDomain, ProcessId, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessCreationTime, MatchedPattern, ReportId
;

// 2) File events that show removal from recycle paths
let file_matches = DeviceFileEvents
| where isnotempty(FolderPath) or isnotempty(FileName) or isnotempty(PreviousFolderPath)
| where FolderPath has_any ("$Recycle.Bin","Recycle.Bin","%systemdrive%\\$Recycle.Bin","\\$Recycle.Bin","$env:systemdrive")
   or PreviousFolderPath has_any ("$Recycle.Bin","Recycle.Bin")
   or FileName has_any ("$Recycle.Bin","Recycle.Bin")
| project TimeGenerated, DeviceName, AccountName = InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, ActionType, FileName, FolderPath, PreviousFolderPath, ReportId
;

// 3) Events table (legacy) for other actions
let generic_matches = DeviceEvents
| where isnotempty(ProcessCommandLine) or isnotempty(InitiatingProcessCommandLine) or isnotempty(RegistryKey) or isnotempty(FolderPath)
| where ProcessCommandLine has_any ("$Recycle.Bin","Recycle.Bin","Clear-RecycleBin","Remove-Item","rd /s /q","del /f /s /q","%systemdrive%","$env:systemdrive")
    or InitiatingProcessCommandLine has_any ("$Recycle.Bin","Recycle.Bin","Clear-RecycleBin","Remove-Item","rd /s /q","del /f /s /q","%systemdrive%","$env:systemdrive")
    or FolderPath has_any ("$Recycle.Bin","Recycle.Bin")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessCommandLine, FileName, FolderPath, ActionType, ReportId
;

// Combine and rank by time
union isfuzzy=true proc_matches, file_matches, generic_matches
| extend RawCommand = coalesce(ProcessCommandLine, InitiatingProcessCommandLine)
| extend RawCommand = trim(" ", RawCommand)
| extend DetectedTime = TimeGenerated
| summarize FirstSeen = min(DetectedTime), LastSeen = max(DetectedTime), Count = count(), AnyDevices = dcount(DeviceName), Devices = make_set(DeviceName, 50), Accounts = make_set(AccountName, 50), SampleCommand = any(RawCommand), SampleInitiating = any(InitiatingProcessCommandLine), MatchedPatterns = make_set(MatchedPattern) by tostring(ReportId)
| order by FirstSeen desc
| project ReportId, FirstSeen, LastSeen, Count, AnyDevices, Devices, Accounts, SampleCommand, SampleInitiating, MatchedPatterns
| take 100
pass124.24s0.0075
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0092
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0111
grok-3-beta
rd
DeviceProcessEvents
| where ProcessCommandLine has 'rd' or ProcessCommandLine has 'rmdir'
| where ProcessCommandLine contains '$Recycle.Bin' or ProcessCommandLine contains 'Recycler'
| project Timestamp, DeviceName, AccountName, AccountDomain, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc
fail19.39s0.0211
grok-3-mini-beta
"cmd.exe" /c rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where ProcessCommandLine contains "Clear-RecycleBin" or (ProcessCommandLine contains "rd" and ProcessCommandLine contains "$Recycle.Bin")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessCommandLine
| order by TimeGenerated desc
pass115.83s0.0016
o1-high
rd /s /q %systemdrive%\$RECYCLE.BIN
// Look for process creation events that reference 'Clear-RecycleBin', '$Recycle.Bin',
// or typical 'rd' and other deletion commands targeting the Recycle Bin.
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where isnotempty(ProcessCommandLine)
| where ProcessCommandLine has_any ("Clear-RecycleBin", "recycle", "$Recycle.Bin", "rd", "rmdir", "del", "erase", "sdelete")
// Filter further to include typical switches or environment variables
| where ProcessCommandLine matches regex @"(?i)(clear-recyclebin|\$recycle\.bin|rd(\s+.*?\/s\s+.*?\/q)?|rmdir(\s+.*?\/s\s+.*?\/q)?|del|erase|sdelete)"
| project TimeGenerated, DeviceName, AccountDomain, InitiatingProcessAccountName, ProcessCommandLine, FolderPath, MachineGroup
| order by TimeGenerated desc
pass142.35s0.3291
o1-low
cmd.exe /c rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where tolower(ProcessCommandLine) has "$recycle.bin" 
  or tolower(ProcessCommandLine) has "clear-recyclebin" 
  or tolower(ProcessCommandLine) has "rd /s /q"
| project Timestamp, DeviceName, AccountDomain, AccountName, InitiatingProcessCommandLine, ProcessCommandLine, FolderPath, MD5, SHA256
| order by Timestamp desc
pass128.21s0.2270
o3-high
"cmd.exe" /c rd /s /q %systemdrive%\$RECYCLE.BIN
// -------------  Recycle-bin wipe hunting -------------
// NOTE: The global time-range that the hunting portal / API runner supplies
// will automatically scope TimeGenerated – do not hard-code dates.
//
// Logic
// 1. Look at all process-creation telemetry ( DeviceProcessEvents + the older
//    DeviceEvents table when ActionType == "CreateProcess" ).
// 2. Keep only entries whose command line contains well-known ways of
//    clearing the recycle bin:
//       • PowerShell Clear-RecycleBin cmdlet
//       • Cmd/PowerShell use of rd|del /s /q against  "$Recycle.Bin" or the legacy "\recycler" folder
//       • Use of cipher /w:  for a secure wipe of that folder
//       • Any of the same paths expressed through environment variables such
//         as %systemdrive% or %homedrive%
// 3. Project the most relevant context so the analyst can see **exactly** what
//    was executed, by whom, and from where.

let recycleBinIndicators = dynamic([
    "clear-recyclebin",                   // PowerShell cmdlet
    "\\$recycle.bin",                    // Current folder name (any drive)
    "\\recycler",                         // Legacy folder name (pre-Vista)
    "%recycle.bin%",                      // Suspicious env-var use
    "%systemdrive%\\$recycle.bin",        // Env-var + path
    "%homedrive%\\$recycle.bin",          // Env-var + path
    "rd /s /q",                           // Silent folder removal
    "del /s /q",                          // Silent file removal
    "cipher /w:"                           // Secure wipe
]);

union isfuzzy=true
    (DeviceProcessEvents
        | where ActionType == "ProcessCreated"
        | project-reorder TimeGenerated, DeviceId, DeviceName, AccountDomain, AccountName, FileName, ProcessCommandLine, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, ReportId, SHA256, Type
        | extend SourceTable = "DeviceProcessEvents")
,
    (DeviceEvents
        | where ActionType == "CreateProcess"
        | project-reorder TimeGenerated, DeviceId, DeviceName, AccountDomain, AccountName, FileName, ProcessCommandLine, InitiatingProcessAccountDomain, InitiatingProcessAccountName, InitiatingProcessCommandLine, ReportId, SHA256, Type
        | extend SourceTable = "DeviceEvents")
| where isnotempty(ProcessCommandLine)
| extend CommandLower = tolower(ProcessCommandLine)
| where CommandLower has_any (recycleBinIndicators)
// Tighten the filter – make sure the command actually targets the recycle-bin
| where CommandLower matches regex @"(clear\-recyclebin)|((rd|del)\s+[^|]*\$recycle\.bin)|(cipher\s+/w:[^|]*\$recycle\.bin)"
| extend RecycleWipeTechnique = case(
        CommandLower has "clear-recyclebin",          "PowerShell Clear-RecycleBin",
        CommandLower matches regex @"(rd|del)\s+[^|]*\$recycle\.bin", "cmd.exe rd/del against $Recycle.Bin",
        CommandLower has "cipher /w:",                 "cipher /w: secure wipe",
        "Other")
| project TimeGenerated,
          DeviceName,
          Account = strcat(AccountDomain, "\\", AccountName),
          FileName,
          ProcessCommandLine,
          RecycleWipeTechnique,
          InitiatingProcess = strcat(InitiatingProcessAccountDomain, "\\", InitiatingProcessAccountName),
          InitiatingProcessCommandLine,
          SHA256,
          SourceTable
| order by TimeGenerated desc
pass279.08s0.0446
o3-mini-high
rd
DeviceProcessEvents
| where isnotempty(InitiatingProcessCommandLine) and (
      InitiatingProcessCommandLine contains "$Recycle.Bin" 
   or InitiatingProcessCommandLine contains "Clear-RecycleBin"
   or (InitiatingProcessCommandLine has "rd" and InitiatingProcessCommandLine contains "$Recycle.Bin")
   or (ProcessCommandLine contains "$Recycle.Bin")
   or (ProcessCommandLine contains "Clear-RecycleBin")
   )
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, InitiatingProcessCommandLine, ProcessCommandLine, ProcessId
| order by TimeGenerated desc
fail120.31s0.0167
o3-mini-low
no answer
no query generatedfail50.00s0.0385
o4-mini-high
cmd.exe /c rd /s /q %systemdrive%\$RECYCLE.BIN
DeviceProcessEvents
| where ProcessCommandLine has "$Recycle.Bin"
    or ProcessCommandLine has "Clear-RecycleBin"
    or (ProcessCommandLine has "Remove-Item" and ProcessCommandLine has "Recycle.Bin")
    or (ProcessCommandLine has "rd " and ProcessCommandLine has "Recycle.Bin")
    or (ProcessCommandLine has "%SystemDrive%" and ProcessCommandLine has "Recycle.Bin")
    or (ProcessCommandLine has "$env:SystemDrive" and ProcessCommandLine has "Recycle.Bin")
| project Timestamp=TimeGenerated,
          DeviceName,
          AccountName=InitiatingProcessAccountName,
          ProcessCommandLine
| sort by Timestamp desc
pass146.58s0.0156
o4-mini-low
rd
let clearPattern = @"(?i)(?:\b(?:rd|rmdir)\b.*\$Recycle\.Bin|\bClear-RecycleBin\b)";
DeviceProcessEvents
| where ProcessCommandLine matches regex clearPattern
| project TimeGenerated,
          DeviceName,
          AccountDomain,
          AccountName,
          ParentProcess = InitiatingProcessFileName,
          Executable = FileName,
          ProcessId,
          CommandLine = ProcessCommandLine
| sort by TimeGenerated desc
fail384.20s0.0270