#!/bin/bash # Intune custom compliance discovery script for Linux: is Microsoft Defender # for Endpoint (mdatp) installed, onboarded, licensed and protecting? # # Upload in Intune > Endpoint security > Device compliance > Scripts (Linux), # and pair it with defender-compliance.json in a Linux compliance policy # (Custom compliance). Himmelblau runs it as root inside # himmelblaud-tasks.service and sends the JSON on stdout to Intune, which # evaluates it against the rules. Every setting is always emitted, so a missing # or stopped Defender reads as non-compliant instead of as a script error. MDATP=/usr/bin/mdatp # Defender won't answer `mdatp health` started from inside himmelblaud-tasks # (it can't read that process while checking the caller), so ask through # systemd, which runs mdatp as its own child. Elsewhere, ask mdatp directly. health="$(systemd-run --quiet --wait --pipe --collect "${MDATP}" health 2>/dev/null)" grep -q '^healthy' <<< "${health}" || health="$("${MDATP}" health 2>/dev/null)" # Print one field of the `mdatp health` output ("name : value") without # quotes or a trailing " [managed]". field() { grep -m1 "^$1 *:" <<< "${health}" \ | sed -e 's/^[^:]*: *//' -e 's/ \[managed\]$//' -e 's/^"//' -e 's/"$//' } bool() { [[ "$1" == true ]] && echo true || echo false } installed=false running=false healthy=false licensed=false onboarded=false rtp=false behavior_monitoring=false cloud_protection=false definitions_ok=false definitions_age=-1 version="" if [[ -x "${MDATP}" ]]; then installed=true if [[ "$(field healthy)" =~ ^(true|false)$ ]]; then # The daemon answered. running=true healthy="$(bool "$(field healthy)")" licensed="$(bool "$(field licensed)")" rtp="$(bool "$(field real_time_protection_enabled)")" [[ "$(field behavior_monitoring)" == enabled ]] && behavior_monitoring=true cloud_protection="$(bool "$(field cloud_enabled)")" [[ -n "$(field org_id)" ]] && onboarded=true [[ "$(field definitions_status)" == up_to_date ]] && definitions_ok=true age="$(field definitions_updated_minutes_ago)" [[ "${age}" =~ ^[0-9]+$ ]] && definitions_age=$(( age / 1440 )) version="$(field app_version)" version="${version//[^0-9A-Za-z._-]/}" fi fi cat <