Agent Foskett Academy • KQL Academy • Module 14 • Lesson 162 • Detection Engineering & Proactive Threat Hunting

Lesson 162 — One Query Found the Same Technique on Twelve Devices

Lesson 161 began with behaviour instead of a known indicator. The hunt found an unusual parent-child relationship: user-facing applications launching PowerShell. Then the analyst widened the query.

The result changed the investigation. The same technique appeared on twelve devices. That could mean a widespread attack — or it could be a legitimate management tool, deployment package or business application behaving exactly as designed. The next job is scoping.

Finding the same behaviour on more devices increases the scope of the question. It does not automatically increase the certainty that the behaviour is malicious.
Agent Foskett KQL Academy environment-wide threat hunting across multiple devices
Your hunting result

The same suspicious PowerShell technique appears on twelve endpoints. Determine whether the devices share the same command, user, parent process and timing — or whether the similarity disappears when you inspect the evidence.

✓ Count affected devices
✓ Compare command lines
✓ Compare users and process ancestry
✓ Build a device-level scope register

Hunt briefing

BEHAVIOURAL HUNT Browser / Office / script host → PowerShell ↓ INITIAL RESULT One suspicious execution ↓ ENVIRONMENT-WIDE SEARCH Same technique appears on 12 devices ↓ TWO COMPETING HYPOTHESES A) WIDER ATTACK same technique spreading or repeated by an attacker B) LEGITIMATE ACTIVITY software deployment / automation / support tooling ↓ THE JOB Compare device + user + command + parent + time before deciding which hypothesis fits the evidence

Hunting objective

Use KQL to scope a behavioural hunting result across endpoints, determine how many devices and users are involved, identify repeated command lines and process ancestry, compare supporting behavioural signals and produce a device-level scope register for further investigation.

Hunter's rule

Scope before severity. Do not call twelve devices “twelve compromised devices” until the behaviour on those devices has actually been validated.

Stage 1 — count the devices that match the behaviour

Start by summarising the hunt result by device and parent process. This tells you whether the original technique is isolated or distributed and establishes first-seen and last-seen times for each endpoint.

01-scope-behaviour-by-device.kql
12345678910111213141516
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where InitiatingProcessFileName in~ (
    "winword.exe", "excel.exe", "outlook.exe",
    "chrome.exe", "msedge.exe", "firefox.exe",
    "wscript.exe", "cscript.exe", "mshta.exe"
)
| summarize Executions=count(),
            FirstSeen=min(Timestamp),
            LastSeen=max(Timestamp),
            Users=make_set(AccountName, 20)
          by DeviceName,
             InitiatingProcessFileName,
             FileName
| order by Executions desc

Device count changes the investigation

One endpoint invites deep inspection. Twelve endpoints require both deep inspection and environment-wide scoping so you understand whether you are looking at propagation, repeated delivery or legitimate enterprise activity.

Do not lose the users

If the same account appears across many devices, that may tell a different story from twelve unrelated users each triggering the same software package.

Stage 2 — find identical commands across multiple devices

Group by the initiating process and full PowerShell command line. Identical commands appearing across many endpoints can reveal a common deployment mechanism, script, attacker technique or shared artefact.

02-find-repeated-commands-across-devices.kql
12345678910111213141516
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where InitiatingProcessFileName in~ (
    "winword.exe", "excel.exe", "outlook.exe",
    "chrome.exe", "msedge.exe", "firefox.exe",
    "wscript.exe", "cscript.exe", "mshta.exe"
)
| summarize Devices=dcount(DeviceName),
            DeviceList=make_set(DeviceName, 100),
            Users=dcount(AccountName),
            FirstSeen=min(Timestamp),
            LastSeen=max(Timestamp)
          by InitiatingProcessFileName,
             ProcessCommandLine
| order by Devices desc

Identical can suggest coordination

A highly specific command repeated across devices is more informative than a generic powershell.exe launch. Preserve the complete command before normalising or shortening it.

But legitimate tooling repeats too

Software distribution systems are designed to execute the same command across many machines. Repetition is therefore evidence of commonality, not evidence of maliciousness.

