Resolves Windows OS build numbers into release names (Windows 10 2004 through Windows 11 25H2) and reports Windows Autopatch / Windows Update for Business ring compliance — feature, quality, and driver deferral — for any Intune-managed Windows endpoint fleet: physical PCs, Cloud PCs, session hosts, kiosks, whatever your org runs.
Replaces manual "what build is this device on, and should it be further along given its ring's deferral policy?" troubleshooting with a repeatable, testable PowerShell module.
Windows Autopatch (and Windows Update for Business generally) manages rollout through deployment rings — Test, First, Fast, Broad by default, often extended with a Zero-Day/expedite ring and a change-sensitive VIP/executive ring — each with its own feature, quality, and driver deferral policy. Two problems show up constantly when managing this at scale:
- Translating a raw
Win32_OperatingSystem.Versionstring into a release name is a manual lookup, every time, for every device. - "Is this device compliant?" isn't one static answer. A device in a 120-day-deferral ring should lag a zero-deferral Test ring — a naive "is it on the latest build" check flags perfectly healthy devices as behind schedule.
This module solves both: release resolution is centralized and versioned, and ring compliance is computed from each ring's actual deferral policy against real release dates — not a hardcoded "latest build" constant that goes stale every time Microsoft ships a new annual update.
Get-WindowsRelease— maps an OS version string (Major.Minor.Build.Revision) to a release name (e.g.10.0.26200.5074→Windows 11 25H2). Pass-AsObject -Edition <Home|Pro|Enterprise|Education>for a full object with servicing branch, edition-aware end-of-servicing date, and support status.Get-RingDefinition— loads deployment ring definitions (feature, quality, and driver deferral days; driver approval method; target rollout %) fromConfig/RingDefinitions.psd1. Defaults match Windows Autopatch's actual out-of-the-box rings (Test / First / Fast / Broad), extended with example ZeroDay and VIP rings — bring your own file via-Pathto match your org's real Autopatch group / update ring setup.Get-IntuneDeviceInventory— live connector using Microsoft Graph (Microsoft.Graph.DeviceManagement/Microsoft.Graph.Groups) that pulls every Intune-managed Windows device and resolves ring assignment from Entra ID group membership (how ring targeting is modeled under the hood), ready to pipe straight intoNew-WindowsUpdateRingReport.New-WindowsUpdateRingReport— resolved release, ring assignment, that ring's current expected minimum release (derived from its feature deferral policy and real release dates), a compliance flag, days behind, and the ring's quality/driver deferral metadata for context.Get-FleetHealthSummary— a Monitor-tab-style rollup: total devices, compliant/non-compliant/unknown counts, and a per-ring breakdown with worst-case days-behind. Deliberately does not invent "devices with error/conflict" numbers — those come from Intune's own deployment telemetry, which this module doesn't have access to. Pair this with the real Monitor tab for deployment-error data; use this for deferral compliance.Get-RingInputSelection— interactive prompt to select devices by Ring Name or Ring ID for ad-hoc reporting.
Each ring in Config/RingDefinitions.psd1 has a FeatureDeferralDays value —
the same knob as Windows Update for Business's
DeferFeatureUpdatesPeriodInDays, visible on Intune's Devices > Windows
updates > Update rings tab. For a ring with N days of deferral, the
module finds the newest shipped release whose GA date is at least N days in
the past — that's the ring's current expected minimum release. A device
is ring-compliant if it's on that release or newer.
Test (0-day deferral) → must be on the newest shipped release
First (0-day deferral) → same bar as Test, quality/driver differ
Fast (0-day deferral) → same bar as Test, quality/driver differ
Broad (0-day deferral) → same bar as Test, quality/driver differ
ZeroDay (2-day deferral) → must be on whatever was newest 2+ days ago
VIP (30-day deferral) → must be on whatever was newest 30+ days ago
Quality and driver deferral days are surfaced per-device-row for context (they're what actually varies most between Test/First/Fast/Broad day to day) — see Roadmap for extending the same deferral-window logic to quality and driver compliance.
Install-Module Microsoft.Graph.DeviceManagement -Scope CurrentUser
Install-Module Microsoft.Graph.Groups -Scope CurrentUserRequires a Graph connection with:
DeviceManagementManagedDevices.Read.AllGroupMember.Read.AllDevice.Read.All
git clone https://github.com/Ramnarendranaidu/windows-update-ring-intelligence.git
Import-Module ./windows-update-ring-intelligence/WindowsUpdateRingIntelligence.psd1Get-WindowsRelease -OSVersion "10.0.26200.5074"
# Windows 11 25H2Get-WindowsRelease -OSVersion "10.0.22631.3593" -Edition Pro -AsObject
# Build : 22631
# Release : Windows 11 23H2
# MajorOS : Windows 11
# ServicingBranch : 23H2
# Edition : Pro
# EndOfServicing : 2025-11-11 00:00:00
# IsSupported : FalseGet-RingDefinition | Format-Table Name, FeatureDeferralDays, QualityDeferralDays, DriverDeferralDays, DriverApprovalMethod, TargetPercentageConnect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All","GroupMember.Read.All","Device.Read.All"
# Map your Autopatch/Update ring names to the Entra ID group each ring's policy targets
$RingMap = @{
"Test" = "11111111-1111-1111-1111-111111111111"
"First" = "22222222-2222-2222-2222-222222222222"
"Fast" = "33333333-3333-3333-3333-333333333333"
"Broad" = "44444444-4444-4444-4444-444444444444"
}
$Devices = Get-IntuneDeviceInventory -RingGroupMap $RingMap
$Report = $Devices | New-WindowsUpdateRingReport
$Report | Where-Object { -not $_.IsRingCompliant } |
Sort-Object DaysBehindRingExpectation -Descending |
Format-Table DeviceName, Ring, ResolvedRelease, RingExpectedMinimumRelease, DaysBehindRingExpectation -AutoSize
$Report | Export-Csv -Path "./ring-noncompliance.csv" -NoTypeInformation$Summary = $Report | Get-FleetHealthSummary
"$($Summary.CompliantDevices)/$($Summary.TotalDevices) devices ring-compliant ($($Summary.CompliancePercentage)%)"
$Summary.RingBreakdown | Format-Table -AutoSize$Selection = Get-RingInputSelection
# Choose input type: 1 = Ring Name, 2 = Ring ID
# Enter ring Name values (comma separated): Fast, BroadCopy Config/RingDefinitions.psd1, rename the rings and adjust the
deferral days/percentages to match your actual Autopatch groups and update
rings (Intune: Tenant administration > Windows Autopatch > Autopatch
groups, and Devices > Windows updates > Update rings / Driver
updates), then point at it:
$Report = $Devices | New-WindowsUpdateRingReport -RingDefinitionsPath "C:\Config\OrgRingDefinitions.psd1"| Build | Release | Servicing branch |
|---|---|---|
| 19041 | Windows 10 2004 | 2004 |
| 19042 | Windows 10 20H2 | 20H2 |
| 19043 | Windows 10 21H1 | 21H1 |
| 19044 | Windows 10 21H2 | 21H2 |
| 19045 | Windows 10 22H2 | 22H2 |
| 22000 | Windows 11 21H2 | 21H2 |
| 22621 | Windows 11 22H2 | 22H2 |
| 22631 | Windows 11 23H2 | 23H2 |
| 26100 | Windows 11 24H2 | 24H2/25H2 (shared branch) |
| 26200 | Windows 11 25H2 | 24H2/25H2 (shared branch) |
25H2 ships as an enablement package on the same servicing branch as 24H2 —
that's why they share cumulative updates each Patch Tuesday. The table (and
each release's GA date, used for ring deferral math) lives in
Private/ReleaseTable.ps1. Update it as new builds ship.
Pester tests live in /Tests and cover release resolution, ring definition
loading, deferral-based compliance, and the fleet health rollup:
Invoke-Pester -Path ./Tests- Extend deferral-window compliance logic to quality updates (needs a device-reported "last quality update installed" date, then the same cutoff-window math as feature updates)
- Driver update compliance (deferral + Automatic/Manual approval state)
- Nerdio Manager REST API connector, for orgs running AVD alongside physical/Cloud PC fleets
- HTML/PowerBI-ready export format
- GitHub Actions CI running Pester on push
MIT — see LICENSE.