When using Defender for Endpoint it is important to make sure the agent are healthy. I performed many reviews/ configurations in the past years and onboarded around a million devices to Defender for Endpoint for small and larger “enterprise” customers. Based on experience seeing quite often the typical mistakes and configuration misconfiguration. Common question – how do you check if my Defender for Endpoint environment is healthy?

Many people only focus on the green status icon in Defender for Endpoint – there is way more behind the green icon since the green status icon is only relevant for the MDE sensor. All more on this later in the blog.

In this blog, I will deep-dive into a typical check for a healthy Defender for Endpoint, with the use of KQL/ Security recommendations and other checks. The end goal is for all machines to be healthy and up-to-date with the latest protection components.

Make sure to read also my blog related to common mistakes, and yes there are many many mistakes possible during the configuration of Defender for Endpoint. Blog: Common mistakes during Microsoft Defender for Endpoint deployments

For troubleshooting and additional protection validation the following blog is recommended: Microsoft Defender for Endpoint series – Validate Defender protection and additional troubleshooting – Part6


When is a machine healthy?

When checking in the Defender for Endpoint/ Defender XDR portal the machines are visible under the assets blade. A common misunderstanding is that the Sensor health state is for both AV/ EDR and all other components.

In general, the Sensor health state is only for the EDR component, which means it is reporting to the portal. All other components (DLP/ AV/ ASR) are not part of the status icon. MDE can be reported as “active” while the AV component is disabled on the endpoint.

The answer; in short; the sensor health state is a good indicator that the asset is reporting correctly to the MDE console, all it does not mean each part of “MDE” is configured correctly. Don’t focus only on the green icon in the portal.

Sensor health status

A typical first check is the sensor health state of the unhealthy machines. Check the following statuses:

  • Misconfigured – These devices might partially be reporting sensor data to the Defender for Endpoint service but have configuration errors that need to be corrected. Misconfigured devices can have either one or a combination of the following issues:
    • No sensor data – Devices have stopped sending sensor data. Limited alerts can be triggered from the device.
    • Impaired communications – Ability to communicate with device is impaired. Sending files for deep analysis, blocking files, isolating device from network and other actions that require communication with the device may not work.

The sensor health state can be filtered in the portal:

Action: filter all devices where the status is “misconfigured” and review the list. Typical is no connection to the endpoint or URLs being blocked via proxy/ firewall. When needed analyze the client with the MDE Client Analyzer: Download the Microsoft Defender for Endpoint client analyzer – Microsoft Defender for Endpoint | Microsoft Learn


Defender not running in active mode

A common part of a healthy environment is to check if Defender is running in active mode; in some environments, Defender is running in passive mode for a reason. When this is not the case, always check if the agents are reporting in active mode.

When the device is running in passive mode, there is the option it is installed with other AV software or the device is manually enforced in passive mode via the registry key.

Defender AV running in a disabled state. When the SignatureVersion = 0.0.0.0 the Defender agent is most of the time disabled by registry key/ policy or GPO.

DeviceTvmSecureConfigurationAssessment 
| where ConfigurationId == "scid-2011" // Update Microsoft Defender for Windows Antivirus definitions
| join kind=leftouter DeviceTvmSecureConfigurationAssessmentKB on ConfigurationId 
| mv-expand  e = parse_json(Context)
| project DeviceName,DeviceId, OSPlatform, SignatureVersion=tostring(e[0]), SignatureDate=todatetime(e[2]), EngineVersion=e[1], ProductVersion=e[3]
 | join kind=inner    (DeviceInfo
| where Timestamp > ago(30d)
| summarize arg_max(Timestamp,*) by DeviceName
| extend LastSeen = Timestamp
)
on $left.DeviceId ==  $right.DeviceId
| project DeviceName, DeviceId, OSPlatform, SignatureVersion, SignatureDate, EngineVersion, ProductVersion, LastSeen
| where SignatureVersion == "0.0.0.0"

The following query can be useful to check the AVMode of the machine. AVMode is active means the device is actively running, Passive and EDR Blocked are the passive statuses for Defender for Endpoint.

let avmodetable = DeviceTvmSecureConfigurationAssessment
| where ConfigurationId == "scid-2010" and isnotnull(Context)
| extend avdata=parsejson(Context)
| extend AVMode = iif(tostring(avdata[0][0]) == '0', 'Active' , iif(tostring(avdata[0][0]) == '1', 'Passive' ,iif(tostring(avdata[0][0]) == '4', 'EDR Blocked' ,'Unknown')))
| project DeviceId, AVMode;
DeviceTvmSecureConfigurationAssessment
| where ConfigurationId == "scid-2011" and isnotnull(Context)
| extend avdata=parsejson(Context)
| extend AVSigVersion = tostring(avdata[0][0])
| extend AVEngineVersion = tostring(avdata[0][1])
| extend AVSigLastUpdateTime = tostring(avdata[0][2])
| project DeviceId, DeviceName, OSPlatform, AVSigVersion, AVEngineVersion, AVSigLastUpdateTime, IsCompliant, IsApplicable
| join avmodetable on DeviceId
| project-away DeviceId1

