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 50Explanation
This KQL 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 what the query does:
-
Define Friendly Names for AV Modes: It maps antivirus mode codes to more understandable names like "Normal," "Passive," and "EDR Block."
-
Set Time Range: It considers data from the last 24 hours.
-
Identify Scan Candidates:
- It looks at devices that are 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.
-
Anchor on Device Events:
- It finds the most recent event for each device to ensure there's a valid event record (with ReportId and Timestamp).
-
Join Data:
- It combines the list of devices needing a scan with their corresponding event records.
-
Output:
- It produces a list of up to 50 devices, including their names, IDs, scan status, and event details, which can be used for custom detection rules and actions like running a full antivirus scan.
This query is useful for security teams to ensure that all devices are regularly scanned and to automate actions for devices that need attention.
Details

Nathan Hutchinson
Released: February 12, 2026
Tables
DeviceTvmInfoGatheringDeviceEvents
Keywords
Devices
Operators
letdynamicagowhereextendparse_jsontostringcoalesceextractjsonisnotemptyhassummarizearg_maxprojectjoinontake