Skip to main content

Check OS Version Compliance Before Raising Intune Baselines

The Problem
#

You need to raise the OS version minimum in your Intune compliance policies. Security team wants it, a CIS benchmark calls for it, or you’re finally enforcing what you should have enforced six months ago. Doesn’t matter – the requirement is real.

The risk is equally real. Raise the baseline, and any device below the new minimum gets marked non-compliant. Non-compliant devices get blocked by Conditional Access. Users get locked out.

The Intune portal shows you current compliance status – devices that pass or fail against your existing policies. It doesn’t have a “what if I change the minimum to X” view. There’s no staging mode. Your options are: leave it alone, or change it and deal with what happens next.

So the naive workflow looks like this: raise the baseline, wait for devices to check in, watch the non-compliant count spike, scramble to identify which devices are affected, roll back, and repeat the cycle next quarter. That’s backwards. You should know the landscape before you make the change, not after.

This script shows you that landscape. Run it against your tenant and it reports the OS version distribution across all platforms – how many devices are on each version, what percentage of your fleet they represent. You look at the numbers, decide where to draw the line, and raise the baseline with confidence instead of anxiety.

How It Works
#

One script, no required parameters. Connect, fetch, report. It retrieves every managed device from Intune, groups them by platform and OS version, and shows the distribution.

# See the full picture
.\Get-OSVersionCompliance.ps1

# Target a specific tenant
.\Get-OSVersionCompliance.ps1 -TenantId "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

# Export the breakdown to CSV
.\Get-OSVersionCompliance.ps1 -ExportCsv "C:\Temp\OSVersionReport.csv"

No changes are made anywhere. Read-only. Run it as many times as you want.

Prerequisites
#

  • PowerShell 5.1+ with the Microsoft Graph PowerShell SDK
  • Microsoft.Graph.Authentication (for Connect-MgGraph)
  • Microsoft.Graph.DeviceManagement (for Get-MgDeviceManagementManagedDevice)
  • Permission: DeviceManagementManagedDevices.Read.All (delegated). Your account also needs an Intune RBAC role with managed device read access – having the Graph scope consented isn’t enough on its own in tenants with strict role assignments
  • Devices enrolled and managed in Intune – the script only sees what Intune sees

Implementation
#

What You Get
#

The script outputs one table per platform showing the version distribution:

Android -- 910 device(s)
---------------------------
Version Devices Pct
------- ------- ---
16.0        555 61%
15.0        210 23.1%
14.0         67 7.4%
13.0         65 7.1%
12.0          8 0.9%
11.0          4 0.4%
10.0          1 0.1%

Windows -- 3704 device(s)
---------------------------
Version          Devices Pct
-------          ------- ---
10.0.26200.7979     830  22.4%
10.0.26200.7781    1486  40.1%
10.0.26100.7979     304  8.2%
10.0.26100.7781     522  14.1%
10.0.22631.6783       7  0.2%
10.0.22631.6649      12  0.3%
10.0.22631.6199      20  0.5%
10.0.19045.6937       1  0%
10.0.19045.6809       1  0%
...

Android versions are normalized – Intune reports some devices as "16" and others as "16.0", so the script pads single-number versions with .0 before grouping. Without this, you’d see separate rows for what is clearly the same OS version.

Each row is one OS version with the device count and its percentage of the platform total. Versions are sorted highest first. You read it top to bottom and the picture is clear: where your fleet is clustered, where the long tail is, and how many devices would be affected if you set the baseline at any given version.

Platform Matching
#

The script maps Intune’s OperatingSystem values to four platform groups:

  • WindowsWindows
  • iOS and iPadOSiOS/iPadOS (combined – they share version numbering and you almost never want different baselines for phones and tablets)
  • AndroidAndroid
  • macOSmacOS

Devices with other OS values (Linux, ChromeOS, etc.) are skipped. They don’t have OS version baselines in Intune compliance policies.

Version Normalization and Sorting
#

Before grouping, the script normalizes version strings – single-number versions like "16" get padded to "16.0". This is necessary because Intune reports some Android devices as "16" and others as "16.0" depending on the manufacturer or enrollment path. Without normalization, you’d see separate rows for the same OS version.

Versions are then sorted using PowerShell’s [version] type, which handles dotted notation correctly. This is non-obvious but important – string sorting would put 10.0.9999 above 10.0.22631 because 9 is lexicographically greater than 2. [version] does numeric comparison across each segment, so the sort order matches what you’d expect.

Devices reporting blank or malformed OS versions show up as (unknown) and sort to the bottom.

The CSV Export
#

Add -ExportCsv to write the distribution data to a CSV file:

.\Get-OSVersionCompliance.ps1 -ExportCsv "C:\Temp\OSVersionReport.csv"

The CSV includes Platform, OsVersion, DeviceCount, and PctOfPlatform – one row per version per platform. This is what you hand to your manager, attach to a change request, or import into Excel for a chart. The console output shows you the picture; the CSV gives you the artifact.

Reading the Output
#

Look at the tables per platform and find where you’d draw the line. If you’re considering raising the Windows baseline to 10.0.26100:

  • Everything from 10.0.26100.x and up would pass – that’s the bulk of the fleet
  • Everything below (10.0.22631.x, 10.0.19045.x) needs attention

Add up the Pct values below your target. If they represent 3% of the fleet, you’re in good shape – raise the baseline with a grace period and let those devices catch up. If they represent 30%, you have a fleet hygiene problem to solve first.

As a rough decision framework:

  • 95% or above your target – low-risk. Raise with a grace period.
  • 80–94% – identify the below-target devices, patch or replace them, then raise.
  • Below 80% – don’t raise the baseline yet. Work the fleet hygiene as its own project.

You can find your current compliance policy baselines in the Intune admin center under Devices > Compliance > Policies, select the policy, then Properties. Compare those numbers against what the script shows you.

Security Considerations
#

The script uses DeviceManagementManagedDevices.Read.All – a read-only delegated permission. It doesn’t write, modify, or trigger any action on any device. Safe to run repeatedly during policy planning without any side effects.

That said, DeviceManagementManagedDevices.Read.All exposes device inventory: device names, OS versions, and user UPNs for every managed device in the tenant. If you use -ExportCsv, that data ends up in a file. Treat it accordingly – don’t leave it in a shared folder or attach it to a ticket with broad access.

The permission is delegated, so it runs under your own identity. You need to have been granted that scope in your tenant – either directly or via admin consent.

When to Use This / When Not To
#

Use this before raising OS version baselines in compliance policies – that’s the specific problem it solves. Also useful during quarterly compliance policy reviews when you want to understand fleet readiness, or when a new OS version ships and you want to see adoption across your fleet before tightening requirements.

The right workflow: run the script, look at the distribution, decide where to draw the line, raise the baseline with a grace period. Remember: devices that fall below the new baseline get marked non-compliant, and if your Conditional Access policies require compliant devices, those users lose access until they update.

Don’t use this as a replacement for Intune’s built-in compliance reporting. This script shows OS version distribution – one dimension of compliance. It doesn’t know about your actual compliance policies, grace periods, Conditional Access rules, or any of the other conditions that feed into a device’s real compliance state. The goal is pre-change impact assessment, not a full compliance audit.

Also: the script only sees devices that have checked in and have a reported OS version. Stale enrollments with blank OS versions show up as (unknown). In a healthy tenant this is noise. In a tenant with orphaned enrollments, clean those up first – otherwise your distribution is based on incomplete data.

GitHub
#

Get-OSVersionCompliance.ps1