Beginner โฑ 120 min ๐Ÿ“‹ 12 Steps

Deploy MDI Sensors on All Supported Servers

Plan and deploy Microsoft Defender for Identity sensors on domain controllers, AD FS, AD CS, and Entra Connect servers. Covers sensor v2.x and v3.x selection, proxy configuration, gMSA setup, automated deployment, and ongoing health monitoring.

๐Ÿ“‹ Overview

About This Lab

Microsoft Defender for Identity (MDI) is a cloud-based security solution that leverages on-premises Active Directory signals to detect advanced threats, compromised identities, and malicious insider actions. MDI sensors run directly on domain controllers and other identity-role servers โ€” capturing authentication traffic (Kerberos, NTLM), LDAP queries, DNS lookups, and directory replication events in real time. No port mirroring required. Sensors are supported on domain controllers, AD FS federation servers, AD CS certification authority servers, and Microsoft Entra Connect servers. Two sensor versions exist: v3.x (preferred for Windows Server 2019+ DCs already running Defender for Endpoint โ€” portal-activated, uses local system account) and v2.x (classic installer for older DCs and all non-DC identity servers). This lab walks you through a complete enterprise deployment across all supported server types, including proxy configuration, gMSA setup, automated bulk deployment, and health monitoring.

๐Ÿข Enterprise Use Case

Fabrikam Inc., a manufacturing company with 5,000 employees, operates a multi-site AD forest with 12 domain controllers across two domains. The security team has identified gaps in identity threat visibility: pass-the-hash attacks, Kerberoasting, and DCSync operations go undetected by traditional log monitoring. A recent penetration test revealed that an attacker could escalate from compromised workstation to domain admin within 4 hours without triggering alerts. The CISO has mandated real-time identity threat detection across all DCs within 30 days.

Success criteria: 100% DC coverage, all sensors healthy, entity profiles generated, lateral movement paths mapped, initial security assessments reviewed.

๐ŸŽฏ What You Will Learn

  1. Understand MDI architecture, supported server types, and sensor v2.x vs v3.x selection
  2. Verify prerequisites across domain controllers, AD FS, AD CS, and Entra Connect servers
  3. Configure proxy settings for sensors that cannot reach the internet directly
  4. Create and configure a Group Managed Service Account (gMSA) for sensor operations
  5. Create the MDI instance and obtain the sensor access key from the Defender portal
  6. Install sensors using interactive and silent (automated) installation methods
  7. Deploy sensors to all remaining domain controllers using PowerShell automation
  8. Deploy sensors on AD FS, AD CS, and Entra Connect servers with required permissions
  9. Verify sensor health, connectivity, and data collection status
  10. Validate entity detection: users, computers, groups, and sensitive accounts
  11. Review identity security assessments and posture recommendations
  12. Establish ongoing sensor monitoring and maintenance procedures

๐Ÿ”‘ Why This Matters

Active Directory is the backbone of enterprise identity: 95% of Fortune 1000 companies rely on AD for authentication and authorization. Identity-based attacks increased by 300% year-over-year according to Microsoft Digital Defense Report, with credential theft being the most common initial access vector. The average time to detect an identity compromise is 207 days without proper monitoring. MDI reduces this to minutes. Attacks like Pass-the-Hash, Golden Ticket, and DCSync are invisible to traditional SIEM solutions because they use legitimate protocols. MDI detects behavioral anomalies within these protocols. MDI provides the identity signal layer for Microsoft Defender XDR, enabling correlated incidents spanning identity, endpoint, email, and cloud app detections.

โš™๏ธ Prerequisites

Supported Server Types

Server RoleSensor VersionNotes
Domain Controller (WS 2019+)v3.x (recommended) or v2.xv3.x requires MDE already deployed; uses local system account
Domain Controller (WS 2016)v2.x onlyInstall via downloaded setup package
AD FS Federation Serverv2.x (if standalone); v3.x (if on DC WS2019+)Not required on WAP servers
AD CS (Certification Authority)v2.x (if standalone); v3.x (if on DC WS2019+)CA Role Service only; skip offline servers
Microsoft Entra Connectv2.x (if standalone); v3.x (if on DC WS2019+)Deploy on both active and staging servers
RODC (Read-Only DC)v2.xSupported; deploy for full coverage

General Requirements

  • Licensing: Microsoft Defender for Identity (included in Microsoft 365 E5, EMS E5, or standalone)
  • OS (v2.x): Windows Server 2016 or later (2019/2022/2025 recommended)
  • OS (v3.x): Windows Server 2019 or later + March 2026 or later cumulative update
  • MDE (v3.x only): Defender for Endpoint must be onboarded on the server before activating v3.x
  • Hardware: Minimum 2 CPU cores and 6 GB RAM available on each server for the sensor
  • .NET Framework (v2.x): .NET Framework 4.7 or later installed
  • Admin Access: Domain Administrator privileges for gMSA creation and sensor installation
  • Portal Access: Security Administrator or Global Administrator role in security.microsoft.com
  • Network: Outbound HTTPS (443) from each sensor server to <workspace>sensorapi.atp.azure.com
  • Proxy: If direct internet access is unavailable, a proxy must be configured (see Step 3)
  • DNS: Servers must resolve *.atp.azure.com via DNS
  • DefenderForIdentity Module: PowerShell module providing New-MDIDSA, Test-MDISensorApiConnection, Set-MDIConfiguration, and more โ€” Install-Module DefenderForIdentity -Scope AllUsers. Supported on Windows PowerShell 5.1 and PowerShell 7.4+. On PS 7.4+, first run Import-Module -Name GroupPolicy -SkipEditionCheck. PowerShell 7.0–7.3 is not supported.
โš ๏ธ Important: On DCs processing more than 10,000 authentications/second, consider using the standalone sensor on a separate server with port mirroring. Use the capacity planning tool to validate sizing.

Step 1 ยท Review MDI Architecture and Plan Deployment

Understand the MDI deployment model before installing sensors. Sensors run as services on supported servers, capturing authentication protocols, LDAP queries, DNS lookups, and directory replication traffic via Windows Event Tracing (ETW) and network parsing.

Sensor Version Decision

Use sensor v3.x if: the server is a domain controller running Windows Server 2019 or later AND Defender for Endpoint is already deployed. Activation is done from the Defender portal โ€” no installer download needed. Runs under the LocalSystem account โ€” no DSA or gMSA is used or configurable.

