Forum Discussion

juliu_s's avatar
juliu_s
Copper Contributor
Aug 19, 2025

Alert Rule Fails on Dynamic Field Parsing in DeviceTvmInfoGathering

Hi, 

Need Help: Alert Rule Fails but Hunting Query Works (Dynamic Fields Issue)
Alert Rule Query Fails When Using parse_json on AdditionalFields — Any Workarounds?

Need to get alert when avmode is disabled.

KQL:

DeviceTvmInfoGathering
| where isnotempty(AdditionalFields)
| where Timestamp > ago(1h)
| extend AF = parse_json(AdditionalFields)
| where AF has "AvMode"
| extend AvMode = tostring(AF.AvMode)
| where AvMode == "2" 
| extend ReportId = tolong(abs(hash(DeviceId)))
| project Timestamp, ReportId, DeviceId, DeviceName, OSPlatform, AvMode

1 Reply

  • Ankit365's avatar
    Ankit365
    Iron Contributor

    The issue is that alert rules in the Microsoft 365 Defender portal handle dynamic fields differently than advanced hunting queries, especially when you use parse_json() inside custom detection logic. While your KQL works fine in hunting because it evaluates JSON dynamically at query time, the alert rule engine runs queries in a more restricted mode that cannot always parse complex or nested JSON fields from dynamic columns like AdditionalFields.

    Here’s what’s happening behind the scenes. When you save an alert rule, the rule engine performs a schema validation pass to ensure that all fields referenced in the query exist in the table definition. Dynamic content such as parse_json(AdditionalFields) creates temporary fields that do not exist in the schema, and the engine fails because it cannot resolve them during precompilation.

    To work around this, you can restructure your query so that it avoids dynamic schema expansion. The simplest method is to cast the AdditionalFields to a string and use string search functions instead of parse_json(). For example:

    DeviceTvmInfoGathering
    | where isnotempty(AdditionalFields)
    | where Timestamp > ago(1h)
    | where AdditionalFields has '"AvMode":"2"'
    | extend ReportId = tolong(abs(hash(DeviceId)))
    | project Timestamp, ReportId, DeviceId, DeviceName, OSPlatform, AdditionalFields

    This approach works reliably in scheduled detection rules and gives the same result because you are matching the raw JSON text rather than trying to parse it dynamically.

    If you really need to extract AvMode as a distinct column, another option is to first materialize it into a custom table through a Microsoft Sentinel analytic rule (if you are using Defender data in Sentinel) or an Advanced Hunting scheduled task that writes to a custom log. Those engines allow parse_json() without schema conflicts.

    In short, the failure is expected behavior due to how the alert rule engine validates dynamic fields. Use string matching on AdditionalFields or move the logic to Sentinel for full JSON parsing support. Please hit like if you like the solution.



Resources