Action: Review the machines and fix the non-active detected machines. When passive is configured for a reason. Tag the device to make sure it is visible for all the devices, this gives visibility for all teams.


Discovered assets

Another good check is to view the discovered devices not onboarded to Defender for Endpoint. This list can include machines discovered in the network, all not onboarded. Discovered devices will be visible with the onboarding status: “Can be onboarded”

Or use the following KQL query to find devices via the query experience:

DeviceInfo
| summarize arg_max(Timestamp, *) by DeviceId 
| where OnboardingStatus == "Can be onboarded"

Action: Review the list of discovered machines, and onboard machines. Sometimes the machines are already onboarded, all blocked by the firewall, which means the device cannot be onboarded successfully.


Outdated/ legacy agents

MMA agent

Some years ago Server 2012R2/ 2016 could be onboarded to MDE via the MMA agent. Since the MMA is legacy and almost EOL, the new unified agent is released to support newer features. A typical health check is to check if the MMA agent is still used in the environment.

There is no reason for 2012R2/ 2016 to keep them running on the MMA agent. The new Unified Agent supports the latest features and improves security via features like “Tamper Protection”

To check the systems running on the unsupported version. The following TVM recommendation can be used: Security recommendations – Microsoft Defender

I prefer to use the query created by Alex Verboon. This will show all machines and the specific agent. View the queries here: Hunting-Queries-Detection-Rules/Defender For Endpoint/MDE-Unified Agent.md at main · alexverboon/Hunting-Queries-Detection-Rules · GitHub

Example:

The below query is a good example created by Alex to show that the MMA or the Unified Agent is installed. The MMA agent is part of the 10.3720 scope, whereas the newer Unified agent starts with 10.8.

DeviceInfo
| where OnboardingStatus == "Onboarded"
| where isnotempty(OSPlatform) 
| summarize arg_max(Timestamp,*) by DeviceName
| where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016"
| extend Agent = case(ClientVersion startswith "10.3720", "MMA", ClientVersion startswith "10.8", "UnifiedClient","Other")
| summarize by DeviceName, OSPlatform, OnboardingStatus,Agent, ClientVersion
| sort by ClientVersion asc

The result is a list of machines where the agent is MMA or UnifiedAgent. When needed filter the query on rule 7 with the following: | where Agent == “MMA” to filter out all UnifiedAgent results.

Action: Update all machines where the MMA agent is installed and used for Defender for Endpoint. For 2012R2 and 2016 it must be running on the unified agent since this gives the latest security capabilities and supports the more advanced MDE features.

Outdated agents

For all agents, it is important to update the agent to the latest available version. Still, see many environments where the production version is not correctly updated. In all of the environments I checked, there are always agents not updating for months. (not only Defender, all mostly all Windows updates)

Windows

For Windows the following updates are available:

UpdateKBDescriptionSCID
Update for Defender antimalware platform (AmProductVersion)KB4052623It is critical to make sure the Defender platform is updated with the latest version, to get the latest technology and featuresScid-2011
Security Intelligence updatesKB2267602Defender AV requires Security Intelligence Updates/ Signature updatesScid-2011
Update for EDR sensor (2012R2/ 2016)KB5005292This update includes updates and fixes to the EDR sensor that is used by MDE for 2012R2/ 2016Scid-2030

The following query can be used to check the minimum version. With this KQL query, you can show all Windows devices when the platform version is under: 4.18.24050.7

DeviceTvmInfoGathering
| extend AdditionalFields = parse_json(AdditionalFields)
| extend AvPlatformVersion = tostring(AdditionalFields.["AvPlatformVersion"])
| where OSPlatform startswith "Windows"
| where parse_version(AvPlatformVersion) < parse_version("4.18.24050.7")

The same method can be used to track the Microsoft Defender AV Engine version:

DeviceTvmInfoGathering
|extend AvVersion=parse_json(AdditionalFields)
|extend AvVersionValue=AvVersion.AvSignatureVersion
|project DeviceName, OSPlatform, AvVersionValue
|where OSPlatform contains "Windows"  

TIP: DeviceTVMInfoGathering includes interesting details including the running mode/ configured ring and installed versions. Explore the table schema for Linux, MacOS, and Windows, it is really useful to deep-dive more into the dataset.

Productversion overview