Use sensor v2.x if: the DC runs Windows Server 2016, OR the server is a standalone AD FS / AD CS / Entra Connect server. Uses the downloaded setup package. A DSA/gMSA is required for AD FS, AD CS, and Entra Connect sensors; for DC sensors it is optional but recommended โ€” without one, SAM-R lateral movement queries, domain and trust mapping, cross-domain LDAP, and Deleted Objects container access are all disabled.

Mixed environments are fully supported โ€” v2.x and v3.x sensors report to the same workspace.

Architecture Components

  • MDI Sensor: Installed on each DC; captures authentication traffic using ETW and network parsing. no port mirroring needed
  • MDI Cloud Service: Hosted in Azure; performs behavioral analytics, machine learning, and threat detection
  • Microsoft Defender Portal: Unified management at security.microsoft.com for alerts, investigations, and health monitoring
  • DSA/gMSA Account (v2.x only): Directory Service Account used by v2.x sensors. Required for AD FS, AD CS, and Entra Connect sensors; optional but recommended for DC sensors (enables SAM-R lateral movement paths, domain and trust mapping, Deleted Objects container, and cross-domain LDAP queries). Not used by v3.x โ€” LocalSystem only.

Deployment Planning Checklist

  1. Inventory all domain controllers, AD FS, AD CS, and Entra Connect servers across all domains and sites
  2. Determine sensor version (v2.x or v3.x) for each server using the decision above
  3. Verify each server meets hardware, OS, and .NET prerequisites
  4. Determine if a proxy is required for any server to reach MDI cloud endpoints
  5. Test network connectivity from each server to MDI cloud endpoints
  6. Identify pilot servers to deploy first (start with non-critical servers)
  7. Create a change management ticket for each deployment batch
  8. Prepare a rollback plan: document the sensor uninstallation process
# WHAT: Inventory all domain controllers across every domain in the AD forest
# WHY:  MDI sensors must be deployed on ALL DCs - even one uncovered DC is a detection blind spot.
#       This script discovers DCs across all domains and sites so you can plan a phased rollout.
# OUTPUT: Table showing DC name, parent domain, AD site, OS version, and IP address
#         Use this list to prioritize deployment order (start with pilot DCs, then cover all remaining)
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$forest.Domains | ForEach-Object {
    $_.DomainControllers | Select-Object Name, Domain, SiteName, OSVersion,
        @{N='IPAddress';E={[System.Net.Dns]::GetHostAddresses($_.Name).IPAddressToString -join ', '}}
} | Format-Table -AutoSize
๐Ÿ’ก Pro Tip: Deploy sensors on all domain controllers. including RODCs. If even one DC is uncovered, attackers can target that DC to avoid detection.

Step 2 ยท Verify Prerequisites on Domain Controllers

Run prerequisite checks on each target DC to verify hardware resources, OS version, .NET Framework, and network connectivity.

Check OS Version and Resources

# WHAT: Verify that this DC meets the three core prerequisites for MDI sensor installation
# WHY:  The MDI sensor requires Server 2016+, at least 2 CPU cores + 6 GB RAM, and .NET 4.7+.
#       Installing on a DC that doesn't meet these minimums causes sensor crashes or data loss.
# OUTPUT: OS version, CPU core count, RAM in GB, and .NET Framework version with pass/fail assessment

# Check OS version (must be Server 2016+ - build 10.0.14393 or higher)
[System.Environment]::OSVersion.Version

# Check available CPU cores and RAM
# MDI sensor minimum: 2 cores, 6 GB RAM. High-traffic DCs (>10K auth/sec) need more.
$cpu = (Get-CimInstance Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum
$ramGB = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 1)
Write-Host "CPU Cores: $cpu | RAM: ${ramGB} GB"

# Check .NET Framework version (must be 4.7+ for sensor compatibility)
# The Release value maps to specific .NET versions per Microsoft documentation
$netRelease = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -EA SilentlyContinue).Release
$friendly = if($netRelease -ge 533320){'.NET 4.8.1+'} elseif($netRelease -ge 528040){'.NET 4.8'} elseif($netRelease -ge 461808){'.NET 4.7.2'} else {"Below 4.7 (Release: $netRelease)"}
Write-Host ".NET Framework: $friendly"

Install the DefenderForIdentity Module

๐Ÿ’ก PowerShell Compatibility: Supported on Windows PowerShell 5.1 and PowerShell 7.4+. On PS 7.4+, you must first import the GroupPolicy module with -SkipEditionCheck โ€” the code block below handles this automatically. PowerShell 7.0–7.3 is not supported.
# WHAT: Install the DefenderForIdentity module and handle PS version compatibility
# WHY:  The module depends on GroupPolicy. PS 5.1 loads it natively; PS 7.4+ needs
#       -SkipEditionCheck. PS 7.0-7.3 is not supported - upgrade or use PS 5.1.

# Step 0: handle PS version compatibility
if ($PSVersionTable.PSEdition -eq 'Core') {
    if ($PSVersionTable.PSVersion -lt [Version]'7.4') {
        throw "PowerShell $($PSVersionTable.PSVersion) is not supported. Use PS 5.1 or PS 7.4+."
    }
    # PS 7.4+: import GroupPolicy with -SkipEditionCheck before loading the module
    Import-Module -Name GroupPolicy -SkipEditionCheck
}

# Install once on any management server with PSGallery access
# -AllowClobber prevents conflicts with the older ATPModule cmdlets
Install-Module -Name DefenderForIdentity -Scope AllUsers -Force -AllowClobber
Import-Module DefenderForIdentity
Get-Command -Module DefenderForIdentity | Select-Object Name

Test Network Connectivity to MDI Endpoints

Use Test-MDISensorApiConnection from the module for a definitive connectivity test. Fall back to Test-NetConnection if the module is not yet installed.

# WHAT: Validate connectivity to your MDI workspace API endpoint using the module
# WHY:  Test-MDISensorApiConnection tests the exact endpoint and auth path the sensor uses โ€”
#       it is more accurate than a generic TCP test and catches proxy/cert issues too.
# Replace "contoso-corp" with your MDI workspace name from:
#   security.microsoft.com > Settings > Identities > About
Import-Module DefenderForIdentity
$workspaceName = "contoso-corp"
$apiUrl = "https://$workspaceName`sensorapi.atp.azure.com"

# Test via module (requires module on this machine)
Test-MDISensorApiConnection -BypassConfiguration -SensorApiUrl $apiUrl -SensorType 'Classic'

