// question

Review Windows process creation events for evidence of a .NET assembly being installed. Which executable was launched with an "/action=install" argument?

Reference KQL answer and model-by-model comparison.

9f9968a6-601a-46ca-b7b7-6d4fe0f98f0b
question id
20/23
models correct
1
valid answer
87%
success rate
// reference answer

Human-validated correct answer for this question.

InstallUtil
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
InstallUtil.exe
DeviceProcessEvents | where ActionType == "ProcessCreated" | where ProcessCommandLine contains "/action=install" | project Timestamp, DeviceName, FileName, ProcessCommandLine
pass18.99s0.0038
gpt-35-turbo
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine contains "/action=install"
| project FileName
pass12.32s0.0023
gpt-4-turbo-2024-04-09
InstallUtil.exe
DeviceProcessEvents
| where ActionType == 'ProcessCreated' and ProcessCommandLine has '/action=install'
| project DeviceName, ProcessId, ProcessCommandLine, InitiatingProcessFileName, TimeGenerated
pass112.91s0.0567
gpt-4.1
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine has "/action=install"
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine
pass13.87s0.0113
gpt-4.1-finetuned
none
DeviceProcessEvents
| where Timestamp > ago(1d)
| where ProcessCommandLine has "/action=install"
| summarize uniqueProcesses = make_set(FolderPath)
| extend uniqueProcessesCount = array_length(uniqueProcesses)
| project uniqueProcessesCount, uniqueProcesses
| order by uniqueProcessesCount desc
fail28.61s0.0199
gpt-4.1-mini
powershell.exe
DeviceProcessEvents
| where ActionType == 'ProcessCreated'
| where InitiatingProcessCommandLine contains "/action=install"
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by Timestamp desc
fail13.32s0.0025
gpt-4.1-nano
InstallUtil.exe
DeviceProcessEvents 
| where ProcessCommandLine contains '/action=install'
| project ProcessId, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCreationTime, DeviceName, InitiatingProcessParentFileName
pass12.20s0.0006
gpt-4o
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine has "/action=install"
| project DeviceName, FileName, ProcessCommandLine, ProcessCreationTime
pass12.97s0.0150
gpt-5-high
InstallUtil.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine matches regex @"(?i)[/-]action\s*=\s*install"
| summarize EventCount=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), SampleCommandLine=any(ProcessCommandLine) by FileName, FolderPath
| order by EventCount desc, LastSeen desc
pass158.62s0.0336
gpt-5-mini-high
InstallUtil.exe
// Find processes launched with "/action=install" in command line
let argPattern = @"/action=install";
// Check DeviceProcessEvents first
DeviceProcessEvents
| where tolower(ProcessCommandLine) contains tolower(argPattern)
| project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256, MD5
| extend SourceTable = "DeviceProcessEvents"

| union (
    // DeviceEvents may store process creation logs in some tenants
    DeviceEvents
    | where tolower(ProcessCommandLine) contains tolower(argPattern) or tolower(InitiatingProcessCommandLine) contains tolower(argPattern)
    | project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256, MD5
    | extend SourceTable = "DeviceEvents"
)

| union (
    // Additional coverage: DeviceFileEvents (initiating process fields)
    DeviceFileEvents
    | where tolower(InitiatingProcessCommandLine) contains tolower(argPattern) or tolower(InitiatingProcessFileName) contains tolower(argPattern)
    | project TimeGenerated, DeviceName, FileName = InitiatingProcessFileName, ProcessId = InitiatingProcessId, ProcessCommandLine = InitiatingProcessCommandLine, ProcessCreationTime = InitiatingProcessCreationTime, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256 = InitiatingProcessSHA256, MD5 = InitiatingProcessMD5
    | extend SourceTable = "DeviceFileEvents"
)

| union (
    // Image loads sometimes show modules loaded by installers
    DeviceImageLoadEvents
    | where tolower(InitiatingProcessCommandLine) contains tolower(argPattern)
    | project TimeGenerated, DeviceName, FileName = InitiatingProcessFileName, ProcessId = InitiatingProcessId, ProcessCommandLine = InitiatingProcessCommandLine, ProcessCreationTime = InitiatingProcessCreationTime, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256 = InitiatingProcessSHA256, MD5 = InitiatingProcessMD5
    | extend SourceTable = "DeviceImageLoadEvents"
)