Stage 3 — pivot from the repeated command back to raw events

Once a command appears on multiple devices, return to the underlying process events. This preserves individual timestamps, users, parent processes and hashes so the shared pattern can be tested rather than assumed.

03-pivot-repeated-command-to-raw-events.kql
123456789101112131415161718192021222324
let SuspiciousCommands =
    DeviceProcessEvents
    | where Timestamp > ago(7d)
    | where FileName in~ ("powershell.exe", "pwsh.exe")
    | where InitiatingProcessFileName in~ (
        "winword.exe", "excel.exe", "outlook.exe",
        "chrome.exe", "msedge.exe", "firefox.exe",
        "wscript.exe", "cscript.exe", "mshta.exe"
    )
    | summarize DeviceCount=dcount(DeviceName)
      by ProcessCommandLine
    | where DeviceCount >= 2;
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| join kind=inner SuspiciousCommands on ProcessCommandLine
| project Timestamp,
          DeviceName,
          AccountName,
          InitiatingProcessFileName,
          ProcessCommandLine,
          DeviceCount,
          SHA1
| order by ProcessCommandLine asc, Timestamp asc

Aggregation discovers; raw evidence explains

Summaries are excellent for finding patterns, but an incident conclusion should be supported by the underlying events. Always retain a path back from the aggregate to the source telemetry.

Look for divergence

If eleven devices have the same parent and user context but the twelfth is different, that outlier may be the most important result in the hunt.

Stage 4 — compare supporting behavioural signals

Measure how often the repeated activity also contains encoded commands or download behaviour. Supporting signals help distinguish a generic enterprise script from a more suspicious execution pattern.

04-compare-supporting-signals.kql
1234567891011121314151617181920212223242526
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where InitiatingProcessFileName in~ (
    "winword.exe", "excel.exe", "outlook.exe",
    "chrome.exe", "msedge.exe", "firefox.exe",
    "wscript.exe", "cscript.exe", "mshta.exe"
)
| extend EncodedCommand =
    ProcessCommandLine has_any ("-enc", "-encodedcommand")
| extend DownloadBehaviour =
    ProcessCommandLine has_any (
        "Invoke-WebRequest", "iwr ",
        "DownloadString", "WebClient",
        "Start-BitsTransfer"
    )
| summarize Executions=count(),
            Devices=dcount(DeviceName),
            Users=dcount(AccountName),
            DeviceList=make_set(DeviceName, 50),
            UserList=make_set(AccountName, 50),
            EncodedExecutions=countif(EncodedCommand),
            DownloadExecutions=countif(DownloadBehaviour)
          by InitiatingProcessFileName,
             ProcessCommandLine
| order by Devices desc, Executions desc

Multiple weak signals can become useful together

A browser launching PowerShell may be unusual. A browser launching encoded PowerShell that downloads content across multiple endpoints is a much stronger investigation candidate.

Still test the business explanation

Before escalation, check whether security tooling, endpoint management, software deployment or support processes can account for the pattern. Hunting works best when technical evidence is combined with environmental knowledge.

Stage 5 — build the device scope register

Finish by creating a concise record for every affected device. This gives the investigation team a reproducible list of endpoints, users, commands, parents, hashes and observation times.

05-build-device-scope-register.kql
1234567891011121314151617181920212223242526
let HuntResults =
    DeviceProcessEvents
    | where Timestamp > ago(7d)
    | where FileName in~ ("powershell.exe", "pwsh.exe")
    | where InitiatingProcessFileName in~ (
        "winword.exe", "excel.exe", "outlook.exe",
        "chrome.exe", "msedge.exe", "firefox.exe",
        "wscript.exe", "cscript.exe", "mshta.exe"
    )
    | project Timestamp,
              DeviceId,
              DeviceName,
              AccountName,
              InitiatingProcessFileName,
              ProcessCommandLine,
              SHA1;