# Fallback: manual TCP check if module is unavailable
$endpoints = @("$workspaceName`sensorapi.atp.azure.com","crl.microsoft.com","ctldl.windowsupdate.com","www.microsoft.com")
foreach ($ep in $endpoints) {
    $r = Test-NetConnection -ComputerName $ep -Port 443 -WarningAction SilentlyContinue
    $s = if ($r.TcpTestSucceeded) { "OK    " } else { "FAILED" }
    Write-Host "[$s] $ep" -ForegroundColor $(if($r.TcpTestSucceeded){'Green'}else{'Red'})
}

Batch Check All DCs Remotely

# WHAT: Run prerequisite checks on ALL domain controllers in bulk via PowerShell remoting
# WHY:  Manually checking each DC is time-consuming in large environments. This script validates
#       CPU (โ‰ฅ2 cores), RAM (โ‰ฅ6 GB), and .NET Framework (โ‰ฅ4.7, release 461308) on every DC.
# OUTPUT: Table with DC name, CPU cores, RAM, .NET release, and a Ready (True/False) column.
#         DCs showing Ready=False must be upgraded before sensor installation.

# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory
$dcs = (Get-ADDomainController -Filter *).Name
$results = foreach ($dc in $dcs) {
    Invoke-Command -ComputerName $dc -ScriptBlock {
        $cpu = (Get-CimInstance Win32_Processor | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum
        $ramGB = [math]::Round((Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB, 1)
        # Release 461308 = .NET 4.7.1 (minimum supported by MDI sensor)
        $netRelease = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -EA SilentlyContinue).Release
        [PSCustomObject]@{
            DC = $env:COMPUTERNAME; CPUCores = $cpu; RamGB = $ramGB; DotNetRel = $netRelease
            Ready = ($cpu -ge 2 -and $ramGB -ge 6 -and $netRelease -ge 461308)
        }
    } -ErrorAction SilentlyContinue
}
$results | Format-Table -AutoSize
โš ๏ธ Important: If .NET Framework 4.7 is missing, download from Microsoft .NET Downloads. A reboot is required after installation.

Run the Official MDI Readiness Script

โœ… Microsoft Recommendation: Before deploying sensors, Microsoft recommends running Test-MdiReadiness.ps1 to validate all prerequisites across your environment. Download it from the Defender XDR portal โ†’ Identities โ†’ Tools (Preview) or from the microsoft/Microsoft-Defender-for-Identity GitHub repository.
# WHAT: Run Microsoft's official MDI prerequisite validation script
# WHY:  Test-MdiReadiness.ps1 checks all environment requirements in one pass โ€”
#       OS version, .NET, disk, network, proxy, ports, and sensor service accounts.
#       Resolves issues it finds before starting sensor deployment.

# Option A: Run directly from Defender XDR portal download
# Download from: security.microsoft.com > Settings > Identities > Tools (Preview)

# Option B: Run from GitHub (verify the script before executing)
# https://github.com/microsoft/Microsoft-Defender-for-Identity

# After downloading, run on each target server (or remotely):
.\Test-MdiReadiness.ps1

# To test all DCs in the domain remotely:
# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory
$dcs = (Get-ADDomainController -Filter *).Name
foreach ($dc in $dcs) {
    Invoke-Command -ComputerName $dc -FilePath .\Test-MdiReadiness.ps1
}

Step 3 ยท Configure Proxy Settings

If your domain controllers or identity servers cannot reach the internet directly, configure a proxy. MDI does not support SSL inspection or intercepting proxies โ€” the proxy must pass traffic through unchanged. Skip this step if your servers have direct internet access.

Required URLs to Allow

# WHAT: Test outbound connectivity to MDI endpoints โ€” run on each sensor server
# WHY:  If these fail, configure proxy settings below before installing the sensor.
#       Replace "contoso-corp" with your actual MDI workspace name from:
#       security.microsoft.com > Settings > Identities > About
$workspaceName = "contoso-corp"
$endpoints = @(
    "$workspaceName`sensorapi.atp.azure.com",
    "crl.microsoft.com",                        # Certificate revocation list
    "ctldl.windowsupdate.com",                  # Trusted root update
    "www.microsoft.com"                         # PKI certs (pki/* and pkiops/*)
)
foreach ($ep in $endpoints) {
    $r = Test-NetConnection -ComputerName $ep -Port 443 -WarningAction SilentlyContinue
    $s = if ($r.TcpTestSucceeded) { "OK    " } else { "FAILED" }
    Write-Host "[$s] $ep" -ForegroundColor $(if($r.TcpTestSucceeded){'Green'}else{'Red'})
}

Option A โ€” Configure Proxy During Installation (Recommended)

# WHAT: Install the MDI sensor and set proxy in a single command
# WHY:  Configuring proxy at install time is the cleanest method โ€” only MDI sensor
#       services use this proxy, not other system services.
# Replace values with your proxy address, domain account, and access key.
$installer  = "\\contoso.com\NETLOGON\MDI-Sensor\Setup\Azure ATP Sensor Setup.exe"
$accessKey  = "YOUR-ACCESS-KEY-HERE"
$proxyUrl   = "http://proxy.contoso.com:8080"
$proxyUser  = "CONTOSO\svc-proxy"
$proxyPass  = "ProxyPassword"

Start-Process -FilePath $installer -Wait -NoNewWindow -ArgumentList `
    "/quiet",
    "NetFrameworkCommandLineArguments=`"/q`"",
    "AccessKey=`"$accessKey`"",
    "ProxyUrl=`"$proxyUrl`"",
    "ProxyUserName=`"$proxyUser`"",
    "ProxyUserPassword=`"$proxyPass`""

Option B โ€” Configure Proxy After Installation via PowerShell

# PS 5.1 or PS 7.4+ required. On PS 7.4+: Import-Module -Name GroupPolicy -SkipEditionCheck
# WHAT: View and update proxy settings using the DefenderForIdentity PowerShell module
# WHY:  Use this to update proxy settings on already-deployed sensors without reinstalling.
# Install the module first if not present:
# Install-Module DefenderForIdentity -Force

# View current proxy config
Get-MDISensorProxyConfiguration

# Set proxy (unauthenticated)
Set-MDISensorProxyConfiguration -ProxyUrl 'http://proxy.contoso.com:8080'

# Set proxy with credentials (use Get-Credential for secure interactive input)
$cred = Get-Credential -Message "Enter proxy credentials (domain\user format)"
Set-MDISensorProxyConfiguration -ProxyUrl 'http://proxy.contoso.com:8080' -ProxyCredential $cred

# Remove proxy config entirely
Clear-MDISensorProxyConfiguration

Option C โ€” Configure Proxy via Deployer.exe (CLI)

# WHAT: Set proxy using the sensor deployment tool (cmd / batch scripts)
# Path: C:\Program Files\Azure Advanced Threat Protection Sensor\<version>\
# Run from the sensor installation directory on each DC.

# Set proxy with credentials
Microsoft.Tri.Sensor.Deployment.Deployer.exe ProxyUrl="http://proxy.contoso.com:8080" ProxyUserName="CONTOSO\svc-proxy" ProxyUserPassword="myP@ssword"

# Remove proxy configuration
Microsoft.Tri.Sensor.Deployment.Deployer.exe ClearProxyConfiguration
โš ๏ธ Important: MDI does not support SSL inspection. If your proxy performs SSL/TLS interception (e.g. Zscaler, BlueCoat), you must bypass it for *.atp.azure.com. Certificate pinning will cause authentication failures.

Step 4 ยท Configure the Directory Service Account (DSA/gMSA) โ€” v2.x Only

A Directory Service Account (DSA) applies to v2.x sensors only. A gMSA is the recommended DSA type because AD rotates its password automatically.

๐Ÿ”ด Required for AD FS, AD CS, and Entra Connect sensors โ€” sensors on these server types cannot use the local service account and require a DSA to connect to the domain.
โš ๏ธ Required for specific features on DC sensors: SAM-R lateral movement path queries, Deleted Objects container access, domain and trust mapping (runs at sensor startup and every 10 minutes), cross-domain LDAP queries. Without a DSA, the sensor falls back to the local service account and these features are disabled.
๐Ÿ’ก v3.x: No DSA or gMSA is used or configurable โ€” v3.x sensors run under LocalSystem exclusively. If all your DCs run v3.x sensors, skip this step entirely.

Create the KDS Root Key

# WHAT: Check for and create the KDS (Key Distribution Services) Root Key in Active Directory
# WHY:  gMSA accounts use the KDS Root Key to generate and rotate passwords automatically.
#       Without this key, New-ADServiceAccount will fail. The key must replicate to all DCs.
# OUTPUT: Existing key details (GUID, creation time) or confirmation of new key creation

# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory

# Check if KDS Root Key exists (required for gMSA)
Get-KdsRootKey

# If no key exists, create one
# Production: -EffectiveImmediately still requires ~10 hours for AD replication across all DCs
Add-KdsRootKey -EffectiveImmediately

# Lab only: backdate the effective time to skip the 10-hour replication wait
# WARNING: Do NOT use this in production - DCs that haven't replicated the key will reject gMSA requests
# Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))

Create the gMSA Account

# WHAT: Create a Group Managed Service Account (gMSA) for MDI sensor directory queries
# WHY:  MDI sensors need an AD account to query objects, resolve entities, and read deleted items.
#       A gMSA is preferred over a standard account because AD automatically rotates its password
#       every 30 days - eliminating password management overhead and reducing credential theft risk.
# OUTPUT: gMSA created in AD, installed on the local DC, and validated (Test returns True/False)
Import-Module ActiveDirectory

# Create the gMSA - PrincipalsAllowedToRetrieveManagedPassword limits which computers can use it
# AES-only encryption prevents downgrade attacks (RC4/DES are vulnerable to Kerberoasting)
New-ADServiceAccount -Name "svc-MDI" `
    -DNSHostName "svc-MDI.contoso.com" `
    -Description "Service account for Microsoft Defender for Identity sensors" `
    -PrincipalsAllowedToRetrieveManagedPassword "Domain Controllers" `
    -KerberosEncryptionType AES128,AES256

# Install the gMSA on each DC (caches the password locally so the sensor can use it)
Install-ADServiceAccount -Identity "svc-MDI"

# Verify the gMSA can be used on this DC (should return True)
# If False: the DC is not in the PrincipalsAllowedToRetrieveManagedPassword group
Test-ADServiceAccount -Identity "svc-MDI"

Module Approach โ€” New-MDIDSA + Test-MDIDSA (Recommended)

The DefenderForIdentity module wraps the manual gMSA steps into a single command and automatically validates permissions, KDS key, and SAMR access.

# PS 5.1 or PS 7.4+ required. On PS 7.4+: Import-Module -Name GroupPolicy -SkipEditionCheck
# WHAT: Create the MDI Directory Service Account (gMSA) using the module and validate it
# WHY:  New-MDIDSA handles KDS key check, New-ADServiceAccount, Install-ADServiceAccount,
#       and the Deleted Objects ACL grant in one call - reducing manual error.
#       Test-MDIDSA then verifies the account has all permissions MDI sensors actually need.
Import-Module DefenderForIdentity

# Create the gMSA - -GmsaGroupName limits which computers can retrieve the password
New-MDIDSA -Identity "svc-MDI" -GmsaGroupName "Domain Controllers"

# Validate all required permissions are in place (returns True on success)
$dsaOk = Test-MDIDSA -Identity "svc-MDI"
if (-not $dsaOk) { Write-Warning "DSA validation failed - check AD permissions and KDS key replication" }

# For multi-domain forests, repeat for each domain:
# New-MDIDSA -Identity "svc-MDI" -GmsaGroupName "Domain Controllers" -Domain "child.contoso.com"

Grant Required Permissions (Manual Approach)

๐Ÿ’ก Module users: New-MDIDSA automatically sets the Deleted Objects container permissions โ€” skip the code below if you used the module approach above.
# WHAT: Grant read access to the AD Deleted Objects container for the MDI service account
# WHY:  MDI needs to read deleted AD objects to correlate historical entity data.
#       The Deleted Objects container has restricted ACLs by default.
# PERMISSIONS: List Contents (LC) + Read Property (RP) โ€” grant to a security GROUP, not directly
#              to the gMSA. The gMSA must be a member of this group.
# NOTE: New-MDIDSA (module approach above) handles this automatically.
Import-Module ActiveDirectory

# Step 1: For gMSA, create a security group and add the gMSA as a member
$groupName = "MDI-DSA-Readers"
New-ADGroup -Name $groupName -SamAccountName $groupName -GroupCategory Security `
    -GroupScope Universal -Description "Group for MDI DSA Deleted Objects read access"
Add-ADGroupMember -Identity $groupName -Members "svc-MDI$"

# Step 2: Get the Deleted Objects container DN and domain name
$distinguishedName = ([adsi]'').distinguishedName.Value
$deletedObjectsDN  = "CN=Deleted Objects,$distinguishedName"
$domain            = ([adsi]'').name.Value

# Step 3: Take ownership, then grant LC+RP (LCRP) to the group
C:\Windows\System32\dsacls.exe "$deletedObjectsDN" /takeOwnership
C:\Windows\System32\dsacls.exe "$deletedObjectsDN" /G "${domain}\${groupName}:LCRP"

# For a regular (non-gMSA) user account, grant permissions directly to the account:
# C:\Windows\System32\dsacls.exe "$deletedObjectsDN" /G "contoso\mdiSvcUser:LCRP"
๐Ÿ’ก Pro Tip: For multi-domain forests, create a separate gMSA in each domain. This simplifies permission management and avoids cross-domain trust issues.

Step 5 ยท Create the MDI Instance and Obtain the Access Key

Create your MDI instance in the Microsoft Defender portal and download the sensor installer.

Portal Instructions

  1. Navigate to security.microsoft.com > Settings > Identities
  2. Click Create to provision a new MDI instance (if first deployment)
  3. Select your preferred data center region (closest to your DCs)
  4. Navigate to Settings > Identities > Sensors
  5. Click + Add sensor to view the Access key
  6. Copy the access key securely. needed during sensor installation on each DC
  7. Click Download sensor setup to get Azure ATP Sensor Setup.zip (the installer retains the legacy "Azure ATP" filename)
  8. Copy the installer to a network share: \\contoso.com\NETLOGON\MDI-Sensor\
# WHAT: Create a network share for the MDI sensor installer and extract it for deployment
# WHY:  Placing the installer in NETLOGON ensures it's replicated to all DCs via DFS-R,
#       making it accessible from any DC during automated bulk deployment (Step 7).
# OUTPUT: Extracted installer at \\DC01\NETLOGON\MDI-Sensor\Setup\Azure ATP Sensor Setup.exe
New-Item -Path "\\DC01\NETLOGON\MDI-Sensor" -ItemType Directory -Force
Copy-Item -Path "C:\Downloads\Azure ATP Sensor Setup.zip" -Destination "\\DC01\NETLOGON\MDI-Sensor\"
Expand-Archive -Path "\\DC01\NETLOGON\MDI-Sensor\Azure ATP Sensor Setup.zip" `
               -DestinationPath "\\DC01\NETLOGON\MDI-Sensor\Setup" -Force
โš ๏ธ Important: The access key is tenant-specific. Treat it as a secret. store it in Azure Key Vault and restrict access.

Step 6 ยท Register the Directory Service Account in the Portal โ€” v2.x Only

Register the v2.x DSA/gMSA in MDI portal settings so sensors know which account to use. Skip this step if all sensors are v3.x โ€” v3.x uses LocalSystem and has no DSA configuration.

  1. In the Defender portal > Settings > Identities > Directory Service Accounts
  2. Click + Add credentials
  3. Select Group Managed Service Account (gMSA)
  4. Enter account name: svc-MDI$ (account name only, with $ suffix โ€” no domain prefix)
  5. Enter domain: contoso.com (full FQDN of the domain where the account is located)
  6. Click Save
  7. For multi-domain forests, add a service account for each domain

Step 7 ยท Install the MDI Sensor on the First Domain Controller

Install the sensor on your pilot DC first. Use the silent installation for scripted, reproducible deployments.

Interactive Installation

  1. Log in to the pilot DC with Domain Administrator credentials
  2. Navigate to \\contoso.com\NETLOGON\MDI-Sensor\Setup\
  3. Run Azure ATP Sensor Setup.exe as Administrator
  4. Select your language and click Next
  5. Paste the Access key from Step 4
  6. Click Install and wait 5–10 minutes
  7. No reboot required. the sensor service starts automatically

Silent Installation (Recommended)

# WHAT: Install the MDI sensor silently (unattended) on a domain controller
# WHY:  Silent installation enables scripted, reproducible deployments across many DCs.
#       The /quiet flag suppresses the GUI wizard. The access key authenticates the sensor
#       to your MDI tenant in the Defender portal.
# OUTPUT: AATPSensor service running, and the last 20 lines of sensor.log confirming startup

# Replace YOUR-ACCESS-KEY with the tenant-specific key from Defender portal > Settings > Identities
$accessKey = "YOUR-ACCESS-KEY-HERE"
$installerPath = "\\contoso.com\NETLOGON\MDI-Sensor\Setup\Azure ATP Sensor Setup.exe"

# /quiet: No GUI | NetFrameworkCommandLineArguments: Silently installs .NET if needed
# AccessKey: Authenticates this sensor to your MDI cloud instance
Start-Process -FilePath $installerPath `
    -ArgumentList "/quiet", "NetFrameworkCommandLineArguments=`"/q`"", "AccessKey=`"$accessKey`"" `
    -Wait -NoNewWindow

# Verify the sensor service is running (Status should be "Running")
Get-Service -Name "AATPSensor" | Select-Object Name, Status, StartType
โš ๏ธ Important: The installer includes Npcap for network capture. If you have a pre-existing Npcap installation, verify network capture is working by checking the sensor logs.

Step 8 ยท Deploy Sensors to All Remaining Domain Controllers

After validating the pilot, deploy sensors to all remaining DCs using PowerShell automation.

# WHAT: Automated bulk deployment of MDI sensor to all remaining domain controllers
# WHY:  After validating the sensor on a pilot DC, this script deploys to every other DC
#       using PowerShell remoting. Each DC copies the installer locally, runs it silently,
#       and reports back whether the AATPSensor service started successfully.
# OUTPUT: Table with DC name, installer exit code, sensor status, and SUCCESS/CHECK/ERROR result
#         Any DC showing CHECK or ERROR requires manual investigation.
$accessKey = "YOUR-ACCESS-KEY-HERE"
$installerShare = "\\contoso.com\NETLOGON\MDI-Sensor\Setup\Azure ATP Sensor Setup.exe"
$pilotDC = "DC01"

# Exclude the pilot DC (already installed in Step 6)
# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory
$targetDCs = (Get-ADDomainController -Filter *).Name | Where-Object { $_ -ne $pilotDC }
$results = foreach ($dc in $targetDCs) {
    Write-Host "Deploying to $dc..." -ForegroundColor Cyan
    try {
        $r = Invoke-Command -ComputerName $dc -ScriptBlock {
            param($installer, $key)
            # Copy installer locally to avoid network latency during installation
            $localPath = "C:\Temp\MDI-Setup"
            New-Item -Path $localPath -ItemType Directory -Force | Out-Null
            Copy-Item -Path $installer -Destination "$localPath\Setup.exe" -Force
            # Run silent install with the tenant access key
            $proc = Start-Process -FilePath "$localPath\Setup.exe" `
                -ArgumentList "/quiet","NetFrameworkCommandLineArguments=`"/q`"","AccessKey=`"$key`"" `
                -Wait -PassThru -NoNewWindow
            # Verify the sensor service started after installation
            $svc = Get-Service -Name "AATPSensor" -ErrorAction SilentlyContinue
            [PSCustomObject]@{ ExitCode = $proc.ExitCode; Status = $svc.Status }
        } -ArgumentList $installerShare, $accessKey -ErrorAction Stop
        [PSCustomObject]@{ DC=$dc; ExitCode=$r.ExitCode; Sensor=$r.Status; Result=if($r.Status -eq 'Running'){'SUCCESS'}else{'CHECK'} }
    } catch {
        [PSCustomObject]@{ DC=$dc; ExitCode='N/A'; Sensor='ERROR'; Result=$_.Exception.Message }
    }
}
$results | Format-Table -AutoSize
๐Ÿ’ก Pro Tip: For large environments (50+ DCs), deploy via SCCM/MECM for better tracking, retry logic, and compliance reporting.

