Query Details

Windows Trigger Full Scan For Devices That Have Not Completed One

Query

// Initial full scan helper for MDE onboarded devices
// Use this in a custom detection rule with the "Run antivirus scan" (Full scan) action.
// Map AV mode codes to friendly names
// Will include Windows clients and servers - See client only query if you do not want ot include servers
let AvModeDescription = dynamic({"0":"Normal", "1":"Passive", "4":"EDR Block"});
let TimeRange = ago(1d);
// 1. Find devices in Normal AV mode that have NOT completed a full scan
let ScanCandidates =
    DeviceTvmInfoGathering
    | where Timestamp > TimeRange
    | extend AdditionalFields = parse_json(AdditionalFields)
    | extend AvMode = tostring(AvModeDescription[tostring(AdditionalFields.["AvMode"])])
    | extend FullScanStatus = coalesce(
        extractjson("$.Full.ScanStatus", tostring(AdditionalFields.AvScanResults)),
        "Not available"
      )
    | where isnotempty(AvMode) and AvMode has "Normal"
    | where FullScanStatus !has "Completed"
    // one latest TVM record per device
    | summarize arg_max(Timestamp, FullScanStatus) by DeviceId, DeviceName
    | project DeviceId, DeviceName, FullScanStatus;
// 2. Anchor on DeviceEvents to get a valid event (ReportId + Timestamp)
DeviceEvents
| where Timestamp > TimeRange
| summarize arg_max(Timestamp, ReportId) by DeviceId
// 3. Join event anchor to the TVM scan status
| join kind=inner ScanCandidates on DeviceId
// 4. Final output for custom detection + device action
| project
    DeviceName,
    DeviceId,
    FullScanStatus,
    ReportId,   // REQUIRED for custom detections
    Timestamp   // REQUIRED for custom detections
    | take 50

Explanation

This query is designed to identify Microsoft Defender for Endpoint (MDE) onboarded devices that are in "Normal" antivirus mode but have not completed a full antivirus scan within the last day. Here's a simplified breakdown of the query:

  1. Define Friendly Names for AV Modes: It maps antivirus mode codes to human-readable names like "Normal," "Passive," and "EDR Block."

  2. Set Time Range: It looks at data from the past day.

  3. Identify Scan Candidates:

    • It searches for devices in "Normal" antivirus mode.
    • It checks if these devices have not completed a full antivirus scan.
    • It ensures only the latest record per device is considered.
  4. Find Relevant Device Events:

    • It looks for the most recent event for each device within the past day to get a valid event timestamp and report ID.
  5. Join Data:

    • It combines the list of devices needing a scan with their latest event data.
  6. Output Results:

    • It produces a list of up to 50 devices, including their names, IDs, full scan status, report IDs, and timestamps. This output can be used for custom detection rules and to trigger a full antivirus scan on these devices.

In essence, this query helps maintain security by ensuring that devices in normal mode are regularly scanned and any that have missed a scan are identified for further action.

Details

Nathan Hutchinson profile picture

Nathan Hutchinson

Released: February 2, 2026

Tables

DeviceTvmInfoGatheringDeviceEvents

Keywords

Devices

Operators

letdynamicagowhereextendparse_jsontostringcoalesceextractjsonisnotemptyhassummarizearg_maxbyprojectjoinkindontake

Actions