// question

A suspicious actor appears to have removed the USN change journal on a Windows workstation. Investigate process start records to find out exactly which command was used to delete the journal. What was the full command line invoked?

Reference KQL answer and model-by-model comparison.

b4115c7a-0e92-47f0-a61e-17e7218b2435
question id
18/23
models correct
1
valid answer
78%
success rate
// reference answer

Human-validated correct answer for this question.

fsutil usn deletejournal /D C:\\
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine contains "fsutil usn deletejournal"
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine
| order by TimeGenerated asc
pass110.54s0.0045
gpt-35-turbo
no answer
no query generatedfail50.00s0.0110
gpt-4-turbo-2024-04-09
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ActionType == 'ProcessCreated'
| where InitiatingProcessCommandLine has 'fsutil' and InitiatingProcessCommandLine has 'usn' and InitiatingProcessCommandLine has 'deletejournal'
| project DeviceName, InitiatingProcessCommandLine, ProcessCreationTime
pass322.02s0.1429
gpt-4.1
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ProcessCommandLine has_any ("usn deletejournal", "fsutil usn deletejournal")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessCommandLine
pass15.80s0.0121
gpt-4.1-finetuned
fsutil usn deletejournal /D C:
DeviceProcessEvents // Use DeviceProcessEvents for process-level details
| where ProcessCommandLine contains "usn" and ProcessCommandLine contains "deletejournal"
| project TimeGenerated, DeviceName, InitiatingProcessAccountName, ProcessCommandLine, ActionType, FolderPath
| order by TimeGenerated desc
| take 1 // Ensure you only get the most recent event
pass414.93s0.0305
gpt-4.1-mini
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ProcessCommandLine has_any ("fsutil usn deletejournal", "fsutil usn delete", "$UsnJrnl")
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, ProcessCreationTime
| order by TimeGenerated desc
pass13.49s0.0023
gpt-4.1-nano
no answer
no query generatedfail50.00s0.0013
gpt-4o
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ActionType =~ "ProcessCreated" and (ProcessCommandLine contains "delete" and ProcessCommandLine contains "USN" and ProcessCommandLine contains "journal")
| project DeviceName, ProcessCommandLine, InitiatingProcessCommandLine, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCreationTime, InitiatingProcessAccountName, InitiatingProcessAccountDomain
| limit 100
pass530.24s0.0694
gpt-5-high
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where FileName =~ "fsutil.exe" or ProcessCommandLine has "fsutil"
| where ProcessCommandLine has_all ("usn", "deletejournal")
| project Time=ProcessCreationTime, DeviceName, AccountDomain, AccountName, FileName, FolderPath, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountDomain, InitiatingProcessAccountName
| order by Time desc
pass151.40s0.0460
gpt-5-mini-high
fsutil usn deletejournal /D C:
// Search DeviceProcessEvents and DeviceEvents for process start records matching USN change journal deletion commands
let keywords = dynamic(["usn","deletejournal","delete journal","fsutil usn","usn delete"]);
// Helper to search a table for matching commandlines
let SearchTable = (tableName: string) {
    toscalar(
        // we can't dynamic reference table by name easily, so we'll rely on union below
        print dummy=1
    )
};