Step 9 ยท Deploy Sensors on AD FS, AD CS, and Entra Connect Servers

Deploy the v2.x sensor on standalone AD FS, AD CS, and Entra Connect servers (those that are not domain controllers). If these roles run on a domain controller running Windows Server 2019 or later, use the v3.x activation in Step 7 instead.

โš ๏ธ Scope rules: AD FS โ€” federation servers only (not WAP).  AD CS โ€” servers with CA Role Service only (skip offline servers).  Entra Connect โ€” deploy on both active and staging servers.  Standalone non-DC servers cannot use local system account โ€” a Directory Service Account (gMSA from Step 4) is required.

Install Sensor on Non-DC Identity Servers

# WHAT: Silent install of MDI v2.x sensor on AD FS, AD CS, or Entra Connect servers
# WHY:  Same installer as DCs, but these servers require a Directory Service Account
#       and additional database permission grants below.
$accessKey  = "YOUR-ACCESS-KEY-HERE"
$installer  = "\\contoso.com\NETLOGON\MDI-Sensor\Setup\Azure ATP Sensor Setup.exe"

# List of non-DC identity servers to deploy to
$identityServers = @("ADFS01","ADFS02","ADCS01","EntraConnect01","EntraConnect02-Staging")

$results = foreach ($server in $identityServers) {
    Write-Host "Deploying to $server..." -ForegroundColor Cyan
    try {
        $r = Invoke-Command -ComputerName $server -ScriptBlock {
            param($installer, $key)
            $localPath = "C:\Temp\MDI-Setup"
            New-Item -Path $localPath -ItemType Directory -Force | Out-Null
            Copy-Item -Path $installer -Destination "$localPath\Setup.exe" -Force
            $proc = Start-Process -FilePath "$localPath\Setup.exe" `
                -ArgumentList "/quiet","NetFrameworkCommandLineArguments=`"/q`"","AccessKey=`"$key`"" `
                -Wait -PassThru -NoNewWindow
            $svc = Get-Service -Name "AATPSensor" -ErrorAction SilentlyContinue
            [PSCustomObject]@{ ExitCode = $proc.ExitCode; Status = $svc.Status }
        } -ArgumentList $installer, $accessKey -ErrorAction Stop
        [PSCustomObject]@{ Server=$server; ExitCode=$r.ExitCode; Status=$r.Status; Result=if($r.Status -eq 'Running'){'SUCCESS'}else{'CHECK'} }
    } catch {
        [PSCustomObject]@{ Server=$server; ExitCode='N/A'; Status='ERROR'; Result=$_.Exception.Message }
    }
}
$results | Format-Table -AutoSize

Grant gMSA Access to the AD FS Database

MDI needs read access to the AD FS configuration database to monitor federation authentication. Run this on each AD FS server individually (permissions are not replicated).

# WHAT: Grant the MDI gMSA db_datareader access to the AD FS configuration database
# WHY:  Without this, the sensor cannot read AD FS events and federation auth is invisible to MDI.
#       Works for both Windows Internal Database (WID) and external SQL Server.
# Replace DOMAIN1\mdiSvc01 with your gMSA name (include the $ for gMSA: DOMAIN1\mdiSvc01$).

$gMSA = "DOMAIN1\mdiSvc01$"
$dbName = "AdfsConfigurationV4"  # Check your AD FS version โ€” may be AdfsConfiguration or AdfsConfigurationV3

# For Windows Internal Database (WID):
$connString = "server=\\.\pipe\MICROSOFT##WID\tsql\query;database=$dbName;trusted_connection=true;"

# For external SQL Server, use: "server=SQLSERVER\INSTANCE;database=$dbName;trusted_connection=true;"
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = @"
USE [master];
CREATE LOGIN [$gMSA] FROM WINDOWS WITH DEFAULT_DATABASE=[master];
USE [$dbName];
CREATE USER [$gMSA] FOR LOGIN [$gMSA];
ALTER ROLE [db_datareader] ADD MEMBER [$gMSA];
GRANT CONNECT TO [$gMSA];
GRANT SELECT TO [$gMSA];
"@
$cmd.ExecuteNonQuery() | Out-Null
$conn.Close()
Write-Host "AD FS DB permissions granted for $gMSA on $dbName" -ForegroundColor Green

Grant Permissions to the Entra Connect (ADSync) Database

โš ๏ธ External SQL only: This step applies only when the ADSync database is hosted on an external SQL Server instance. If Entra Connect is using the default LocalDB installation, this permission grant is not required.
# WHAT: Grant MDI sensor permissions to the Entra Connect ADSync database
# NOTE: Only required when ADSync DB is on an external SQL Server instance.
#       Entra Connect uses LocalDB by default - check SQLInstance registry value first.
#       Run on each Entra Connect server (both active and staging).

$entraConnectServerDomain    = $env:USERDOMAIN
$entraConnectServerComputer  = $env:COMPUTERNAME
$dbName      = (Get-ItemProperty 'registry::HKLM\SYSTEM\CurrentControlSet\Services\ADSync\Parameters' -Name 'DBName').DBName
$sqlServer   = (Get-ItemProperty 'registry::HKLM\SYSTEM\CurrentControlSet\Services\ADSync\Parameters' -Name 'Server').Server
$sqlInstance = (Get-ItemProperty 'registry::HKLM\SYSTEM\CurrentControlSet\Services\ADSync\Parameters' -Name 'SQLInstance').SQLInstance

$connString = "server={0}\{1};database={2};trusted_connection=true;" -f $sqlServer, $sqlInstance, $dbName
$conn = New-Object System.Data.SqlClient.SqlConnection($connString)
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = @"
USE [master];
CREATE LOGIN [{0}\{1}$] FROM WINDOWS WITH DEFAULT_DATABASE=[master];
USE [{2}];
CREATE USER [{0}\{1}$] FOR LOGIN [{0}\{1}$];
GRANT CONNECT TO [{0}\{1}$];
GRANT SELECT TO [{0}\{1}$];
GRANT EXECUTE ON OBJECT::{2}.dbo.mms_get_globalsettings TO [{0}\{1}$];
GRANT EXECUTE ON OBJECT::{2}.dbo.mms_get_connectors TO [{0}\{1}$];
"@ -f $entraConnectServerDomain, $entraConnectServerComputer, $dbName
$cmd.ExecuteNonQuery() | Out-Null
$conn.Close()
Write-Host "Entra Connect DB permissions granted" -ForegroundColor Green

Post-Install: Verify or Update the Resolver Domain Controller (Optional)

During installation on an AD FS, AD CS, or Entra Connect server, the closest domain controller is automatically selected. Use the following steps to check or update it if needed.

  1. In the Defender portal > Settings > Identities > Sensors
  2. Locate the AD FS / AD CS / Entra Connect sensor
  3. In the Domain controller (FQDN) box, enter the FQDN of the resolver DC (e.g. DC01.contoso.com)
  4. Select + Add to add the FQDN, then select Save

Validate AD FS / AD CS Sensor Data (Advanced Hunting)

# Validate AD FS sensor โ€” run in Defender portal > Hunting > Advanced Hunting
IdentityLogonEvents | where Protocol contains 'Adfs'
# Expected: rows with LogonType = "Logon with ADFS authentication"

# Validate AD CS sensor
IdentityDirectoryEvents | where Protocol == "Adcs"
# Expected: certificate issuance events (success and failure)

Step 10 ยท Verify Sensor Health in the Defender Portal

Verify all sensors are healthy, connected, and collecting data.

Portal Verification

  1. Navigate to security.microsoft.com > Settings > Identities > Sensors
  2. Verify each sensor shows green health and Running status
  3. Check Last connected timestamp. should be within the last few minutes
  4. Click each sensor for detailed metrics: CPU, memory, network activity
  5. Address any health alerts (yellow or red indicators)

Common Health Alerts

  • Directory services not configured: Add the gMSA in Settings > Identities > Directory Service Accounts
  • Sensor not receiving traffic: Verify Npcap is installed and the sensor has capture permissions
  • Sensor service stopped: Check logs and restart with Restart-Service AATPSensor
  • Outdated version: Sensors auto-update; verify auto-update isn't blocked by GPO
# WHAT: Check the MDI sensor and updater service status on every domain controller
# WHY:  After deploying sensors, verify all DCs report healthy. The AATPSensor service captures
#       traffic; the AATPSensorUpdater service handles automatic version updates from Microsoft.
#       Any DC where the sensor is not Running represents a detection gap.
# OUTPUT: Per-DC status line: Sensor status, Updater status, and installed sensor version
#         Look for: Sensor=Running, Updater=Running, Version matching latest release
# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory
$dcs = (Get-ADDomainController -Filter *).Name
foreach ($dc in $dcs) {
    $svc = Invoke-Command -ComputerName $dc -ScriptBlock {
        $sensor = Get-Service -Name "AATPSensor" -ErrorAction SilentlyContinue
        $updater = Get-Service -Name "AATPSensorUpdater" -ErrorAction SilentlyContinue
        [PSCustomObject]@{ Sensor=$sensor.Status; Updater=$updater.Status }
    } -EA SilentlyContinue
    Write-Host "$dc | Sensor: $($svc.Sensor) | Updater: $($svc.Updater)"
}

Module Validation โ€” Test-MDIConfiguration + New-MDIConfigurationReport

# PS 5.1 or PS 7.4+ required. On PS 7.4+: Import-Module -Name GroupPolicy -SkipEditionCheck
# WHAT: Run a full MDI configuration audit using the DefenderForIdentity module
# WHY:  Test-MDIConfiguration checks that all required GPOs, audit policies, and configurations
#       are correctly applied. New-MDIConfigurationReport generates an HTML+JSON report for
#       review and record-keeping. Run these after every deployment.
Import-Module DefenderForIdentity

# Test all MDI-required domain configurations (audit policies, SAMR, etc.)
$configOk = Test-MDIConfiguration -Mode Domain -Configuration All
Write-Host "Domain config test: $(if($configOk){'PASSED'}else{'FAILED - review report'})" `
    -ForegroundColor $(if($configOk){'Green'}else{'Red'})

# Also validate DSA permissions are still intact
$dsaOk = Test-MDIDSA -Identity "svc-MDI"
Write-Host "DSA permissions:    $(if($dsaOk){'PASSED'}else{'FAILED - check gMSA'})" `
    -ForegroundColor $(if($dsaOk){'Green'}else{'Red'})

# Generate a full configuration report (HTML + JSON)
$reportPath = "$env:USERPROFILE\Desktop\MDI-ConfigReport-$(Get-Date -Format 'yyyyMMdd-HHmm')"
New-MDIConfigurationReport -Path $reportPath
Write-Host "Report saved: $reportPath.html" -ForegroundColor Cyan
๐Ÿ’ก Pro Tip: Save the New-MDIConfigurationReport output after each deployment. It serves as a change baseline โ€” run it again after any GPO or AD change to quickly spot configuration drift.

Step 11 ยท Validate Entity Detection and Security Assessments

Verify MDI is discovering entities (users, computers, groups) and generating security assessments.

Verify Entity Discovery

  1. Navigate to Assets > Identities in the Defender portal
  2. Verify users, computers, and service accounts appear in the inventory
  3. Click a user to view their profile: activity timeline, group memberships, risk score
  4. Check that domain admins and enterprise admins have the Sensitive tag

Review Identity Security Assessments

  1. In the Defender portal, navigate to identity security assessments (location varies โ€” check Secure Score or the Identities section)
  2. Review key findings:
    • Accounts with non-expiring passwords
    • Dormant entities in sensitive groups
    • Entities exposing credentials in clear text
    • Unsecured SID History attributes
    • Weak cipher usage (DES, RC4) in Kerberos
    • Unmonitored domain controllers
  3. Prioritize High impact findings for immediate remediation
๐Ÿ’ก Pro Tip: Entity detection and lateral movement path calculation can take 24–48 hours. The behavioral learning period is typically 30 days.

Step 12 ยท Establish Ongoing Monitoring and Maintenance

Set up monitoring procedures to maintain sensor health and respond to issues proactively.

Monitoring Schedule

  • Daily: Check sensor health status; investigate any yellow or red alerts
  • Weekly: Review identity security assessments; track remediation progress
  • Monthly: Verify all DCs have sensors (check for newly provisioned DCs); review resource consumption
  • Quarterly: Test sensor failover; verify sensor auto-updates are working

Automated Health Monitoring Script

# WHAT: Automated daily health monitoring script for all MDI sensors across the AD forest
# WHY:  Sensors can stop due to resource exhaustion, service crashes, OS patches, or GPO changes.
#       This script should run as a scheduled task (daily) to catch unhealthy sensors within 24h.
# OUTPUT: Green HEALTHY / Red UNHEALTHY / Yellow ERROR status per DC
#         If any unhealthy sensors are found, a summary with required actions is displayed.
#         Integrate the $unhealthy output with your alerting system (email, Teams, ITSM ticket).
# Requires: ActiveDirectory module (RSAT). Detects OS and offers install if missing.
if (-not (Get-Module -ListAvailable -Name ActiveDirectory)) {
    $isClient = (Get-CimInstance Win32_OperatingSystem).ProductType -eq 1
    Write-Warning "ActiveDirectory module (RSAT) not found."
    if ($isClient) { Write-Host "  Install: Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -ForegroundColor Cyan }
    else           { Write-Host "  Install: Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools" -ForegroundColor Cyan }
    $yn = Read-Host "Install RSAT now? [Y/N]"
    if ($yn -match '^[Yy]') {
        if ($isClient) { Add-WindowsCapability -Online -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 }
        else           { Install-WindowsFeature -Name RSAT-AD-PowerShell -IncludeManagementTools }
    } else { throw "RSAT not installed. Re-run after installing." }
}
Import-Module ActiveDirectory
$dcs = (Get-ADDomainController -Filter *).Name
$unhealthy = @()

foreach ($dc in $dcs) {
    try {
        $status = Invoke-Command -ComputerName $dc -ScriptBlock {
            $svc = Get-Service -Name "AATPSensor" -EA SilentlyContinue
            [PSCustomObject]@{ Name = $env:COMPUTERNAME; Status = if($svc){$svc.Status}else{"NOT INSTALLED"} }
        } -ErrorAction Stop
        if ($status.Status -ne "Running") {
            $unhealthy += $status
            Write-Host "UNHEALTHY: $dc. $($status.Status)" -ForegroundColor Red
        } else {
            Write-Host "HEALTHY: $dc" -ForegroundColor Green
        }
    } catch {
        # DC is unreachable - could indicate network issue or DC is offline
        $unhealthy += [PSCustomObject]@{ Name = $dc; Status = "UNREACHABLE" }
        Write-Host "ERROR: $dc. Cannot connect" -ForegroundColor Yellow
    }
}

if ($unhealthy.Count -gt 0) {
    Write-Host "`nACTION REQUIRED: $($unhealthy.Count) unhealthy sensor(s) found" -ForegroundColor Red
    $unhealthy | Format-Table -AutoSize
    # TODO: Send alert to SOC via email/Teams webhook/ITSM ticket
}

Monthly โ€” Generate Configuration Report

# PS 5.1 or PS 7.4+ required. On PS 7.4+: Import-Module -Name GroupPolicy -SkipEditionCheck
# WHAT: Generate a monthly MDI configuration audit report using the module
# WHY:  Configurations drift over time as GPOs change and AD is modified. A monthly report
#       provides a record of audit policy compliance and flags any missing configurations.
#       Schedule this as a monthly scheduled task on a management server.
Import-Module DefenderForIdentity
$reportPath = "$env:USERPROFILE\Documents\MDI-Reports\MDI-Config-$(Get-Date -Format 'yyyy-MM')"
New-Item -Path (Split-Path $reportPath) -ItemType Directory -Force | Out-Null
New-MDIConfigurationReport -Path $reportPath
Write-Host "Monthly report: $reportPath.html" -ForegroundColor Cyan

Summary

What You Accomplished

  • Reviewed MDI architecture, sensor v2.x vs v3.x selection, and all supported server types
  • Verified prerequisites across domain controllers, AD FS, AD CS, and Entra Connect servers
  • Configured proxy settings and optionally set up a forward proxy for isolated servers
  • Created a gMSA for secure, password-free sensor operations (v2.x deployments)
  • Created the MDI instance and securely stored the sensor access key
  • Installed sensors using both interactive and silent methods on DCs and identity servers
  • Granted AD FS database and Entra Connect ADSync database permissions to the gMSA
  • Verified sensor health, connectivity, and data collection
  • Validated entity detection and reviewed identity security assessments
  • Established automated monitoring and maintenance procedures

Next Steps

  • Next Lab: Configure Identity Threat Detection
  • Configure email notifications for identity alerts
  • Remediate all High-impact identity security assessments
  • Integrate MDI alerts with Microsoft Sentinel for centralized SIEM correlation

๐Ÿ“š Documentation Resources

ResourceDescription
What is Microsoft Defender for Identity?Product overview and capabilities
MDI prerequisitesSystem requirements and network configuration
Install the MDI sensorStep-by-step sensor installation guide
Directory service accounts for MDIConfigure gMSA and standard service accounts
Capacity planning for MDISizing guidance and performance considerations
MDI health alertsMonitor and troubleshoot sensor health
Deploy MDI sensor v3.xActivate v3.x sensor on Windows Server 2019+ domain controllers
MDI sensor v2.x prerequisitesRequirements for classic sensor on older DCs and non-DC servers
Configure sensors for AD FS, AD CS, Entra ConnectNon-DC identity server deployment and database permissions
Configure proxy settingsProxy and firewall configuration for sensor connectivity
Identity security assessmentsPosture recommendations and remediation
DefenderForIdentity PowerShell moduleNew-MDIDSA, Test-MDISensorApiConnection, Set-MDIConfiguration, and more
โ† All Labs Next Lab โ†’