Open your Intune Settings Catalog report right now. Filter to the LAPS profile. Every device shows Succeeded. Feels good, right? Now go check one of those devices in the Entra portal and look at the actual password expiration timestamp on the local Administrator account. There is a real chance it hasn't moved in weeks — maybe months. "Policy applied" and "password rotating" are not the same thing, and the gap between them is exactly where a departed contractor's old support-ticket password, or a screenshot buried in a stale runbook, quietly stays valid forever.
This post explains why that gap exists — specifically the conflict between the modern Intune/CSP delivery path for Windows LAPS and a leftover on-prem Group Policy configuration — how to manually spot-check a single device, and how to build a PowerShell audit that checks your entire fleet against Microsoft Graph and tells you, in plain colour-coded terms, which devices are actually rotating and which ones only look like they are.
Get-LAPSRotationCompliance.ps1 is free and open source. Download it from the Imran76Awan/Daily-Tasks repository on GitHub — no sign-in required.
The problem — "configured" and "rotating" are two different states
Windows LAPS is the built-in, first-party successor to the old Microsoft LAPS download. Since Windows 11 and Windows Server 2019 (with later cumulative updates) it ships in-box, no separate MSI, no external CSE, no separate ADMX to hunt down on TechNet. It manages the password of a local account — usually the built-in Administrator, or a designated managed local account — and rotates that password on a schedule you define, backing the current value up to either Microsoft Entra ID (cloud-native) or on-prem Active Directory (hybrid).
That is the theory, and when it works it is genuinely excellent security hygiene: every device gets a unique, unpredictable local admin password, and that password changes automatically, which closes off an entire class of lateral-movement attacks where a single leaked local admin password gets reused across an entire estate.
Here is the problem. "The LAPS policy applied successfully" is a statement about policy delivery. It tells you the Settings Catalog profile reached the device and the CSP accepted the values. It says nothing about whether the underlying rotation actually executed. A device can sit in the following state for months without a single alert firing anywhere in the Intune or Entra portals:
- Settings Catalog LAPS profile assignment: Succeeded
- Device compliance: Compliant
- Local admin password: identical to what it was three months ago
This happens for one of three structural reasons, all of which we cover in detail below: a conflict between the modern Intune/CSP LAPS path and a leftover on-prem Group Policy LAPS configuration, a device that has quietly stopped checking in, or a policy application that silently failed without tripping any compliance flag. None of these show up as a red banner anywhere. The device just sits there, technically "managed," with a stale local admin password.
Why it happens — CSP vs. GPO, and the conflict nobody notices
Windows LAPS can be deployed to a device in two structurally different ways, and this is the part that trips up even experienced admins because both paths look completely valid in isolation.
Path 1 — Intune Settings Catalog / CSP (the modern, cloud-native path)
The recommended path for Intune-managed and hybrid Entra-joined devices is the Settings Catalog, which surfaces the Windows LAPS CSP under the policy area named simply LAPS (CSP name: Policy/LocalAdminPassword, with related nodes for rotation frequency, password complexity, password age, and account name). When you assign this policy, the device's LAPS client reads the CSP values through the MDM channel, rotates the password on schedule, and backs the resulting credential up to Microsoft Entra ID — or to on-prem Active Directory if the device is hybrid Azure AD joined and you've configured the backup directory accordingly.
Path 2 — Group Policy (the on-premises path)
The second path is Group Policy, under Computer Configuration › Policies › Administrative Templates › System › LAPS. This works because the Windows LAPS ADMX template ships in-box on Windows 11 22H2 and Server 2022 onward — you do not need to download or install anything extra, it is simply part of the built-in Group Policy Central Store templates. This is the correct on-prem path for domain-joined devices that are not Intune-managed, or for organisations mid-migration who still manage most policy through Group Policy.
AdmPwd.dll. If you still have that legacy CSE-based GPO lingering in an OU somewhere, it uses entirely different registry keys and a different attribute schema (ms-Mcs-AdmPwd rather than msLAPS-Password), and it is a separate migration project of its own. This post is about the modern in-box LAPS GPO and CSP paths conflicting with each other — not the legacy tool.Both paths are individually well-documented and individually correct. The trouble starts when a device receives both at the same time — which happens more often than you'd expect, usually because a device was originally managed purely through Group Policy, then later Intune-enrolled as part of a hybrid or co-management rollout, and nobody went back to clean up the original GPO link.
The second and third reasons rotation quietly stalls are simpler but just as invisible in the portal:
- Devices that stop checking in. A laptop that goes on extended leave with its user, a device that's been re-imaged and never re-enrolled properly, or a VM that was decommissioned but never removed from Entra ID — none of these will ever receive a rotation command, because there's no channel to deliver it. The device's last recorded password expiration timestamp simply sits there, aging, with nothing in the portal flagging it as a problem. It looks identical to a device with a genuine policy conflict unless you specifically cross-reference the device's last check-in time.
- Silent policy application failure. Occasionally the CSP accepts the policy push and reports success, but the underlying LAPS client on the device fails to actually rotate — a corrupted local security policy cache, a permissions issue on the local SAM database, or a timing race during a reboot. The Settings Catalog report still shows Succeeded because policy delivery genuinely did succeed; only the execution failed.
How to verify — spot-checking a single device
Before building any kind of fleet-wide audit, it's worth knowing how to manually check one device, both for the cloud-native (Entra ID) view and the on-prem AD attribute for hybrid devices.
Entra ID portal — Local Administrator Password Recovery (LAPS) blade
Selecting a specific device and opening its LAPS blade shows you the account name being managed, the password's expiration timestamp, and (if you have the right role) a button to reveal the current password. The field that matters for a compliance audit is the expiration timestamp — if it's in the past, the account is overdue for rotation right now.
On-prem Active Directory — msLAPS-PasswordExpirationTime for hybrid devices
For hybrid Azure AD joined devices backing LAPS credentials up to on-prem Active Directory rather than Entra ID, the equivalent attribute lives directly on the computer object. You can inspect it with ADSI Edit, or faster, with PowerShell:
Get-ADComputer -Identity "DESKTOP-████████" -Properties msLAPS-PasswordExpirationTime | Select-Object Name, @{Name='PasswordExpires';Expression={ [datetime]::FromFileTime([int64]$_.'msLAPS-PasswordExpirationTime') }}
The attribute stores a Windows FILETIME value, so it needs converting with [datetime]::FromFileTime() before it's human-readable — a detail that trips people up the first time they query it directly.
Get-ADComputer query per hostname, works for spot-checking a single reported problem device — it does not work for confidently answering "how many of our 3,000 managed endpoints have actually rotated in the last 30 days." That's the gap the audit script in the next section closes.The fix — auditing rotation compliance with PowerShell
The script below, Get-LAPSRotationCompliance.ps1, uses the Microsoft Graph PowerShell SDK to enumerate every Windows device in the tenant, pull its Windows LAPS credential record, and classify it GREEN, AMBER, or RED based on how current its rotation actually is — then cross-references Intune's own device check-in timestamp to tell you whether a flagged device is a genuine policy conflict or simply offline.
Core logic — the Graph query and date comparison
# Connect with the scopes needed to read device + LAPS credential + Intune check-in data Connect-MgGraph -Scopes "Device.Read.All", "DeviceLocalCredential.Read.All", "DeviceManagementManagedDevices.Read.All" -NoWelcome $now = Get-Date $AmberThresholdDays = 45 # Get-MgDirectoryDeviceLocalCredentialInfo returns a deviceLocalCredentialInfo object with a # Credentials array. Each credential has PasswordExpirationDateTime and BackupDateTime. $credInfo = Get-MgDirectoryDeviceLocalCredentialInfo -DeviceLocalCredentialInfoId $device.DeviceId $latestCred = $credInfo.Credentials | Sort-Object BackupDateTime -Descending | Select-Object -First 1 $expiresOn = $latestCred.PasswordExpirationDateTime $lastRotated = $latestCred.BackupDateTime if ($expiresOn -lt $now) { $status = 'RED' # rotation has stalled - password is already expired } elseif (($now - $lastRotated).TotalDays -gt $AmberThresholdDays) { $status = 'AMBER' # approaching staleness / possible check-in problem } else { $status = 'GREEN' } # Cross-check Intune's own LastSyncDateTime to tell "policy conflict" apart from "offline" $managed = Get-MgDeviceManagementManagedDevice -Filter "azureADDeviceId eq '$($device.DeviceId)'" if (($now - $managed.LastSyncDateTime).TotalDays -le 7) { $rootCause = 'Likely policy conflict (GPO vs CSP) - device checks in fine' } else { $rootCause = 'Device offline - has not checked in recently' }
The full script (embedded below and downloadable from GitHub above) wraps this logic in a loop over every Windows device in the tenant, adds a colour-coded console report, and an optional CSV export for a compliance record you can attach to an audit.
A realistic run against a pilot tenant
Here's what a first run typically surfaces — a mix of healthy devices, one approaching staleness, and — the interesting part — two devices that are checking in to Intune perfectly fine but whose LAPS password hasn't rotated in weeks, plus one device that's simply gone dark:
=== Connecting to Microsoft Graph === Connected as admin@contoso.onmicrosoft.com | Tenant: ████████-████-████-████-████████████ === Enumerating devices === Pulling Entra ID device list (Get-MgDevice -All)... Pulling Intune managed device list (Get-MgDeviceManagementManagedDevice -All)... Found 62 Entra ID devices, 58 Intune-managed devices. === Evaluating LAPS rotation compliance === === LAPS rotation compliance report === [FAIL] FIN-LAPTOP-07 Password expired on 2026-06-05 09:12 | Likely policy conflict (GPO vs CSP) - device checks in fine [FAIL] FIN-LAPTOP-11 Password expired on 2026-05-28 14:03 | Likely policy conflict (GPO vs CSP) - device checks in fine [FAIL] SALES-DESKTOP-22 No LAPS record retrievable via Graph | Device offline - has not checked in for 96 days [WARN] OPS-LAPTOP-04 Last rotation was 51 days ago (threshold: 45 days) | Check-in slipping - investigate connectivity [OK] IT-LAPTOP-01 rotated 2026-07-14 06:02:11 [OK] IT-LAPTOP-02 rotated 2026-07-13 22:41:07 [OK] HR-LAPTOP-03 rotated 2026-07-15 05:18:44 [OK] ...54 more devices... all GREEN Summary: 57 GREEN | 1 AMBER | 3 RED (out of 61 devices checked) ACTION NEEDED: 3 device(s) have stalled or missing LAPS rotation. Review RootCause column before remediating.
Note the distinction the RootCause column draws: FIN-LAPTOP-07 and FIN-LAPTOP-11 are checking in to Intune perfectly normally — recent LastSyncDateTime — which rules out "device is unreachable" and points squarely at a policy problem on the device itself. SALES-DESKTOP-22, on the other hand, hasn't synced in 96 days; its stale LAPS record is a symptom of the device being effectively abandoned, not a policy conflict, and the remediation path is completely different.
That side-by-side is the entire problem in one screen. The device has a GPO-delivered configuration under ...\LAPS\Config saying rotate every 30 days and back up to Active Directory, and a CSP-delivered configuration under ...\PolicyManager\current\device\LAPS saying rotate every 90 days and back up to Entra ID. Whichever one the LAPS client treats as authoritative on that specific device silently wins — and the other configuration's intended rotation schedule simply never happens, with nothing logging the conflict.
Remediation steps — covering both deployment paths
Proof it worked — re-running the audit after remediation
After unlinking the conflicting GPO from the two Finance devices and forcing a policy re-sync, give it 24-48 hours for the next scheduled rotation to actually execute, then re-run the exact same script:
=== Connecting to Microsoft Graph === Connected as admin@contoso.onmicrosoft.com | Tenant: ████████-████-████-████-████████████ === Enumerating devices === Pulling Entra ID device list (Get-MgDevice -All)... Pulling Intune managed device list (Get-MgDeviceManagementManagedDevice -All)... Found 62 Entra ID devices, 60 Intune-managed devices. === Evaluating LAPS rotation compliance === === LAPS rotation compliance report === [FAIL] SALES-DESKTOP-22 No LAPS record retrievable via Graph | Device offline - has not checked in for 98 days [OK] FIN-LAPTOP-07 rotated 2026-07-17 03:14:52 [OK] FIN-LAPTOP-11 rotated 2026-07-17 03:16:09 [OK] OPS-LAPTOP-04 rotated 2026-07-16 22:04:31 [OK] IT-LAPTOP-01 rotated 2026-07-14 06:02:11 [OK] IT-LAPTOP-02 rotated 2026-07-13 22:41:07 [OK] ...55 more devices... all GREEN Summary: 60 GREEN | 0 AMBER | 1 RED (out of 61 devices checked)
Both Finance laptops now show a fresh passwordExpirationDateTime generated within hours of the forced re-sync — clear proof the CSP path is now the sole authority on those devices and rotation is genuinely executing again. The Ops laptop that was AMBER also cleared once its check-in cadence recovered. SALES-DESKTOP-22 remains RED, correctly, because it's a device-offline case rather than a policy conflict — that one needs someone to physically locate the machine, not another gpupdate.
I'll audit your fleet's rotation compliance, diagnose GPO/CSP conflicts, and get every device onto a single, working deployment path.