// Union the two relevant tables that contain process creation info
union isfuzzy=true DeviceProcessEvents, DeviceEvents, DeviceFileEvents, DeviceImageLoadEvents
| where TimeGenerated between (startofday(ago(30d)) .. now()) // placeholder; time range in function call will override
| extend cmd = coalesce(ProcessCommandLine, InitiatingProcessCommandLine, ProcessCommandLine, ProcessCommandLine)
| where isnotempty(cmd)
| where cmd has_any ("usn", "deletejournal") or cmd contains_cs("fsutil usn") or cmd has_any ("\"deletejournal\"", "delete journal", "usn delete")
| project TimeGenerated, DeviceName, DeviceId, ReportId, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessAccountName, ProcessId, ProcessCommandLine=cmd, ActionType, FileName
| distinct DeviceName, DeviceId, InitiatingProcessId, ProcessId, ProcessCommandLine, TimeGenerated, InitiatingProcessFileName, InitiatingProcessAccountName, ActionType, ReportId, FileName
| order by TimeGenerated desc
| take 100
pass119.81s0.0051
gpt-5-mini-low
"cmd.exe" /c fsutil usn deletejournal /D C:
(DeviceProcessEvents
| where isnotempty(ProcessCommandLine)
| where tostring(tolower(ProcessCommandLine)) has "usn" and (tostring(tolower(ProcessCommandLine)) has "deletejournal" or tostring(tolower(ProcessCommandLine)) has "delete journal")
| project TimeGenerated, Timestamp, DeviceName, ProcessCommandLine, FileName, ProcessId, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessId, AccountName, AccountDomain = AccountDomain, InitiatingProcessAccountName, InitiatingProcessAccountDomain, ReportId, _ResourceId
)

| union (
    DeviceEvents
    | where isnotempty(ProcessCommandLine) or isnotempty(InitiatingProcessCommandLine)
    | extend ProcessCommandLine2 = iff(isnotempty(ProcessCommandLine), ProcessCommandLine, InitiatingProcessCommandLine)
    | where tostring(tolower(ProcessCommandLine2)) has "usn" and (tostring(tolower(ProcessCommandLine2)) has "deletejournal" or tostring(tolower(ProcessCommandLine2)) has "delete journal")
    | project TimeGenerated, Timestamp, DeviceName, ProcessCommandLine = ProcessCommandLine2, FileName, ProcessId = coalesce(ProcessId, InitiatingProcessId), ProcessCreationTime = coalesce(ProcessCreationTime, InitiatingProcessCreationTime), InitiatingProcessFileName, InitiatingProcessId, AccountName, AccountDomain = AccountDomain, InitiatingProcessAccountName, InitiatingProcessAccountDomain, ReportId, _ResourceId
)

| extend CommandLower = tostring(tolower(ProcessCommandLine))
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), AnyProcessName = any(FileName), AnyInitiating = any(InitiatingProcessFileName), AnyProcessId = any(ProcessId), AnyAccount = any(iff(isnotempty(AccountName), AccountName, InitiatingProcessAccountName)), SampleCommand = any(ProcessCommandLine) by CommandLower, DeviceName
| project DeviceName, FirstSeen, LastSeen, AnyAccount, AnyProcessName, AnyInitiating, AnyProcessId, SampleCommand
| order by FirstSeen desc
| limit 100
pass119.57s0.0050
gpt-5-mini-medium
cmd.exe /c fsutil usn deletejournal /D C:
// Look for process creation events showing deletion of USN change journal
let keywords = dynamic(["fsutil","usn","deletejournal","esentutl","esentutl /r","esentutl /p","del"]);
DeviceProcessEvents
| where TimeGenerated between (startofday(ago(30d)) .. now())
// ProcessCreationTime/TimeGenerated timeframe will be set by function call, but include a 30d fallback
| where tostring(ProcessCommandLine) != ""
| where tolower(ProcessCommandLine) contains "usn" and tolower(ProcessCommandLine) contains "deletejournal"
// Include common variants and other utilities that might be used
| where tolower(ProcessCommandLine) contains "fsutil" or tolower(ProcessCommandLine) contains "esentutl" or tolower(ProcessCommandLine) contains "deletejournal"
| project TimeGenerated, DeviceName, DeviceId, AccountName, AccountDomain, AccountSid, InitiatingProcessAccountName, InitiatingProcessAccountDomain, InitiatingProcessId, InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessId, FileName, ProcessCommandLine, ProcessCreationTime, ReportId
| extend FullCommandLine = iff(isnotempty(ProcessCommandLine), ProcessCommandLine, InitiatingProcessCommandLine)
| summarize any(FullCommandLine) by DeviceName, DeviceId, ProcessId, InitiatingProcessId, ProcessCreationTime, TimeGenerated, AccountName, InitiatingProcessAccountName, InitiatingProcessFileName, FileName
| order by TimeGenerated desc
| take 50