DeviceTvmSecureConfigurationAssessment  
| where ConfigurationId == "scid-2011" 
| mv-expand  e = parse_json(Context) 
| project DeviceName,DeviceId, OSPlatform, SignatureVersion=tostring(e[0]), SignatureDate=todatetime(e[2]), EngineVersion=e[1], ProductVersion=e[3] 

Outdated signatures macOS

DeviceTvmSecureConfigurationAssessment 
| where ConfigurationId == "scid-5095" and isnotnull(Context) 
| where OSPlatform contains "macOS" 
| extend avdata=parsejson(Context) 
| extend AVSigVersion = tostring(avdata[0][0]) 
| extend AVEngineVersion = tostring(avdata[0][1]) 
| extend AVSigLastUpdateTime = tostring(avdata[0][2]) 
| extend AVProductVersion = tostring(avdata[0][3]) 
| join DeviceInfo on DeviceId 
| summarize by DeviceId, DeviceName, OSPlatform, RegistryDeviceTag, AVSigVersion, AVEngineVersion, AVSigLastUpdateTime,AVProductVersion, IsCompliant, IsApplicable, MachineGroup

Action: Update affected machines, and make sure all machines are actively updated and running on the latest supported versions.


Security configurations

A quick tip to view the overall compliance in the environment is to use the security recommendations.

The first step in enrolling MDE is confirming that all configurations are compliant. Using Microsoft Defender Vulnerability Management it is possible to check the configured security controls for Antivirus, Application Guard, ASR, Bitlocker, Credential Guard, EDR, Exploit Guard, Firewall, SmartScreen, and the general onboarding state of MDE.

View via the portal: Go to recommendations and filter on the related component “Security controls” for viewing the compliance of all security controls policies.

In this view, you can see the compliance of the items and the count of misconfigured machines.

In the above view, you can see two devices are not configured with PUA protection in block mode. (scid-2013). The data can be extracted via Advanced hunting to create a general overview of all configurations and compliance checks.

Important to start with the following recommendations, since the components are used for more features:

SCIDPlatformComponent
SCID-2012Windowsreal-time protection
SCID-5090macOSreal-time protection
SCID-6090LinuxRealtimeProtection
SCIDPlatformComponent
SCID-2016WindowsCloudProtection
SCID-5094macOSCloudProtection
SCID-6094LinuxCloudProtection

The following query can be used to cross-check configuration for macOS, Linux, and Windows in one single run. The idea of the query can be used to re-create and add additional scid’s to create a one-click overview to report against the compliance for important controls.

DeviceTvmSecureConfigurationAssessment
| where ConfigurationId in ('scid-90', 'scid-91', 'scid-2003', 'scid-2010', 'scid-2011', 'scid-2012', 'scid-2013', 'scid-2016', 'scid-5095', 'scid-6095', 
                            'scid-5090', 'scid-6090', 'scid-5091', 'scid-6091', 'scid-5094', 'scid-6094')
| extend Test = case(
    ConfigurationId == 'scid-2003' and OSPlatform startswith 'Windows', 'TamperProtection',
    ConfigurationId == 'scid-2010' and OSPlatform startswith 'Windows', 'AntivirusEnabled',
    ConfigurationId == 'scid-90'   and OSPlatform startswith 'Windows', 'EmailScanning', 
    ConfigurationId == 'scid-2011' and OSPlatform startswith 'Windows', 'AntivirusSignatureVersion',
    ConfigurationId == 'scid-5095' and OSPlatform == 'macOS', 'AntivirusSignatureVersion',
    ConfigurationId == 'scid-6095' and OSPlatform == 'Linux', 'AntivirusSignatureVersion',
    ConfigurationId == 'scid-2012' and OSPlatform startswith 'Windows','RealtimeProtection',
    ConfigurationId == 'scid-5090' and OSPlatform == 'macOS', 'RealtimeProtection',
    ConfigurationId == 'scid-6090' and OSPlatform == 'Linux', 'RealtimeProtection',
    ConfigurationId == 'scid-2013' and OSPlatform startswith 'Windows', 'PUAProtection',
    ConfigurationId == 'scid-5091' and OSPlatform == 'macOS', 'PUAProtection',
    ConfigurationId == 'scid-6091' and OSPlatform == 'Linux', 'PUAProtection',
    ConfigurationId == 'scid-2016' and OSPlatform startswith 'Windows', 'CloudProtection',
    ConfigurationId == 'scid-5094' and OSPlatform == 'macOS', 'CloudProtection',
    ConfigurationId == 'scid-6094' and OSPlatform == 'Linux', 'CloudProtection',
    ConfigurationId == 'scid-91' and OSPlatform startswith 'Windows', 'BehaviourMonitoring',
    'NA'),
        Result = case(IsCompliant == 1, 'GOOD', 'BAD'),
        SignVer = case(ConfigurationId == 'scid-2011' and OSPlatform startswith 'Windows', parse_json(Context)[0], 
                       ConfigurationId == 'scid-5095' and OSPlatform == 'macOS', parse_json(Context)[0], 
                       ConfigurationId == 'scid-6095' and OSPlatform == 'Linux', parse_json(Context)[0], 
        ''),
        DeviceName = toupper(tostring(split(DeviceName, '.')[0]))
