In this module
AD3.9 Device Compliance Monitoring
Figure AD3.9 — Compliance monitoring cadence. Weekly checks during the first month after enforcement catch early issues. Monthly checks in steady state catch drift. Quarterly reviews update policies and feed the management report.
Monthly compliance reporting with PowerShell
Build an automated compliance report that runs monthly and gives you the metrics for your management report:
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"
$devices = Get-MgDeviceManagementManagedDevice -All
# Overall compliance rate
$total = $devices.Count
$compliant = ($devices | Where-Object { $_.ComplianceState -eq "compliant" }).Count
$nonCompliant = ($devices | Where-Object { $_.ComplianceState -eq "noncompliant" }).Count
$inGrace = ($devices | Where-Object { $_.ComplianceState -eq "inGracePeriod" }).Count
$unknown = ($devices | Where-Object { $_.ComplianceState -eq "unknown" }).Count
Write-Host "=== COMPLIANCE REPORT ===" -ForegroundColor Cyan
Write-Host "Total devices: $total"
Write-Host "Compliant: $compliant ($([math]::Round($compliant/$total*100,1))%)" -ForegroundColor Green
Write-Host "Non-compliant: $nonCompliant" -ForegroundColor Red
Write-Host "In grace period: $inGrace" -ForegroundColor Yellow
Write-Host "Unknown: $unknown" -ForegroundColor Gray
# Compliance by platform
Write-Host "`n=== BY PLATFORM ===" -ForegroundColor Cyan
$devices | Group-Object OperatingSystem | ForEach-Object {
$platTotal = $_.Count
$platCompliant = ($_.Group | Where-Object { $_.ComplianceState -eq "compliant" }).Count
Write-Host "$($_.Name): $platCompliant/$platTotal ($([math]::Round($platCompliant/$platTotal*100,1))%)"
}
# Stale devices (no sync in 30+ days)
$staleDate = (Get-Date).AddDays(-30)
$stale = $devices | Where-Object { $_.LastSyncDateTime -lt $staleDate }
Write-Host "`n=== STALE DEVICES (30+ days) ===" -ForegroundColor Cyan
Write-Host "Count: $($stale.Count)"
$stale | Select-Object DeviceName, OperatingSystem, LastSyncDateTime, UserPrincipalName |
Format-Table -AutoSize
# Encryption status
$encrypted = ($devices | Where-Object { $_.OperatingSystem -eq "Windows" -and $_.IsEncrypted -eq $true }).Count
$winTotal = ($devices | Where-Object { $_.OperatingSystem -eq "Windows" }).Count
Write-Host "`n=== ENCRYPTION ===" -ForegroundColor Cyan
Write-Host "Windows encrypted: $encrypted/$winTotal ($([math]::Round($encrypted/$winTotal*100,1))%)"Save this script as Get-ComplianceReport.ps1 and run it on the first business day of each month. The output gives you five data points for the quarterly management report: overall compliance rate, compliance by platform, stale device count, encryption coverage, and non-compliant device list.
Catching compliance drift
Devices don't become non-compliant all at once. They drift — one at a time, over weeks. The user defers a Windows Update, and 30 days later the OS version is below your minimum. The user installs a VPN client that disables the firewall, and the device is non-compliant until someone notices. A BitLocker recovery event requires the user to re-enter their recovery key, and until they do, the device shows as unencrypted.
The monthly compliance report catches this drift systematically. Each month, compare the compliance rate to the previous month. A 98% rate dropping to 95% in one month means 6-7 devices fell out of compliance — investigate each one. A 98% rate holding steady means your controls are working and users are maintaining their devices.
Investigating compliance drift — the common causes
When devices fall out of compliance, the cause falls into one of five categories. Knowing the categories speeds investigation:
Windows Update deferral. The most common cause of OS version compliance failures. Users defer updates because they don't want to restart. After the deferral period expires (set in your update ring), Windows installs the update on the next restart — but the user may defer the restart too. Check your update ring configuration:
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All"
# Check Windows Update ring settings
Get-MgDeviceManagementDeviceConfiguration -Filter "displayName eq 'Windows Update Ring'" |
Select-Object DisplayName, @{N="Settings";E={$_.AdditionalProperties}} | Format-ListIf your update ring allows unlimited deferrals, users can defer indefinitely. Set a deadline: after the deferral period plus the deadline, the update installs automatically regardless of user action. Recommended: quality update deferral 7 days + deadline 5 days = maximum 12 days before forced install. Feature update deferral 30 days + deadline 14 days = maximum 44 days.
BitLocker recovery events. When a device triggers BitLocker recovery (firmware update, BIOS change, hardware modification), the user must enter the recovery key. Until they do, the drive appears "locked" and the compliance check may fail. Check for recovery events:
# Check if BitLocker recovery keys were recently used
Get-MgInformationProtectionBitlockerRecoveryKey -All |
Where-Object { $_.CreatedDateTime -gt (Get-Date).AddDays(-30) } |
Select-Object DeviceId, CreatedDateTime | Format-TableIf you see recent recovery key activity, those devices experienced a recovery event. The users need to complete the recovery process before compliance is restored.
Third-party software conflicts. Certain applications disable Windows Firewall or Defender real-time protection during installation — some VPN clients, some development tools, and some legacy applications. These changes trigger non-compliance immediately. The fix is either configuring the application to coexist with the security controls or adding an Intune remediation script that re-enables the control after installation.
Stale enrollment. Devices that haven't checked into Intune for 30+ days aren't receiving compliance evaluations. They show as "Unknown" rather than compliant or non-compliant — which means CA003 may treat them as non-compliant and block access. Force a sync from the Intune portal or contact the user to connect the device.
New devices without compliance policy assignment. When a new device enrolls, it must be in a group targeted by your compliance policy. If the device lands in a group that isn't targeted — or if your compliance policy targets specific groups rather than "All devices" — the new device has no policy and shows "Not evaluated." Verify your compliance policy assignment targets the right groups, or use "All devices" to ensure no device is missed.
For proactive monitoring, set up a scheduled report in Intune that emails you weekly with the non-compliant device list. Navigate to intune.microsoft.com → Reports → Device compliance → Noncompliant devices → Schedule. Configure a weekly email to your admin mailbox with the list of non-compliant devices. This catches drift between your monthly manual checks.
Setting up compliance alerts in Intune
Beyond scheduled reports, configure real-time alerts for compliance state changes. Navigate to intune.microsoft.com → Tenant administration → Diagnostics and feedback → Monitoring → Alerts.
While Intune's native alerting is limited compared to Sentinel, you can create basic notifications for significant compliance events. The most useful approach for an E3 environment is to create a Logic App or Power Automate flow that queries the Intune Graph API daily and sends you a summary email.
A simpler approach: add a 5-minute compliance check to your Monday morning review routine. Navigate to intune.microsoft.com → Devices → Compliance → Monitor → Device compliance status. The overview shows the current compliance rate across all platforms with a trend chart. A downward trend means devices are falling out of compliance faster than they're being remediated — investigate.
For specific device compliance detail, use Graph Explorer or PowerShell:
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All"
# Devices that became non-compliant in the last 7 days
$devices = Get-MgDeviceManagementManagedDevice -All |
Where-Object { $_.ComplianceState -eq "noncompliant" }
foreach ($device in $devices) {
# Get compliance policy state for each non-compliant device
$states = Get-MgDeviceManagementManagedDeviceCompliancePolicyState -ManagedDeviceId $device.Id
foreach ($state in $states) {
if ($state.State -ne "compliant") {
Write-Host "$($device.DeviceName) | $($device.UserPrincipalName) | $($state.DisplayName) | $($state.State)" -ForegroundColor Red
}
}
}This shows not just WHICH devices are non-compliant, but WHICH specific compliance check they're failing. "DESKTOP-NE042 | m.thompson@northgateeng.com | Windows Security Compliance | noncompliant" followed by the failing setting tells you exactly what to remediate without navigating to each device in the portal.
New device onboarding compliance verification
When a new device is deployed, verify it reaches compliance within 48 hours of enrollment. Add this check to your device deployment checklist:
- Enroll the device in Intune (via Autopilot or manual enrollment)
- Wait 2 hours for compliance policy evaluation
- Check compliance status: intune.microsoft.com → Devices → search by device name → Device compliance
- If any checks fail, remediate before handing the device to the user
- Document the compliance state at handover
New devices should be compliant from day one. If a new device fails compliance, the deployment process needs adjustment — the deployment image may be missing BitLocker configuration, the OS may be out of date, or the Intune profiles may not be deploying correctly during enrollment.
Build a PowerShell check that runs against recently enrolled devices to catch compliance gaps immediately:
# Devices enrolled in the last 14 days that aren't yet compliant
$twoWeeksAgo = (Get-Date).AddDays(-14)
Get-MgDeviceManagementManagedDevice -All |
Where-Object { $_.EnrolledDateTime -gt $twoWeeksAgo -and $_.ComplianceState -ne "compliant" } |
Select-Object DeviceName, OperatingSystem, ComplianceState, EnrolledDateTime,
UserPrincipalName |
Format-Table -AutoSizeRun this weekly. Any recently enrolled device that hasn't reached compliance within 14 days has a deployment issue that needs investigation — not a user remediation issue. The deployment process should produce compliant devices automatically. If it consistently doesn't, fix the deployment before adding more devices.
Your monthly compliance report shows the overall rate dropped from 97% to 93% this month. Investigation reveals that 8 devices fell out of compliance because a Windows quality update released 3 weeks ago caused a compatibility issue with a specific printer driver, and those 8 users deferred the update. Now the deferral period has expired, the devices are non-compliant, and the users are locked out of M365. What do you do?
Option A: Temporarily extend the grace period for the OS version compliance check from 7 days to 30 days for all users.
Option B: Contact the 8 users, help them install the update (which includes the printer driver fix in a subsequent patch), and trigger Intune sync to restore compliance. Investigate whether the initial update deferral should have been caught earlier.
Option C: Remove the OS version compliance check until the printer driver issue is fully resolved.
The correct answer is Option B. The issue is specific to 8 devices with a known cause. Extending the grace period or removing the OS check affects all devices unnecessarily. Contact the 8 users, install the updates (which likely include the fix for the printer driver issue), and restore compliance within the day. For future prevention: if Windows Update quality updates are causing compatibility issues, test updates on a pilot group before broad deployment via your Intune update ring (deferral of 7 days gives you time to catch these issues before they reach everyone).
Try it: Run the compliance monitoring report
Copy the PowerShell script from this subsection into a file called Get-ComplianceReport.ps1. Run it against your Intune tenant. Record the five data points: overall compliance rate, compliance by platform, stale device count, encryption coverage, and non-compliant device list.
Compare these numbers against your baseline from AD3.2. The difference shows the improvement your compliance deployment achieved: devices that were unencrypted are now encrypted, devices with disabled firewalls now have them enabled, and OS versions are current.
Set a calendar reminder to run this report on the first business day of each month. After three months, you have a trend line for the quarterly management report: "Device compliance rate maintained at 96-98% over the quarter, with zero compliance-related security incidents."
You're reading the free modules of M365 Security: From Admin to Defender
The full course continues with advanced topics, production detection rules, worked investigation scenarios, and deployable artifacts.