// Fallback to DeviceEvents if no hits in DeviceProcessEvents
| union (
    DeviceEvents
    | where TimeGenerated between (startofday(ago(30d)) .. now())
    | where tostring(ProcessCommandLine) != ""
    | where tolower(ProcessCommandLine) contains "usn" and tolower(ProcessCommandLine) contains "deletejournal"
    | project TimeGenerated, DeviceName, DeviceId, AccountName, AccountDomain, AccountSid, InitiatingProcessAccountName, InitiatingProcessAccountDomain, InitiatingProcessId, InitiatingProcessFileName = InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessId = InitiatingProcessId, FileName = InitiatingProcessFileName, ProcessCommandLine = InitiatingProcessCommandLine, ProcessCreationTime = InitiatingProcessCreationTime
    | extend FullCommandLine = ProcessCommandLine
    | order by TimeGenerated desc
    | take 50
)
| distinct *
pass119.37s0.0052
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0069
gpt-5-nano-medium
no answer
no query generatedfail50.00s0.0055
grok-3-beta
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ProcessCommandLine contains "fsutil" and ProcessCommandLine contains "deletejournal"
| project Timestamp, DeviceName, AccountName, ProcessCommandLine
| order by Timestamp desc
pass18.38s0.0207
grok-3-mini-beta
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ProcessCommandLine contains "fsutil" and ProcessCommandLine contains "usn" and ProcessCommandLine contains "deletejournal"
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine
| order by TimeGenerated desc
| limit 10
pass111.21s0.0016
o1-high
fsutil usn deletejournal /D C:
union DeviceProcessEvents, DeviceEvents
| where ActionType in~ ("CreateProcess","ProcessCreated")
| where isnotempty(ProcessCommandLine) or isnotempty(InitiatingProcessCommandLine)
| where (ProcessCommandLine has "fsutil" or InitiatingProcessCommandLine has "fsutil")
  and ((ProcessCommandLine has_any ("usn", "deletejournal") or InitiatingProcessCommandLine has_any ("usn", "deletejournal")))
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessCommandLine
| order by TimeGenerated desc
pass399.25s0.7405
o1-low
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ProcessCommandLine has_any ("deletejournal", "usn")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, FolderPath, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessFileName
| order by TimeGenerated desc
pass160.66s0.3655
o3-high
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ActionType == "ProcessCreated"               // only process start events
| where tolower(ProcessCommandLine) has_all ("fsutil", "usn", "deletejournal")
// optional: keep devices or users of interest
// | where DeviceName =~ "<suspect host>"
| project TimeGenerated,
          DeviceName,
          AccountDomain,
          AccountName,
          FileName,
          ProcessCommandLine,
          FolderPath,
          InitiatingProcessFileName,
          InitiatingProcessCommandLine,
          InitiatingProcessAccountDomain,
          InitiatingProcessAccountName
| order by TimeGenerated desc
pass142.98s0.0264
o3-mini-high
cmd.exe /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where InitiatingProcessCommandLine has_cs "fsutil" and InitiatingProcessCommandLine has_cs "deletejournal"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine
| sort by TimeGenerated asc
pass117.47s0.0079
o3-mini-low
"cmd.exe" /c fsutil usn deletejournal /D C:
DeviceProcessEvents
| where InitiatingProcessCommandLine contains "fsutil" and InitiatingProcessCommandLine contains "deleteJournal"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine
| sort by TimeGenerated asc
pass149.38s0.0098
o4-mini-high
fsutil usn deletejournal /D C:
DeviceProcessEvents
| where ActionType == "ProcessCreated"
// Look specifically for the fsutil usn deletejournal command
| where tolower(FileName) == "fsutil.exe" 
      and tolower(ProcessCommandLine) contains "usn" 
      and tolower(ProcessCommandLine) contains "deletejournal"
// Show the relevant details including the full command line
| project TimeGenerated, DeviceName, AccountName, ProcessId, ProcessCommandLine
| sort by TimeGenerated asc
pass244.55s0.0174
o4-mini-low
no answer
no query generatedfail50.00s0.0332