| extend packed = pack(Test, Result)
| summarize Tests = make_bag(packed), SignatureData = max(SignVer), DeviceName = any(DeviceName), OSPlatform = any(OSPlatform) by DeviceId
| evaluate bag_unpack(Tests)
| extend AVSignatureVersion = tostring(parse_json(SignatureData)[0]), Date = todatetime(parse_json(SignatureData)[2]), ProductVersion = tostring(parse_json(SignatureData)[3]), EngineVersion = tostring(parse_json(SignatureData)[1])
| join kind=leftouter (DeviceInfo
| distinct DeviceId, MachineGroup, OnboardingStatus) on DeviceId
| where OnboardingStatus == "Onboarded"
| project-away SignatureData, NA, DeviceId1

As a result;

For each defined configuration a Good or Bad, including details like the AVSignatureVersion, ProductionVersion, EngineVersion, and MachineGroup.


Portal configuration

The portal configuration is important as well, go to Settings -> Endpoints -> Advanced features. To make sure the latest devices are getting optimal protection: Enable at least the following recommendations:

  • Enable EDR in block mode
  • Allow or block file
  • Custom network indicators
  • Tamper Protection
  • Unified audit log
  • Default to streamlined connectivity when onboarding devices in the Defender portal​​
  • Device discovery
  • Live Response
  • Authenticated telemetry

Tip: There are more configurations; read my blog series to understand all of the features and view the recommended value. The above features are in my view used to improve the overall client security. Blog series: MDE Series blogs – Jeffrey Appel – Microsoft Security blog

Action: Check that the basic is enabled. Don’t forget Tamper Protection, no discussion is needed with Tamper Protection, since this feature is critical in terms of protecting endpoints and hardening the agent with additional controls.


Attack Disruption

Attack disruption is part of the Microsoft 365 XDR ecosystem and correlates all signals from individual Defender/ Microsoft security products as part of the XDR solution. Attack disruption is enabled by default when all prerequisites are correctly enabled and configured – the feature is built-in and is based on the collected insights/ security research and AI models to combine and correlate events to identify advanced attacks and perform automated actions (attack disruption).

If the beginning of a human-operated attack is detected on a single device, attack disruption will stop the campaign on that device and inoculate all other devices in the organization to prevent further damage. The goal of automatic attack disruption is to contain compromised users across all devices to outmaneuver attackers before they have the chance to act with malicious items (credential theft/ data exfiltration/ remote encryption).

When checking the complete flow automatic attack disruption operates in three stages:

Stage 1: Correlates events from Microsoft 365 Defender XDR across all products and creates one single, high-confidence incident based on all collected data from endpoints, identities, email, and collaboration tools. Calculation is performed to calculate high-fidelity attacks to avoid false positives.

Stage 2: Identify affected assets controlled by the attacker that are used during the attack.

Stage 3: Take automated response actions.

Since automatic actions can lead to potential impact when the alert/ signal is classified as a false positive. Attack disruption is designed to rely on high-fidelity signals.

It is important to validate that all the controls are correctly configured for attack disruption to perform automated responses. Read the following blows to learn more:

Automatic attack disruption in Microsoft Defender XDR and containing users during Human-operated Attacks (jeffreyappel.nl)

How to use Automatic Attack Disruption in Microsoft 365 Defender (BEC, AiTM & HumOR)

Action: Validate that the attack disruption feature is correctly configured in Defender XDR. Check MDI and the device groups for sure! this is commonly not configured correctly.


Summary

Don’t focus only on the green status icon in Defender for Endpoint, there is way more, it is important to make the health checks as part of the management of the tool and frequently check for misconfigured devices. I know there are more components, that can be misconfigured, all this blog gives hopefully a good start with some ideas to validate the environment and check for incorrect machines.

The device health report can also be used via https://security.microsoft.com/devicehealth?viewid=sensorhealthsreport – all personally like it more directly in KQL or via the security recommendations to view the misconfigured devices directly.


Sources

Make sure to read also my blog related to common mistakes, and yes there are many many mistakes possible during the configuration of Defender for Endpoint. Blog: Common mistakes during Microsoft Defender for Endpoint deployments

For troubleshooting and additional protection validation the following blog is recommended: Microsoft Defender for Endpoint series – Validate Defender protection and additional troubleshooting – Part6