TL;DR
- The Intune portal shows now. It doesn't keep history, so you can't answer "are we healthier than last month?"
- Once a week, export managed devices and compliance policies to a dated CSV folder with read-only Graph scopes, then compare against last week.
- Track five numbers: total devices, noncompliant count/%, stale sync, unencrypted Windows devices, and compliance policy changes.
- Keep the CSVs private (they contain UPNs and device IDs). Use the trend as evidence before you move Conditional Access from report-only to enforce. Free checklist for that step: CA Rollout Checklist.
"Are we healthier than last month?" is hard to answer from the Intune portal. Portal views only show the current state. They don't keep versions, they don't diff, and nobody remembers what the noncompliant count was three Mondays ago.
The fix is boring: once a week, export device and compliance state to a dated CSV, read-only, and compare. Here's the pattern we use.
What permissions do you need to export Intune devices with Graph?
A snapshot job should never be able to change anything. Set it up so it can't.
| Choice | Starter setting |
|---|---|
| Entra role for the person running it | Intune Reader, or Global Reader if that's enough in your tenant. Not Global Admin for a weekly export |
| Graph scope: devices | DeviceManagementManagedDevices.Read.All |
| Graph scope: compliance policies | DeviceManagementConfiguration.Read.All |
| Where it runs | A dedicated admin workstation or hardened jump box, not a shared PC |
| Auth | Interactive delegated sign-in to start. Only automate later with app permissions + a certificate once you've thought it through |
If Connect-MgGraph fails with insufficient privileges, stop and get consent the proper way. Don't "fix" it by borrowing a more powerful session.
How do you export Intune managed devices to CSV with PowerShell?
One-time setup on the admin workstation:
Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
Install-Module Microsoft.Graph.DeviceManagement -Scope CurrentUser
(If your org blocks PSGallery, use your internal module distribution.)
Each Monday:
$week = Get-Date -Format 'yyyy-MM-dd'
$out = ".\snapshots\$week"
New-Item -ItemType Directory -Path $out -Force | Out-Null
Connect-MgGraph -Scopes 'DeviceManagementManagedDevices.Read.All','DeviceManagementConfiguration.Read.All'
# Managed devices: a small, useful property set (read-only GET)
Get-MgDeviceManagementManagedDevice -All -Property `
'deviceName','operatingSystem','osVersion','complianceState','lastSyncDateTime',`
'enrolledDateTime','userPrincipalName','isEncrypted','azureADDeviceId','id' |
Select-Object DeviceName, OperatingSystem, OsVersion, ComplianceState,
LastSyncDateTime, EnrolledDateTime, UserPrincipalName,
IsEncrypted, AzureADDeviceId, Id |
Export-Csv "$out\intune-devices.csv" -NoTypeInformation -Encoding UTF8
Testing on a big tenant? Use -Top 50 instead of -All to pull a pilot-sized sample first.
How do you export Intune compliance policies?
The device export above covers the weekly snapshot. A second file with your compliance policy list (names, platform, last modified) is what tells you "someone edited a live policy on Thursday." The device CSV alone won't. This post doesn't include the policy-export script; it's included in the Intune & M365 Admin Starter Pack (read-only compliance policy summary). Save its output in the same dated folder.
You end up with:
snapshots/
2026-09-28/intune-devices.csv
2026-09-28/compliance-policies.csv
2026-10-05/intune-devices.csv
2026-10-05/compliance-policies.csv
What should you track in an Intune compliance report each week?
Don't build a dashboard. Track five numbers in a ticket or wiki table:
| Metric | Why it matters |
|---|---|
| Total managed devices | A sudden drop means an enrollment or licensing problem. A sudden jump means someone enrolled personal devices |
| Noncompliant count (and %) | The headline trend. It should fall as pilots mature |
Stale sync (LastSyncDateTime > ~7 days) |
Usually powered-off laptops or broken enrollment, not compliance logic (sync triage) |
IsEncrypted false on Windows rows |
Cross-check against a BitLocker requirement (why encrypting devices show noncompliant). Treat odd/null values on non-Windows rows carefully |
| Compliance policy count / last-modified changes | Unannounced policy edits are the #1 cause of "nothing changed but everything broke" |
How do you compare two weeks of Intune snapshots?
$prev = Import-Csv .\snapshots\2026-09-28\intune-devices.csv
$curr = Import-Csv .\snapshots\2026-10-05\intune-devices.csv
'Last week:'; $prev | Group-Object ComplianceState | Select-Object Name, Count
'This week:'; $curr | Group-Object ComplianceState | Select-Object Name, Count
# Devices that went from compliant to anything else
$prevState = @{}; $prev | ForEach-Object { $prevState[$_.Id] = $_.ComplianceState }
$curr | Where-Object { $prevState[$_.Id] -eq 'compliant' -and $_.ComplianceState -ne 'compliant' } |
Select-Object DeviceName, ComplianceState, LastSyncDateTime | Format-Table -AutoSize
# Stale sync this week
$cutoff = (Get-Date).AddDays(-7)
$curr | Where-Object { $_.LastSyncDateTime -and [datetime]$_.LastSyncDateTime -lt $cutoff } |
Measure-Object | Select-Object Count
The "went from compliant to noncompliant" list is the one worth 5 minutes of human attention. Everything else is trend.
The 30-minute weekly ritual
- Run the device export and save it under
yyyy-mm-dd/ - If you use the Starter Pack, run its compliance policy summary script (not included in this post) and save the output in the same folder
- Write the five numbers down next to last week's
- Spot-check 1–2 odd devices on the endpoint itself (
dsregcmd /status, encryption status) - Only open a ticket if the trend gets worse, or if Conditional Access report-only "would block" numbers spike
That's it. After a month you'll have real evidence for "are we ready to move CA from report-only to enforce?" instead of a gut feeling.
Where should you store Intune export CSVs?
These files contain device names, user principal names, and tenant-linked IDs. Treat them as internal data:
- ❌ Public Teams/Slack channels with guests, Discord servers, community forums
- ❌ Pasted into public AI chat tools or GitHub issues
- ❌ Attached to vendor tickets without trimming them to the rows the vendor needs
- ❌ Product reviews or blog screenshots (redact names/UPNs/IDs first)
- ✅ An access-controlled share or repo your org approves, with a retention rule (for example, keep 12 weeks)
If you need help on a forum, share the counts or a redacted row, never the file.
Common errors with Get-MgDeviceManagementManagedDevice
| Symptom | Likely cause |
|---|---|
Missing module Microsoft.Graph.* |
Installed under a different PowerShell edition/host than the one running the script |
| Consent prompt loop | Admin consent is required once per tenant |
| Empty device list | Wrong tenant (check Get-MgContext) or a scope that's too weak |
| Graph 403 | Your role doesn't cover Intune read. Assign Intune Reader or another appropriate role |
Execution policy blocks .ps1
|
Use a process-scoped bypass or signed scripts per IT policy. Don't loosen machine policy casually |
FAQ
Can I export Intune devices to CSV without PowerShell?
Yes. The device list in the Intune admin center has an Export button. PowerShell is worth it when you want the same columns every week, dated folders, and a diff.
Does Get-MgDeviceManagementManagedDevice change anything?
No. It's a read (GET) call, and with only .Read.All scopes the session can't write anyway.
Which Graph permission do I need to read Intune devices?
DeviceManagementManagedDevices.Read.All for devices and DeviceManagementConfiguration.Read.All for compliance policies.
Why is IsEncrypted blank or false on some rows?
Check the OS first. Values on non-Windows platforms aren't comparable to BitLocker. On Windows, confirm on the device with Get-BitLockerVolume before you trust the column.
Related reading
- Conditional Access report-only → enforce without lockouts
- BitLocker still encrypting? Why Intune marks devices noncompliant
- Company Portal can't connect / device not syncing: 10-minute triage
Free checklist: use your snapshots for the CA go/no-go
These snapshots are the evidence. The free Conditional Access Rollout Checklist is the process that uses them: inventory, report-only, What If, the exit bar, waves, and rollback triggers.
Want this ready-made? The Intune & M365 Admin Starter Pack includes the full inventory-snapshot module, plus enrollment hygiene, baseline compliance, M365 admin hygiene, and 7 break/fix cards. It comes with three read-only PowerShell scripts: a local enrollment snapshot (no Graph needed), a Graph managed-device snapshot, and a compliance policy summary. The scripts only read; they take no device actions and make no policy changes: Intune & M365 Admin Starter Pack.
Admin Pack Studio. Not affiliated with Microsoft. Operational guidance for admins authorized to manage their tenant. Pilot first.
Top comments (0)