Plan deployment rings, create onboarding packages via Group Policy and Intune, deploy to Windows Server 2019/2022/2025, verify sensor health, and troubleshoot onboarding failures across your enterprise fleet.
Microsoft Defender for Endpoint (MDE) is a cloud-delivered endpoint security platform that provides preventative protection, post-breach detection, automated investigation, and response capabilities. Onboarding is the process of enrolling endpoints with the MDE sensor so that telemetry flows from your servers to the Microsoft Defender portal. Without onboarding, your servers are invisible to MDE: no alerts, no vulnerability assessments, no threat analytics. This lab walks you through a structured, enterprise-grade approach to onboarding a fleet of Windows Servers using Group Policy.
Scenario: Contoso Ltd operates 500+ Windows Servers across three data centers running Windows Server 2019, 2022, and 2025.
The security team must onboard all servers to MDE within 30 days to meet a regulatory compliance deadline. They need a phased rollout strategy (deployment rings) to minimize risk and avoid disrupting production workloads. The IT team uses Active Directory Group Policy as their primary endpoint management tool for servers.
Success criteria: 100% sensor health, telemetry flowing, device groups organized, and alerts validated.
Servers are high-value targets: they store sensitive data, run critical applications, and have elevated privileges. According to Microsoft Digital Defense Report, over 70% of ransomware attacks involve lateral movement through unprotected servers. Unmonitored servers create blind spots that attackers exploit to persist in your network for weeks or months. MDE onboarding provides immediate visibility: vulnerability assessments, behavioral sensors, and automated investigation. A structured onboarding approach reduces deployment failures and ensures consistent coverage across your entire fleet.
Before deploying the onboarding package, verify that every target server meets the minimum requirements and can reach the MDE cloud service endpoints.
winver or the command below# ---------------------------------------------------------
# WHAT: Verify OS version, TLS configuration, and patch level
# WHY: MDE requires Windows Server 2019+ (build 17763) or 2022 (build 20348).
# TLS 1.2 is mandatory for secure communication with MDE cloud services.
# Missing cumulative updates can cause sensor registration failures.
# ---------------------------------------------------------
# Check OS version - returns Major.Minor.Build.Revision
# OUTPUT: 10.0.17763.0 = Server 2019, 10.0.20348.0 = Server 2022
[System.Environment]::OSVersion.Version
# Verify TLS 1.2 is enabled in the SCHANNEL registry hive
# WHY: MDE cloud endpoints require TLS 1.2; older protocols are rejected.
# OUTPUT: DisabledByDefault=0 and Enabled=1 confirms TLS 1.2 is active.
# If this key is missing, TLS 1.2 uses OS defaults (enabled on 2019/2022).
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -ErrorAction SilentlyContinue
# Check last 5 installed Windows updates (hotfixes/cumulative updates)
# WHY: Outdated servers may lack required MDE sensor components or bug fixes.
# OUTPUT: Lists HotFixID, InstalledBy, and InstalledOn date.
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5Test-NetConnectionInvoke-WebRequest to confirm no proxy or firewall is blocking traffic# ---------------------------------------------------------
# WHAT: Test TCP/HTTPS connectivity to all required MDE cloud endpoints
# WHY: The MDE sensor transmits telemetry, receives detections, and
# downloads signatures over HTTPS (port 443). If any endpoint is
# blocked by a firewall or proxy, onboarding will fail silently.
# OUTPUT: Green = reachable, Red = blocked (work with network team)
# ---------------------------------------------------------
# Define the critical MDE service URLs:
# winatp-gw-*.microsoft.com - Sensor gateway (telemetry upload & command channel)
# us.vortex-win.data.microsoft.com - Diagnostic data pipeline
# settings-win.data.microsoft.com - Configuration & policy delivery
# ctldl.windowsupdate.com - Certificate Trust List updates for TLS validation
$urls = @(
"winatp-gw-eus.microsoft.com",
"winatp-gw-weu.microsoft.com",
"us.vortex-win.data.microsoft.com",
"settings-win.data.microsoft.com",
"ctldl.windowsupdate.com"
)
# Test TCP connectivity on port 443 for each endpoint
# WHY: Test-NetConnection performs a TCP handshake without sending HTTP;
# it quickly identifies firewall blocks at the transport layer.
foreach ($url in $urls) {
$result = Test-NetConnection -ComputerName $url -Port 443 -WarningAction SilentlyContinue
Write-Host "$url : $($result.TcpTestSucceeded)" -ForegroundColor $(if($result.TcpTestSucceeded){'Green'}else{'Red'})
}
# Validate full HTTPS handshake (catches TLS inspection / proxy issues)
# WHY: Some proxies allow TCP but inject certificates or block payloads.
# Invoke-WebRequest verifies the entire TLS + HTTP chain end-to-end.
# OUTPUT: StatusCode 200 = fully reachable; errors indicate proxy/TLS issues.
Invoke-WebRequest -Uri "https://winatp-gw-eus.microsoft.com/test" -UseBasicParsing -TimeoutSec 10A ring-based deployment strategy minimizes risk by gradually expanding onboarding coverage. Define three rings aligned to your change management process.
# ---------------------------------------------------------
# WHAT: Create AD security groups for a 3-ring deployment strategy
# WHY: Ring-based deployments minimize blast radius. GPO security
# filtering uses these groups to control which servers receive
# the MDE onboarding package at each phase.
# Ring 0 (5-10 servers) - Non-critical dev/test, validates package
# Ring 1 (50-100 servers) - Low-risk prod (file/print), validates scale
# Ring 2 (remaining fleet) - Full production including DCs and SQL
# ---------------------------------------------------------
# Create Global Security groups in the Security Groups OU
# WHY: Global scope allows cross-domain membership in multi-domain forests.
# Security category is required for GPO security filtering.
New-ADGroup -Name "MDE-Ring0-Pilot" -GroupScope Global -GroupCategory Security -Path "OU=Security Groups,DC=contoso,DC=com"
New-ADGroup -Name "MDE-Ring1-EarlyAdopters" -GroupScope Global -GroupCategory Security -Path "OU=Security Groups,DC=contoso,DC=com"
New-ADGroup -Name "MDE-Ring2-Production" -GroupScope Global -GroupCategory Security -Path "OU=Security Groups,DC=contoso,DC=com"
# Add pilot servers to Ring 0
# NOTE: The trailing "$" is required - AD computer accounts are security
# principals whose sAMAccountName ends with a dollar sign.
Add-ADGroupMember -Identity "MDE-Ring0-Pilot" -Members "SERVER-DEV01$","SERVER-DEV02$","SERVER-TEST01$"$ suffix on computer account names when adding them to groups: AD computer accounts are security principals with a trailing dollar sign.The onboarding package contains a configuration script that registers the MDE sensor with your tenant. Download it from the Microsoft Defender portal.
WindowsDefenderATPOnboardingPackage.zipWindowsDefenderATPOnboardingScript.cmd and an OptionalParamsPolicy folder\\contoso.com\NETLOGON\MDE-Onboarding\# ---------------------------------------------------------
# WHAT: Stage the MDE onboarding package on a domain-accessible share
# WHY: The GPO startup script references the onboarding CMD file via UNC path.
# NETLOGON is replicated to all DCs, ensuring every server can reach
# the package regardless of which DC it authenticates against.
# OUTPUT: \\DC01\NETLOGON\MDE-Onboarding\ containing the onboarding script
# ---------------------------------------------------------
# Create the target directory in NETLOGON (replicated via DFS-R / SYSVOL)
New-Item -Path "\\DC01\NETLOGON\MDE-Onboarding" -ItemType Directory -Force
# Copy the extracted onboarding package files
# Contents: WindowsDefenderATPOnboardingScript.cmd (tenant-specific config)
# OptionalParamsPolicy\ folder (additional policy settings)
Copy-Item -Path "C:\Downloads\WindowsDefenderATPOnboardingPackage\*" `
-Destination "\\DC01\NETLOGON\MDE-Onboarding\" -RecurseCreate a dedicated GPO that runs the onboarding script at machine startup, ensuring every server in the targeted ring is automatically onboarded.
MDE-Onboarding-Ring0 (you will create separate GPOs per ring)\\contoso.com\NETLOGON\MDE-Onboarding\WindowsDefenderATPOnboardingScript.cmdMDE-Onboarding-Ring0 GPOMDE-Ring0-Pilot to target only pilot servers# ---------------------------------------------------------
# WHAT: Create and link a GPO for MDE onboarding, scoped to Ring 0
# WHY: The GPO runs the onboarding CMD at machine startup. Security
# filtering restricts it to only Ring 0 pilot servers, preventing
# accidental onboarding of the entire domain.
# ---------------------------------------------------------
# Create a new GPO dedicated to MDE onboarding
$gpo = New-GPO -Name "MDE-Onboarding-Ring0" -Comment "MDE onboarding for pilot ring"
# Link the GPO to the Servers OU so it processes on server startup
# NOTE: Adjust the target OU to match your AD structure.
$gpo | New-GPLink -Target "OU=Servers,DC=contoso,DC=com" -LinkEnabled Yes
# GpoApply = The Ring 0 group members WILL process and apply this GPO.
# GpoRead = Authenticated Users can READ the GPO (required for processing)
# but without GpoApply they won't execute the startup script.
# WHY: This two-permission model is the standard way to implement
# security filtering - scope who the GPO applies to without
# breaking GPO read access needed for policy evaluation.
Set-GPPermission -Name "MDE-Onboarding-Ring0" -TargetName "MDE-Ring0-Pilot" -TargetType Group -PermissionLevel GpoApply
Set-GPPermission -Name "MDE-Onboarding-Ring0" -TargetName "Authenticated Users" -TargetType Group -PermissionLevel GpoReadgpresult /r /scope:computer on a target server to confirm the GPO is being applied correctly before rebooting.MDE requires a minimum diagnostic data level to function properly. Configure this setting in the same GPO or a separate baseline GPO.
MDE-Onboarding-Ring0 GPO (or your server baseline GPO)# ---------------------------------------------------------
# WHAT: Verify diagnostic data level and Defender AV protection settings
# WHY: MDE requires a minimum diagnostic data level of 1 (Required/Basic).
# A value of 0 (Security/Off) blocks all MDE telemetry transmission.
# Cloud protection (MAPS) and sample submission are needed for
# real-time cloud verdicts and block-at-first-sight capabilities.
# ---------------------------------------------------------
# Check the Windows diagnostic data level set by Group Policy
# OUTPUT: AllowTelemetry = 0 (Off), 1 (Required/Basic), 2 (Enhanced), 3 (Full)
# REQUIRED: Value must be >= 1 for MDE sensor to transmit telemetry.
Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -ErrorAction SilentlyContinue
# Check Defender AV protection settings
# MAPSReporting: 0=Disabled, 1=Basic, 2=Advanced (recommended for full cloud protection)
# SubmitSamplesConsent: 0=AlwaysPrompt, 1=SendSafeSamples, 2=NeverSend, 3=SendAll
# DisableRealtimeMonitoring: $false = real-time protection ON (expected)
# DisableBehaviorMonitoring: $false = behavior monitoring ON (expected)
Get-MpPreference | Select-Object MAPSReporting, SubmitSamplesConsent, DisableRealtimeMonitoring, DisableBehaviorMonitoringTrigger a Group Policy refresh on your Ring 0 pilot servers and confirm the MDE sensor registers successfully.
gpupdate /force to pull the latest Group Policy settings# ---------------------------------------------------------
# WHAT: Verify MDE sensor (SENSE) service and onboarding status
# WHY: The SENSE service is the MDE behavioral sensor. It must be
# running for telemetry to flow. DiagTrack (Connected User
# Experiences and Telemetry) transports diagnostic data to
# Microsoft - also required for MDE to function.
# ---------------------------------------------------------
# Query the MDE sensor service ("sense" = Microsoft Defender for Endpoint)
# OUTPUT: STATE 4 RUNNING = sensor is active and transmitting telemetry.
# STATE 1 STOPPED = onboarding script may not have executed.
sc query sense
# Check the service start type (should be AUTO_START for persistence)
sc qc sense
# Verify DiagTrack (telemetry transport service) is also running
# WHY: Without DiagTrack, diagnostic data cannot reach Microsoft's cloud.
sc query DiagTrack
# Review the SENSE operational event log for registration events
# KEY EVENT IDs:
# Event ID 28 = Onboarding successful (sensor registered with tenant)
# Event ID 5 = Onboarding failed (check connectivity or package validity)
# Event ID 7 = Communication error (firewall/proxy blocking MDE URLs)
Get-WinEvent -LogName "Microsoft-Windows-SENSE/Operational" -MaxEvents 20 |
Format-Table TimeCreated, Id, Message -AutoSize -Wrap
# Search specifically for Event ID 28 - confirms successful onboarding
# OUTPUT: If found, the server is registered with your MDE tenant.
# If missing, re-run the onboarding script or check connectivity.
Get-WinEvent -LogName "Microsoft-Windows-SENSE/Operational" |
Where-Object { $_.Id -eq 28 } | Select-Object -First 1Get-WindowsFeature Windows-Defender*C:\Windows\Temp for script output logs\\contoso.com\NETLOGON\MDE-Onboarding\WindowsDefenderATPOnboardingScript.cmdGet-MpComputerStatus | Select-Object AMRunningMode to quickly verify Defender Antivirus is in Normal mode, not passive or SxS passive.Run the official MDE detection test to verify end-to-end telemetry flow from the onboarded server to the Defender portal.
# ---------------------------------------------------------
# WHAT: Microsoft's official MDE detection test command
# WHY: This SAFE, BENIGN command simulates suspicious behavior
# (downloading + executing a file) that the MDE sensor is
# specifically designed to detect. It connects to localhost
# only (127.0.0.1) - no actual malware is involved.
# DETECTION: Triggers alert "[TestAlert] Suspicious PowerShell commandline"
# in the Defender portal within 5-15 minutes.
# OUTPUT: Confirms end-to-end telemetry: sensor โ cloud โ portal alert.
# TRUE POSITIVE: Expected activity - resolve as Informational.
# ---------------------------------------------------------
# Official MDE detection test command (run from elevated cmd.exe)
powershell.exe -NoExit -ExecutionPolicy Bypass -WindowStyle Hidden $ErrorActionPreference = 'silentlycontinue';(New-Object System.Net.WebClient).DownloadFile('http://127.0.0.1/1.exe', 'C:\\test-MDATP-test\\invoice.exe');Start-Process 'C:\\test-MDATP-test\\invoice.exe'# ---------------------------------------------------------
# WHAT: EICAR standard antivirus test file
# WHY: EICAR is the industry-standard test string recognized by
# every antivirus engine worldwide. It is completely harmless
# but triggers an immediate AV detection, validating that
# Defender AV real-time protection is actively scanning files.
# DETECTION: "EICAR_Test_File" quarantine within seconds of file creation.
# TRUE POSITIVE: Expected activity - confirms AV engine is operational.
# ---------------------------------------------------------
# Write the EICAR test string to disk - Defender will quarantine it instantly
$eicar = 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
Set-Content -Path "$env:TEMP\eicar-test.txt" -Value $eicar
# Verify the detection was recorded by Defender AV
# OUTPUT: ThreatName = "EICAR_Test_File", ActionSuccess = True,
# Resources = path to the quarantined file.
Get-MpThreatDetection | Select-Object -First 5 | Format-List ThreatName, ActionSuccess, ResourcesOrganize your server fleet with device groups and tags to enable scoped policies, RBAC, and targeted investigations.
Production Servers with rank 1Environment:ProductionDevelopment Servers, Domain Controllers, and Database Servers# ---------------------------------------------------------
# WHAT: Set an MDE device tag via the registry
# WHY: Device tags enable dynamic device group membership in the
# Defender portal. Tags drive policy targeting, RBAC scoping,
# and automated investigation levels. The registry approach
# scales via GPO Registry Preferences to the entire fleet.
# OUTPUT: The tag appears in Device Inventory within ~30 minutes.
# NOTE: Only ONE tag can be set via registry ("Group" value).
# For multiple tags, use the portal or MDE API instead.
# ---------------------------------------------------------
# Create the DeviceTagging registry key under the MDE policy path
$tagPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Advanced Threat Protection\DeviceTagging"
New-Item -Path $tagPath -Force | Out-Null
# Set the tag value - use a consistent taxonomy (e.g., "Environment:Production")
Set-ItemProperty -Path $tagPath -Name "Group" -Value "Environment:Production"
# Verify the tag was written to the registry
Get-ItemProperty -Path $tagPath# ---------------------------------------------------------
# WHAT: Set a device tag using the MDE REST API
# WHY: The API supports multiple tags per device and enables
# automation - integrate with CMDB, deployment pipelines,
# or asset management tools to auto-tag at onboarding.
# ENDPOINT: POST /api/machines/{id}/tags
# AUTH: Requires a Bearer token from an Azure AD app registration
# with Machine.ReadWrite.All permission in WindowsDefenderATP.
# OUTPUT: 200 OK with updated machine object including the new tag.
# ---------------------------------------------------------
# Replace with the actual machine ID (from Device Inventory or API)
$machineId = "your-machine-id-here"
$token = "your-bearer-token"
# Build the request body - Action can be "Add" or "Remove"
$body = @{
Value = "Environment:Production"
Action = "Add"
} | ConvertTo-Json
# Call the MDE Machines Tags API
Invoke-RestMethod -Method POST `
-Uri "https://api.securitycenter.microsoft.com/api/machines/$machineId/tags" `
-Headers @{ Authorization = "Bearer $token"; "Content-Type" = "application/json" } `
-Body $bodyEnvironment:Production, Tier:Critical, Location:DC-East, and App:SQL.After validating Ring 0 pilot success for 48 hours, systematically expand onboarding to Ring 1 and Ring 2.
MDE-Onboarding-Ring0 GPO or create MDE-Onboarding-Ring1 with identical settingsMDE-Ring1-EarlyAdopters groupMDE-Onboarding-Ring2 GPO targeting the MDE-Ring2-Production group# ---------------------------------------------------------
# WHAT: Remotely check MDE sensor status across deployment rings
# WHY: After GPO rollout, you need to confirm every server's SENSE
# service is running. This script queries AD group membership
# to get the server list, then uses PowerShell Remoting
# (WinRM, port 5985/5986) to check the service status.
# OUTPUT: "ServerName : Running" = onboarded successfully
# "ServerName : Stopped" = onboarding script may not have run
# "ServerName : " (blank) = WinRM connectivity issue
# ---------------------------------------------------------
# Get server names from each ring's AD security group
$ring1Servers = Get-ADGroupMember -Identity "MDE-Ring1-EarlyAdopters" | Select-Object -ExpandProperty Name
$ring2Servers = Get-ADGroupMember -Identity "MDE-Ring2-Production" | Select-Object -ExpandProperty Name
# Remotely query the SENSE service status on each Ring 1 server
# NOTE: Requires WinRM enabled on target servers and appropriate admin rights.
foreach ($server in $ring1Servers) {
$sense = Invoke-Command -ComputerName $server -ScriptBlock {
(Get-Service -Name "sense" -ErrorAction SilentlyContinue).Status
} -ErrorAction SilentlyContinue
Write-Host "$server : $sense"
}Set up ongoing monitoring to ensure all onboarded servers maintain healthy sensor status, up-to-date signatures, and active telemetry.
// ---------------------------------------------------------
// WHAT: Find servers that stopped reporting telemetry in the last 24h
// WHY: Silent servers indicate sensor failures, network issues, or
// machines that were decommissioned without offboarding.
// These gaps leave blind spots in your security coverage.
// TABLE: DeviceInfo - contains device metadata refreshed every 15 min.
// DeviceType == "Server" filters out workstations/mobile.
// LOGIC: Looks back 7 days of data, finds each server's most recent
// report, then flags servers whose LastSeen is older than 24h.
// OUTPUT: Servers sorted oldest-first - top entries need urgent attention.
// FALSE POSITIVE: Servers powered off for maintenance may appear here.
// ---------------------------------------------------------
DeviceInfo
| where Timestamp > ago(7d)
| where DeviceType == "Server"
| summarize LastSeen = max(Timestamp) by DeviceName, OSPlatform
| where LastSeen < ago(24h)
| sort by LastSeen asc// ---------------------------------------------------------
// WHAT: Dashboard query - sensor health summary for the server fleet
// WHY: Provides a single-row KPI view: total servers, active vs.
// inactive vs. misconfigured sensors, and coverage percentage.
// Target: CoveragePercent should be 100% for full visibility.
// TABLE: DeviceInfo - SensorHealthState field tracks sensor status.
// LOGIC: arg_max(Timestamp, *) gets the latest record per DeviceId,
// avoiding double-counting servers that reported multiple times.
// SensorHealthState values:
// "Active" - sensor running, telemetry flowing normally
// "Inactive" - sensor stopped or server offline > 7 days
// "ImpairedCommunications" - sensor running but can't reach cloud
// OUTPUT: One row with counts and coverage %. Schedule as a custom
// detection rule to alert when CoveragePercent drops below 95%.
// ---------------------------------------------------------
DeviceInfo
| where Timestamp > ago(1d)
| where OSPlatform startswith "WindowsServer"
| summarize arg_max(Timestamp, *) by DeviceId
| summarize
TotalServers = count(),
ActiveSensors = countif(SensorHealthState == "Active"),
InactiveSensors = countif(SensorHealthState == "Inactive"),
MisconfiguredSensors = countif(SensorHealthState == "ImpairedCommunications")
| extend CoveragePercent = round(ActiveSensors * 100.0 / TotalServers, 1)// ---------------------------------------------------------
// WHAT: Check AV signature compliance across the entire fleet
// WHY: Outdated AV signatures leave servers vulnerable to known malware.
// This query uses the Threat & Vulnerability Management (TVM)
// secure configuration assessment to check compliance.
// TABLE: DeviceTvmSecureConfigurationAssessment - evaluates security
// configurations against Microsoft's recommended baselines.
// ConfigurationId "scid-2010" = "Real-time protection is enabled"
// (Other useful scids: scid-2011=PUA, scid-2012=Cloud protection,
// scid-2013=Tamper protection, scid-91=Network protection)
// LOGIC: Gets latest assessment per device, counts compliant vs. not.
// OUTPUT: Compliant = signatures current, NonCompliant = needs update.
// ---------------------------------------------------------
DeviceTvmSecureConfigurationAssessment
| where ConfigurationId == "scid-2010"
| where Timestamp > ago(1d)
| where isnotempty(DeviceName)
| summarize arg_max(Timestamp, *) by DeviceId
| summarize Compliant = countif(IsCompliant == 1), NonCompliant = countif(IsCompliant == 0)| Resource | Description |
|---|---|
| Onboard Windows servers to Microsoft Defender for Endpoint | Official guide for onboarding Windows Server 2019+ to MDE |
| Onboard devices using Group Policy | Deploy MDE onboarding packages via Group Policy Objects |
| Configure device proxy and Internet connectivity settings | Set up proxy and firewall rules for MDE service connectivity |
| Run a detection test on a newly onboarded device | Verify sensor health by running a simulated detection test |
| Create and manage device groups | Organize onboarded devices into groups for targeted policy management |
| Create and manage device tags | Apply tags to devices for filtering, scoping, and reporting |
| Fix unhealthy sensors in Microsoft Defender for Endpoint | Troubleshoot and resolve common MDE sensor health issues |
| Check sensor health state | Monitor sensor status and verify telemetry is flowing correctly |
| Plan your Microsoft Defender for Endpoint deployment | Design deployment rings and phased rollout strategies for MDE |
| Microsoft Defender for Endpoint documentation | Comprehensive reference for all MDE features and capabilities |