HuntResults
| summarize Executions=count(),
            FirstSeen=min(Timestamp),
            LastSeen=max(Timestamp),
            Users=make_set(AccountName, 20),
            Parents=make_set(InitiatingProcessFileName, 20),
            Commands=make_set(ProcessCommandLine, 20),
            Hashes=make_set(SHA1, 20)
          by DeviceId, DeviceName
| order by FirstSeen asc

Scope registers support response

If the behaviour is later confirmed malicious, the device register immediately becomes useful for containment, forensic prioritisation and checking whether remediation covered the full observed scope.

Scope is allowed to change

A hunt may begin with twelve devices and later expand to twenty or contract to two genuinely suspicious endpoints. Record how the scope was derived and update it as evidence improves.

Agent Foskett's environment-wide scope

ONE BEHAVIOURAL RESULT ↓ SEARCH ALL DEVICES ↓ 12 MATCHING ENDPOINTS ↓ COMPARE Device User Parent process Full command line Hash First / last seen ↓ REPEATED COMMAND? YES ↓ SUPPORTING SIGNALS Encoded execution Download behaviour Unusual parent ↓ VALIDATE BUSINESS CONTEXT Deployment tool? Support script? Security product? ↓ OUTCOME Legitimate pattern OR Prioritised devices for deeper investigation
The query found twelve matches. The investigation determines how many of those matches actually matter.

How to interpret environment-wide repetition

PatternPossible explanationNext question
Same command, same time, many devicesCentral deployment or coordinated activity.What system or actor initiated it?
Same command, scattered timesRecurring automation, user action or repeated attack technique.What triggers each execution?
Same user across many devicesAdministrator, service account or compromised identity.Is the account expected on those endpoints?
Different users, identical parent and commandCommon application or deployment mechanism.Is the software approved and expected?
One device diverges from the other elevenPotential outlier hidden inside a legitimate pattern.Why is its ancestry, command or source different?

Write the hunt finding like an analyst

Example: A behaviour-led PowerShell hunt identified matching execution patterns across twelve endpoints. The activity was scoped by device, user, initiating process, command line, hash and first/last observation time. Repeated command lines were then pivoted back to their underlying process events and compared for encoded execution and download-related behaviour. The presence of the technique across twelve devices does not establish twelve compromises; legitimate enterprise tooling can produce repeated execution at scale. The affected-device register should be validated against approved software deployment, management and support activity. Endpoints whose command line, ancestry, user context or supporting signals diverge from the established pattern should receive priority for deeper investigation.

Lesson 162 key takeaways

  • Environment-wide scoping should follow a high-value behavioural hunting result.
  • Count devices and users before describing the scale of an incident.
  • Compare full command lines and parent processes across affected endpoints.
  • Identical activity can indicate coordinated attack behaviour or legitimate centralised tooling.
  • Pivot aggregate patterns back to raw telemetry before drawing conclusions.
  • Outliers inside a repeated pattern can be more valuable than the common pattern itself.
  • Use supporting behavioural signals to prioritise suspicious executions.
  • Validate repeated activity against software deployment, support and security tooling.
  • Build a device scope register that can support investigation and response.
  • The number of matching devices is a scope measurement, not a compromise count.

Module 14 — from hunting result to reusable detection

Lesson 162 showed how a single behaviour-led query can expand into an environment-wide investigation. Next, we take a useful hunting query and ask the detection-engineering question: can this logic become a reliable, repeatable detection?

Next: Lesson 163 — Turning an Investigation Query Into a Detection.

Continue your KQL investigation training

Module 14 turns investigation knowledge into proactive hunts, environment-wide scoping and reusable detections.

🔎 KQL Academy — Module 14: Advanced Detection Engineering & Proactive Threat Hunting

Turn investigation knowledge into proactive hunts, reusable analytics and higher-confidence detections.

Scope KQL threat hunting results across multiple devices

Lesson 162 of the Agent Foskett KQL Academy shows how to expand a behavioural hunting result across Microsoft Defender endpoint telemetry and determine how many devices and users share the same suspicious technique.

Investigate repeated PowerShell behaviour across endpoints

Learn how to compare command lines, parent processes, users, hashes and supporting behavioural signals, pivot aggregate results back to raw events and build an environment-wide device scope register.