edgarus71
2 TopicsDetermine Defender for Endpoint offboarding state for Linux devices
There are certain instances when a machine or machines are offboarded that the corresponding status takes an unusual amount of time to report in the Defender portal. The status that is shown in the portal is “Can be onboarded,” however this status doesn’t clarify with absolute certainty that the machine was offboarded from the platform. The status “Can be onboarded” means that either the endpoint was offboarded from the platform or, that it is a new device discovered by the “Device Discovery” service of MDE and the platform is highlighting this for you as something to address and cover the security gap that represents an endpoint without protection. Figure 1.”Can be onboarded” status of a device. In advanced hunting in the Defender portal, there’s not a direct field that reflects if a device was offboarded but if it is onboarded that is visible using a KQL query. If a device is onboarded, this is shown in the portal, under Assets -- Device Inventory -- All devices, but not if it is offboarded. Figure 2. Onboarding status as seen in the Device Inventory view. To circumvent this existing challenge, I am using a similar approach to what I described in the article “Determine offboarding state using Powershell” and you can run a bash script that determines with a high level of confidence that a device was offboarded from the platform without the need to wait for the 7 days period it takes a device to be deemed as inactive in the console. This script can be handy in situations where offboarding is happening on devices that are experiencing communication issues or sensor issues and offboarding is the option to fix the problem and you would like to know straight away if the process was successful. In essence, the bash script checks three indicators present in Linux system to confirm if the key services responsible for sending telemetry to the portal are up and running. The key parameters are listed below: Confirm the onboard file exists in this path: "/etc/opt/microsoft/mdatp/mdatp_onboard.json" Check the Defender daemon process is running: wdavdaemon/mdatp Check mdatp rpm package is installed These two last parameters are informational only to report the status of the wdavdaemon and if the rpm package for Defender is installed, but it provides two key pieces of information: If service is still running but machine is offboarded, this is the expected behavior unless you also uninstall the MDE agent from the Linux endpoint. If the service and rpm package show as not installed and the device also shows as offboarded that means the machine hasn't been onboarded to Defender for Endpoint High level execution of the script: Scans computer(s) to determine onboarding method in MDE: The script proceeds through several logical steps: It first checks if the onboarding file exists and attempts to extract the organization ID from it using either jq or a portable grep/awk fallback. Next, it determines if the MDE package is installed by querying the system’s package manager. It then checks if the Defender service is running, using systemd if available, or falling back to process checks otherwise. The script also locates the Defender CLI and, if present, queries its health status and extracts additional metadata such as org ID, machine ID, health state, and app version. In theory, to make it scalable and reach to more devices, this bash script could be pushed to Linux endpoints using any of the Linux management tools like Chef, Ansible or Puppet. Finally, the script synthesizes these findings to decide the overall status: it reports “ONBOARDED” if the Defender agent is healthy, the service is active, or both the package and onboarding file are present; otherwise, it reports “OFFBOARDED.” The output summarizes key findings, making it easy for administrators or automation systems to quickly assess the Defender state on Linux endpoints. For further troubleshooting with Linux devices: Microsoft Defender for Endpoint on Linux resources - Microsoft Defender for Endpoint | Microsoft Learn Parameters used in the script: The script contains different parameters to evaluate with a great level of certainty if a device was onboarded using one of the known methods: ONBOARD_FILE: The path to the Defender onboarding artifact (/etc/opt/microsoft/mdatp/mdatp_onboard.json). Its presence and contents are used to determine onboarding state and extract the organization ID. onboard_state: Indicates whether the onboarding file is present ("Present") or missing ("Missing"). org_from_file / org_from_cli: The organization (tenant) ID, extracted from the onboarding file or from the Defender CLI health output, respectively. pkg_status: Reflects whether the Defender package (mdatp) is installed, and via which package manager (Installed(rpm), Installed(dpkg), or NotInstalled(...)). svc_state: The running state of the Defender service or process (active, inactive, UnitMissing, NoSystemd, etc.), determined via systemd or process checks. MDATP_CLI: The path to the Defender CLI binary, used to query health and metadata. healthy: Indicates if the Defender agent is healthy (true/false), as reported by the CLI. edr_machine_id: The unique machine ID assigned by Defender, extracted from the CLI health output. app_version: The installed version of the Defender agent, also from the CLI health output. overall: The final computed status, either "ONBOARDED" or "OFFBOARDED", based on the combination of health, service, package, and onboarding file checks. - HOW TO RUN - EXAMPLE Open a terminal window in the Linux device you want to check and navigate to the directory where the script is saved. Run the following command to make it executable: chmod +x MDE_CheckOffboardingState_Linux.sh Run the Script with Sufficient Privileges: Sudo bash ./MDE_CheckOffboardingState_Linux.sh Check the output of the script. If the endpoint is onboarded you will see an output similar to this: Fig. 3 Linux device is onboarded in Defender for Endpoint If the endpoint hasn’t been onboarded to Defender for Endpoint or it has been offboarded, the output of the shell script will be similar to this: Fig. 4 A Linux device that is offboarded from Defender for Endpoint Linux shell scripting code: Code disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. NOTE: When using your scripting editing tool of choice, be aware of any additional spaces added as a result of the copy/past operation into your editing tool. #!/usr/bin/env bash # Check Microsoft Defender for Endpoint (MDE) offboarding/onboarding status on Linux # v3 - robust unit detection, non-systemd fallback, smarter CLI/Org ID parsing # Output is ASCII-only, suitable for CI/logging. # USAGE DISCLAIMER # The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are # provided AS IS without warranty of any # kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of # merchantability or of fitness for a # particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation # remains with you. In no event shall # Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for # any damages whatsoever (including, # without limitation, damages for loss of business profits, business interruption, loss of business information, or other # pecuniary loss) arising out of the use # of or inability to use the sample scripts or documentation, even if Microsoft # has been advised of the possibility of such damages. # Author: Edgar Parra - Microsoft v1.1 #!/usr/bin/env bash # Check Microsoft Defender for Endpoint (MDE) offboarding/onboarding status on Linux # v3-modified - authoritative offboarding via artifact files only set -euo pipefail ONBOARD_FILE="/etc/opt/microsoft/mdatp/mdatp_onboard.json" OFFBOARD_FILE="/etc/opt/microsoft/mdatp/mdatp_offboard.json" # ---- helper: trim ---- _trim() { sed -e 's/^[[:space:]]\+//' -e 's/[[:space:]]\+$//' ; } # ---- 1) Onboarding artifact check ---- onboard_state="Missing" if [[ -s "$ONBOARD_FILE" ]]; then onboard_state="Present" fi offboard_state="Missing" if [[ -s "$OFFBOARD_FILE" ]]; then offboard_state="Present" fi # ---- 2) Package presence (rpm or dpkg) ---- pkg_status="Unknown" if command -v rpm >/dev/null 2>&1; then if rpm -q mdatp >/dev/null 2>&1; then pkg_status="Installed(rpm)" else pkg_status="NotInstalled(rpm)" fi elif command -v dpkg >/dev/null 2>&1; then if dpkg -s mdatp >/dev/null 2>&1; then pkg_status="Installed(dpkg)" else pkg_status="NotInstalled(dpkg)" fi fi # ---- 3) Service/process state (informational only) ---- svc_state="Unknown" if systemctl is-active --quiet mdatp 2>/dev/null; then svc_state="active" else svc_state="inactive" fi # ---- 4) CLI presence (informational only) ---- MDATP_CLI="$(command -v mdatp 2>/dev/null || true)" [[ -z "$MDATP_CLI" ]] && MDATP_CLI="/opt/microsoft/mdatp/bin/mdatp" # ---- 5) Decide OFFBOARDING STATUS (AUTHORITATIVE LOGIC ONLY) ---- overall="NOT_OFFBOARDED" if [[ "$offboard_state" == "Present" && "$onboard_state" == "Missing" ]]; then overall="OFFBOARDED" fi # ---- 6) Output ---- echo "========== Microsoft Defender for Endpoint (Linux) ==========" echo "Offboarding status (authoritative): $overall" echo "mdatp_offboard.json: $offboard_state ($OFFBOARD_FILE)" echo "mdatp_onboard.json: $onboard_state ($ONBOARD_FILE)" echo "mdatp service status (informational): $svc_state" echo "mdatp RPM status (informational): $pkg_status" echo "=============================================================" Conclusion The purpose of this script is to be used as an alternative to discover faster if a device has been offboarded or never onboarded in Defender for Endpoint. It provides a swift approach for when deployments occur and you need to know faster when a device has been offboarded. It streamlines your deployment and allows you to move faster. We understand that waiting 7 days for a device to be marked as “Can be onboarded” in the Defender portal, feels like a long wait but the reasons for this are security. To allow devices that have been offline for a period of time that may reconnect with Defender. Additional benefit An additional benefit of this script is that it can also be run from Live Response console but only on devices that are onboarded in Defender for Endpoint. For devices that are not onboarded, Live Response is not available. However, running the script will tell you if the device is properly onboarded and the output of the script will be shown in the Live Response console. This is a practical way to run the script remotely without the need to logon to the device directly and find out quickly if the device was onboarded properly. Fig. 5 Running the shell script from the Live Response console and output is shown in the Live Response console.Determine Defender for Endpoint offboarding state of Windows machines using PowerShell
There are certain instances when a machine or machines are offboarded that the corresponding status takes an unusual amount of time to report in the Defender portal. The status that is shown in the portal is “Can be onboarded”, however this status doesn’t clarify with absolute certainty that the machine was offboarded from the platform. The status “Can be onboarded” means that either the endpoint was offboarded from the platform or, that it is a new device discovered by the “Device Discovery” service of MDE and the platform is highlighting this for you as something to address and cover the security gap that represents an endpoint without protection. Figure 1.”Can be onboarded” status of a device. In advanced hunting in the Defender portal, there’s not a direct field that reflects if a device was offboarded but if it is onboarded that is visible using a KQL query. If a device is onboarded, this is shown in the portal, under Assets --> Device Inventory --> All devices, but not if it is offboarded. Figure 2. Onboarding status as seen in the Device Inventory view. To circumvent this existing challenge, Powershell can come to the rescue, and you can run a script that determines with a high level of confidence that a device was offboarded from the platform without the need to wait for the 7 days period it takes a device to be deemed as inactive in the console. This script can be handy in situations where offboarding is happening on devices that are experiencing communication issues or sensor issues and offboarding is the option to fix the problem and you would like to know straight away if the process was successful. In essence, the script checks an indicator in the registry and the status of the key service that is responsible for sending telemetry to the portal and a true indication that the device is onboarded in Defender for Endpoint, the Sense.exe service. The registry key: 'HKLM:\SOFTWARE\Microsoft\Windows Advanced Threat Protection\Status', REG_DWORD: OnboardingState. High level execution of the script: Scans computers to determine if devices are offboarded from MDE: The script checks one or more Windows computers (locally by default, or remotely via PowerShell remoting) and infers whether the device appears OFFBOARDED from MDE by looking at: Registry onboarding indicators (OnboardingState and OnboardedInfo) The state of the SENSE service (Sense) Then it outputs: A human-readable status (ASCII only) It pipes the results to a .csv file Optionally exports CSV Fairly simple script but it allows administrators to check on the fly if a device has been offboarded from Defender for Endpoint. I wanted to keep it simple, but this script could be run from Configuration Manager or Intune to check in bulk what devices are offboarded from MDE. PowerShell scripting code: Code disclaimer: The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages. NOTE: When using your scripting editing tool of choice, be aware of any additional spaces added as a result of the copy/past operation into your editing tool. <# .SUMMARY Checks if a device appears OFFBOARDED from Microsoft Defender for Endpoint (MDE). .DESCRIPTION - Reads onboarding indicators in the registry. - Checks the SENSE service state. - Outputs a simple, ASCII-only status. - Can run locally (default) or against one/many remote computers via PS Remoting. .PARAMETER ComputerName One or more computers to check. Default = local computer. .PARAMETER OutCsv Optional path to write results as CSV. .PARAMETER Quiet If set, returns $true when OFFBOARDED and $false otherwise (for local-only use). .NOTES Registry indicators are based on the typical onboarding keys used by MDE. References: - MS Learn: Offboard devices (status becomes Inactive after 7 days; data retained up to 180 days). - Author: Edgar Parra - Microsoft v1.0 #> [CmdletBinding()] param( [string[]]$ComputerName = @($env:COMPUTERNAME), [string]$OutCsv, [switch]$Quiet ) # --- inner checker that runs LOCALLY on a target (used both locally and via Invoke-Command) --- $localCheck = { $regPaths = @( 'HKLM:\SOFTWARE\Microsoft\Windows Advanced Threat Protection\Status', 'HKLM:\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection\Status' ) $onboardingStates = @() foreach ($p in $regPaths) { if (Test-Path $p) { try { $val = Get-ItemPropertyValue -Path $p -Name 'OnboardingState' -ErrorAction SilentlyContinue if ($null -ne $val) { $onboardingStates += [int]$val } } catch { } } } # SENSE service check $senseStatus = try { $svc = Get-Service -Name 'Sense' -ErrorAction Stop $svc.Status.ToString() } catch { 'NotInstalled' } # Determine likely state # If any OnboardingState == 1 OR SENSE Running, treat as not offboarded $isOnboarded = ($onboardingStates -contains 1) -or ($senseStatus -eq 'Running') # Build result [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME SenseService = $senseStatus OnboardingState = if ($onboardingStates.Count) { ($onboardingStates -join ',') } else { 'N/A' } AppearsOffboarded = if ($isOnboarded) { $false } else { $true } Notes = if ($isOnboarded) { 'OnboardingState==1 and/or SENSE Running' } else { 'No onboarding indicators and SENSE not running' } } } $results = @() foreach ($comp in $ComputerName) { if ($comp -ieq $env:COMPUTERNAME -or $comp -eq '.' -or $comp -eq 'localhost') { $results += & $localCheck } else { try { $res = Invoke-Command -ComputerName $comp -ScriptBlock $localCheck -ErrorAction Stop $res | ForEach-Object { $_.ComputerName = $comp } $results += $res } catch { $results += [PSCustomObject]@{ ComputerName = $comp SenseService = 'Unknown' OnboardingState = 'Unknown' AppearsOffboarded = $null Notes = "Error: $($_.Exception.Message)" } } } } # Output if ($OutCsv) { $results | Export-Csv -NoTypeInformation -Path $OutCsv -Encoding UTF8 Write-Host "Saved results to $OutCsv" } if ($ComputerName.Count -eq 1 -and $Quiet) { # local single-check boolean mode return [bool]$results[0].AppearsOffboarded } # Human-readable summary (ASCII only) $results | ForEach-Object { $status = if ($_.AppearsOffboarded -eq $true) { 'OFFBOARDED' } elseif ($_.AppearsOffboarded -eq $false) { 'ONBOARDED' } else { 'UNKNOWN' } Write-Host ('[{0}] Status: {1} | SENSE: {2} | OnboardingState: {3} | Notes: {4}' -f ` $_.ComputerName, $status, $_.SenseService, $_.OnboardingState, $_.Notes) } # Also emit objects so you can pipe to Select-Object/Where-Object if you want $results Additional information: Offboarding devices from Defender for Endpoint. Offboarding devices via API explorer. In the next publication, I will aboard how to do this same process but for devices running Linux. Stay tuned!! and thank you for reading!