// Deduplicate by device + process id + command line
| summarize arg_count = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by DeviceName, ProcessId, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256, MD5, SourceTable
| order by FirstSeen desc
| project FirstSeen, LastSeen, DeviceName, FileName, ProcessId, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256, MD5, SourceTable, arg_count
pass114.68s0.0041
gpt-5-mini-low
InstallUtil.exe
// Find processes where the command line contains "/action=install" (case-insensitive) in DeviceProcessEvents and DeviceEvents
let installArg = "/action=install";
let dpe = DeviceProcessEvents
| where isnotempty(ProcessCommandLine) and tostring(ProcessCommandLine) !="" and tolower(ProcessCommandLine) contains installArg
| where ActionType in ("ProcessCreated","Creation","Created","Process created","ProcessCreation")
| extend CmdLine = ProcessCommandLine, ProcFile = FileName
| project TimeGenerated, Timestamp, DeviceName, DeviceId, ProcFile, PID = ProcessId, CmdLine, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, SHA256, MD5, ActionType;
let de = DeviceEvents
| where isnotempty(ProcessCommandLine) and tostring(ProcessCommandLine) != "" and tolower(ProcessCommandLine) contains installArg
| where ActionType in ("ProcessCreated","Creation","Created","Process created","ProcessCreation")
| extend CmdLine = ProcessCommandLine, ProcFile = FileName
| project TimeGenerated, Timestamp, DeviceName, DeviceId, ProcFile, PID = ProcessId, CmdLine, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, SHA256, MD5, ActionType;
union isfuzzy=true dpe, de
| summarize arg_max(TimeGenerated, *) by DeviceId, PID, CmdLine
| order by TimeGenerated desc
| project TimeGenerated, DeviceName, DeviceId, ProcFile, PID, CmdLine, ProcessCreationTime, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine, SHA256, MD5, ActionType
| take 100
pass220.42s0.0057
gpt-5-mini-medium
InstallUtil.exe
(
    DeviceProcessEvents
    | where tostring(ProcessCommandLine) has_cs "/action=install" or tolower(tostring(ProcessCommandLine)) has "/action=install"
    | project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, AccountName, AccountDomain, SHA256, MD5, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId
)
| union (
    DeviceEvents
    | where tostring(ProcessCommandLine) has_cs "/action=install" or tolower(tostring(ProcessCommandLine)) has "/action=install"
    | project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, AccountName, AccountDomain, SHA256, MD5, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId
)
| distinct TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, AccountName, AccountDomain, SHA256, MD5, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId
| order by TimeGenerated desc
| extend MatchedArgument = 
    case(
        tolower(tostring(ProcessCommandLine)) contains "/action=install", "/action=install",
        tolower(tostring(InitiatingProcessCommandLine)) contains "/action=install", "/action=install",
        ""
    )
| where MatchedArgument != ""
| project TimeGenerated, DeviceName, FileName, ProcessId, ProcessCommandLine, AccountName, AccountDomain, SHA256, MD5, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId, MatchedArgument
pass114.63s0.0039
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0078
gpt-5-nano-medium
InstallUtil.exe
DeviceProcessEvents
| where (ProcessCommandLine contains "/action=install" or InitiatingProcessCommandLine contains "/action=install")
| extend ExecutableLaunched = FileName, ExecutablePath = FolderPath
| project TimeGenerated, DeviceName, ExecutableLaunched, ExecutablePath, CommandLine = ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc
| take 100
pass139.19s0.0020
grok-3-beta
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine contains "/action=install"
| project DeviceName, FileName, ProcessCommandLine, ProcessCreationTime
| order by ProcessCreationTime desc
pass110.56s0.0214
grok-3-mini-beta
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine contains '/action=install'
| distinct FileName, ProcessCommandLine, Timestamp
| project FileName, ProcessCommandLine, Timestamp
pass113.24s0.0016
o1-high
InstallUtil.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine has "/action=install"
| project TimeGenerated, DeviceName, FileName, FolderPath, ProcessCommandLine
| order by TimeGenerated desc
pass126.16s0.1952
o1-low
InstallUtil.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where tolower(ProcessCommandLine) contains "/action=install"
| project TimeGenerated, DeviceName, FileName, FolderPath, ProcessCommandLine
| order by TimeGenerated desc
pass231.53s0.2434
o3-high
InstallUtil.exe
DeviceProcessEvents
// Time filter is applied automatically by the hunting UI / workbook. Remove or modify the next line if you need a fixed range.
//| where TimeGenerated between (datetime(2024-01-01) .. datetime(2024-01-31))
| where tolower(ProcessCommandLine) has "/action=install"
// Focus on process creation events if ActionType is populated in your environment
//| where ActionType == "CreateProcess" or isnull(ActionType)
| project TimeGenerated,
          DeviceName,
          FileName,
          FolderPath,
          ProcessCommandLine,
          AccountName,
          AccountDomain,
          InitiatingProcessFileName,
          InitiatingProcessCommandLine
| summarize FirstSeen = min(TimeGenerated),
            LastSeen  = max(TimeGenerated),
            LaunchCount = count()
          by DeviceName, FileName, FolderPath, ProcessCommandLine
| order by LastSeen desc
pass131.55s0.0229
o3-mini-high
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine contains "/action=install"
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine
pass17.41s0.0094
o3-mini-low
InstallUtil.exe
DeviceProcessEvents
| where ProcessCommandLine has "/action=install"
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, ProcessId
pass121.70s0.0137
o4-mini-high
InstallUtil.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where tolower(ProcessCommandLine) contains "/action=install"
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine
| sort by TimeGenerated desc
pass246.38s0.0162
o4-mini-low
InstallUtil.exe
DeviceProcessEvents
| where ActionType == "ProcessCreated"
| where ProcessCommandLine has "/action=install"
| project TimeGenerated, DeviceName, Executable = FileName, ProcessCommandLine
| order by TimeGenerated desc
pass240.11s0.0117