// question

A Windows host logs a change to the Terminal Server registry key disabling single-session per user. Which command-line utility executed this registry modification?

Reference KQL answer and model-by-model comparison.

35727d9e-7a7f-4d0c-a259-dc3906d6e8b9
question id
14/23
models correct
1
valid answer
61%
success rate
// reference answer

Human-validated correct answer for this question.

reg
// model comparison
ModelAnswerKQL queryStatusTriesTimeCost
gemini-2.5-flash-preview-04-17
no answer
no query generatedfail50.00s0.0170
gpt-35-turbo
no answer
no query generatedfail50.00s0.0115
gpt-4-turbo-2024-04-09
reg
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server" and RegistryValueData == "0"
| summarize by InitiatingProcessCommandLine
| distinct InitiatingProcessCommandLine
pass111.71s0.0504
gpt-4.1
no answer
no query generatedfail50.00s0.0476
gpt-4.1-finetuned
no answer
no query generatedfail50.00s0.0543
gpt-4.1-mini
reg
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server" and RegistryValueName == "fSingleSessionPerUser"
| project TimeGenerated, DeviceName, InitiatingProcessCommandLine
| order by TimeGenerated desc
pass13.07s0.0021
gpt-4.1-nano
reg.exe
DeviceRegistryEvents
| where RegistryKey has 'Terminal Server' and PreviousRegistryValueName == 'fSingleSessionPerUser' and RegistryValueData =~ '0'
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RegistryKey, RegistryValueData
pass220.60s0.0007
gpt-4o
reg
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server" and RegistryValueName == "fSingleSessionPerUser" and RegistryValueData == "0"
| project DeviceName, InitiatingProcessCommandLine, InitiatingProcessAccountName, TimeGenerated
pass223.82s0.0272
gpt-5-high
reg.exe
let reg_change =
DeviceRegistryEvents
| where RegistryValueName =~ "fSingleSessionPerUser"
| where RegistryKey has @"\Control\Terminal Server"
| where RegistryKey startswith "HKEY_LOCAL_MACHINE" or RegistryKey startswith "HKLM"
| where ActionType == "RegistryValueSet"
| extend NewVal = tostring(RegistryValueData), OldVal = tostring(PreviousRegistryValueData)
| where NewVal in ("0", "00000000", "0x0", "0x00000000")
   or (OldVal in ("1", "00000001", "0x1", "0x00000001") and NewVal !in ("1", "00000001", "0x1", "0x00000001"))
| project TimeGenerated, DeviceId, DeviceName, RegistryKey, RegistryValueName, RegistryValueData,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessAccountDomain, InitiatingProcessAccountName;
reg_change
| summarize Events=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated)
          by DeviceId, DeviceName, Utility=InitiatingProcessFileName
| join kind=leftouter (
    reg_change
    | summarize arg_max(TimeGenerated, *) by DeviceId, Utility=InitiatingProcessFileName
    | project DeviceId, Utility, LatestTime=TimeGenerated, LatestCommandLine=InitiatingProcessCommandLine
  ) on DeviceId, Utility
| project DeviceName, Utility, LatestCommandLine, Events, FirstSeen, LastSeen
| order by LastSeen desc
pass3318.20s0.1594
gpt-5-mini-high
reg.exe
DeviceRegistryEvents
| where RegistryKey has_cs "Terminal Server" or RegistryKey has_cs "fSingleSessionPerUser" or RegistryValueName has_cs "fSingleSessionPerUser"
| where ActionType in ("RegistryValueSet", "RegistryValueDeleted", "RegistryKeyCreated", "RegistryKeyDeleted", "RegistryValueWrite", "SetValue", "SetValueKey", "Write")
| extend Key=RegistryKey, ValueName=coalesce(RegistryValueName, "")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessId, InitiatingProcessAccountName, InitiatingProcessAccountDomain, InitiatingProcessCreationTime, Key, ValueName, RegistryValueData, PreviousRegistryValueData, ActionType, ReportId
| sort by TimeGenerated desc
| limit 50

