如何优化KQL查询实现单设备唯一CVE条目展示?
解决KQL查询中设备-CVE重复条目问题
针对你遇到的同一设备同一CVE因检测周期重复出现的问题,最可靠的方法是按设备和CVE唯一组合分组,保留每组的最新记录,替代单纯的时间窗口过滤。以下是优化后的查询:
DeviceTvmSoftwareVulnerabilities | join kind=inner DeviceTvmSoftwareVulnerabilitiesKB on CveId | join kind=inner DeviceInfo on DeviceId | where DeviceManualTags contains "SupportTeamName" // 简化OS平台过滤逻辑,用!in替代多个!contains | where OSPlatform !in ("2012", "2008", "Windows10", "windows11") // 简化严重级别过滤,用in替代多个contains(更精准匹配) | where VulnerabilitySeverityLevel in ("Critical", "High") // 核心去重逻辑:按设备ID和CVE ID分组,保留每组中时间戳最新的完整记录 | summarize arg_max(Timestamp, *) by DeviceId, CveId | project Timestamp, DeviceName, OSPlatform, CveId, CvssScore, VulnerabilitySeverityLevel, PublishedDate, VulnerabilityDescription, RecommendedSecurityUpdate, DeviceManualTags
关键优化点说明:
- 去重逻辑:
summarize arg_max(Timestamp, *) by DeviceId, CveId是核心。它会将所有记录按DeviceId(唯一标识设备)和CveId(唯一标识漏洞)分组,然后保留每组中Timestamp最新的那条完整记录,从根源上避免重复条目。 - 简化过滤条件:用
!in和in替代多个!contains/contains,既让代码更简洁,也避免了部分匹配可能带来的误判(比如OS名称包含目标字符串但并非对应系统的情况)。 - 稳定性提升:相比单纯依赖时间窗口过滤,这种分组保留最新记录的方式不受检测周期波动影响,无论检测频率如何,每个设备-CVE组合只会显示当前最新的漏洞状态。
如果你的场景不需要最新记录,只是单纯去重,也可以用distinct DeviceId, CveId, *替代summarize语句,但arg_max的方式更符合漏洞监控的实际需求——展示设备当前的最新漏洞状态。
内容的提问来源于stack exchange,提问作者David Wilson
相关产品推荐
相关产品推荐

