The 30-minute Monday habit: weekly read-only Intune snapshots
"Are we healthier than last month?" is a hard question to answer from the Intune portal. Portal views show now. They don't version-control, they don't diff, and nobody remembers what the noncompliant count was three Mondays ago.
The fix is boring: export device and compliance state to a dated CSV once a week, read-only, and compare. Here's the pattern we use.
Related reading:
- Conditional Access without the Monday lockout (report-only → enforce)
- BitLocker still encrypting? Why Intune marks you noncompliant
1. Read-only, least privilege, on purpose
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 sufficient 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; automate later with app permissions + certificate only 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.
2. The export (one-time setup, then copy-paste)
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
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
Then export your compliance policy list (names, platform, last modified) into the same folder. That second file is what tells you "someone edited a live policy on Thursday" — the device CSV alone won't.
Testing on a big tenant? Use -Top 50 instead of -All for a pilot-sized sample first.
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
3. What to track week over week
Don't build a dashboard. Track five numbers in a ticket or wiki table:
| Metric | Why it matters |
|---|---|
| Total managed devices | Sudden drops = enrollment or licensing problem; sudden jumps = someone enrolled personal devices |
| Noncompliant count (and %) | The headline trend. Should fall as pilots mature |
Stale sync (LastSyncDateTime > ~7 days) |
Usually powered-off laptops or broken enrollment — not compliance logic |
IsEncrypted false on Windows rows |
Cross-check vs a BitLocker requirement; 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" |
A quick comparison of two weeks:
$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.
4. The ritual (≤30 minutes)
- Run the device export → save under
yyyy-mm-dd/ - Run the compliance policy export
- Write down the five numbers next to last week's
- Spot-check 1–2 weird devices on the endpoint itself (
dsregcmd /status, encryption status) - Open a ticket only if the trend worsens — or if Conditional Access report-only "would block" numbers spike
That's it. After a month you have real evidence for "ready to move CA from report-only to enforce?" instead of a gut feeling.
5. Where NOT to put these CSVs
These files contain device names, user principal names, and tenant-linked IDs. Treat them like 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 to the rows they need
- ❌ Product reviews or blog screenshots (redact names/UPNs/IDs first)
- ✅ An access-controlled share or repo your org approves, with a retention rule (e.g. keep 12 weeks)
If you need help from a forum, share the counts or a redacted row — never the file.
6. Common snags
| 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 required once per tenant |
| Empty device list | Wrong tenant — check Get-MgContext — or scope too weak |
| Graph 403 | Role doesn't cover Intune read; assign Intune Reader or an appropriate role |
Execution policy blocks .ps1
|
Use process-scoped bypass or signed scripts per IT policy — don't weaken machine policy casually |
Want this ready-made?
This post is the short version. The Intune & M365 Admin Starter Pack ($19 during launch week; normally $29) includes the full inventory-snapshot module plus enrollment hygiene, baseline compliance, M365 admin hygiene, and break/fix cards — and three read-only PowerShell scripts: a local enrollment snapshot (no Graph), a Graph managed-device snapshot, and a compliance policy summary. The scripts only read; they take no device actions and make no policy changes.
👉 https://cashflow4375.gumroad.com/l/joonf
Not affiliated with Microsoft. Operational guidance for admins authorized to manage their tenant. Pilot first.
Top comments (0)