// Join with DeviceProcessEvents to enrich with parent process information and broader process command line context
| join kind=leftouter (
    DeviceProcessEvents
    | project ProcessTime=TimeGenerated, DeviceName2=DeviceName, ProcessId=ProcessId, ProcessFileName=FileName, ProcessCommandLine=ProcessCommandLine, InitiatingProcessParentId=InitiatingProcessParentId, InitiatingProcessParentFileName=InitiatingProcessParentFileName
) on $left.DeviceName == $right.DeviceName2 and $left.InitiatingProcessId == $right.ProcessId
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, ProcessFileName, ProcessCommandLine, InitiatingProcessId, InitiatingProcessAccountName, InitiatingProcessAccountDomain, InitiatingProcessCreationTime, Key, ValueName, RegistryValueData, PreviousRegistryValueData, ActionType
| sort by TimeGenerated desc
| limit 100
pass112.77s0.0042
gpt-5-mini-low
reg.exe
// Detect changes to Terminal Server single-session-per-user registry value and show initiating command-line utility
DeviceRegistryEvents
| where RegistryValueName =~ "fSingleSessionPerUser"
// include events where the key path references Terminal Server
| where RegistryKey contains "Terminal Server" or RegistryKey contains "\\Control\\Terminal Server"
// filter for value set/modify actions or when data is present
| where ActionType in ("SetValue", "SetValueKey", "ValueSet", "RegistryValueSet", "Modify", "Set") or isnotempty(RegistryValueData)
| extend ChangeTime = TimeGenerated
| project ChangeTime, DeviceName, DeviceId, InitiatingProcessId, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessAccountDomain, RegistryKey, RegistryValueName, RegistryValueData, PreviousRegistryValueData, ActionType
| sort by ChangeTime desc
| summarize arg_max(ChangeTime, *) by DeviceId, InitiatingProcessId, RegistryKey, RegistryValueName
| top 100 by ChangeTime
pass217.86s0.0044
gpt-5-mini-medium
reg.exe
let changes =
    union DeviceRegistryEvents, DeviceEvents
    | where isnotempty(RegistryKey)
    | extend rk = tolower(RegistryKey), rvn = tolower(RegistryValueName), rvd = tostring(RegistryValueData)
    // Look for Terminal Server registry path or the fSingleSessionPerUser value name
    | where rk contains "terminal server" or rvn contains "singlesession" or rvn contains "fsinglesessionperuser"
    // Value set to 0 (may appear as "0", "0x0", etc.) — adjust if you expect different encoding
    | where rvd contains "0" or rvd contains "0x0"
    | extend Executable = tolower(extract(@"([^\\]+)$", 1, InitiatingProcessFileName))
    | project TimeGenerated, DeviceName, Executable, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessId, RegistryKey, RegistryValueName, RegistryValueData, ActionType, ReportId;

// Recent matching events (detail)
changes
| sort by TimeGenerated desc
| take 50

// Summary by initiating executable
; changes
| summarize Events=count(), LastSeen=max(TimeGenerated) by Executable
| order by Events desc
| take 20
pass128.86s0.0068
gpt-5-nano-high
no answer
no query generatedfail50.00s0.0061
gpt-5-nano-medium
reg.exe
DeviceRegistryEvents
| where TimeGenerated >= ago(1d)
| where RegistryKey contains "Terminal Server" or RegistryKey contains "WinStations" or RegistryKey contains "TerminalServer"
| where RegistryValueName in ("fSingleSessionPerUser","SingleSessionPerUser")
| where RegistryValueData =~ "0"
| project TimeGenerated, DeviceName, DeviceId, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessCreationTime, InitiatingProcessId, InitiatingProcessAccountName, InitiatingProcessAccountDomain
| order by TimeGenerated desc
pass118.55s0.0019
grok-3-beta
no answer
no query generatedfail50.00s0.0856
grok-3-mini-beta
reg.exe
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server"
| where RegistryValueData == "0"  // Assuming '0' indicates the disabling of single-session per user
| project DeviceName, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessCommandLine, InitiatingProcessFileName, Timestamp
| summarize arg_max(Timestamp, *) by InitiatingProcessCommandLine  // Get the most recent event per unique command line
| order by Timestamp desc
pass115.10s0.0016
o1-high
reg.exe
DeviceRegistryEvents
| where RegistryKey has "Control\\Terminal Server" 
| where RegistryValueName =~ "fSingleSessionPerUser"
| where RegistryValueData == "0"
| project TimeGenerated, DeviceName, ActionType, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName, InitiatingProcessAccountDomain
pass119.51s0.1611
o1-low
reg.exe
DeviceRegistryEvents
| where RegistryKey has "\\Control\\Terminal Server"
| where RegistryValueName == "fSingleSessionPerUser"
| where RegistryValueData == "0"
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RegistryKey, RegistryValueData
| order by TimeGenerated desc
pass119.30s0.1544
o3-high
no answer
no query generatedfail50.00s0.1013
o3-mini-high
reg.exe
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server"
      and RegistryValueName == "fSingleSessionPerUser"
      and RegistryValueData =~ "0"
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RegistryKey, RegistryValueName, RegistryValueData
| sort by TimeGenerated desc
| limit 10
pass117.46s0.0098
o3-mini-low
reg.exe
DeviceRegistryEvents
| where RegistryKey contains "Terminal Server"
| where RegistryValueName == "fSingleSessionPerUser" and RegistryValueData == "0"
| project TimeGenerated, DeviceName, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by TimeGenerated desc
| take 20
pass143.90s0.0114
o4-mini-high
no answer
no query generatedfail50.00s0.0487
o4-mini-low
no answer
no query generatedfail50.00s0.0330