HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links★ Pro Subscribe free
← Back to Blog
Windows Hello for Business Windows Hello for BusinessWHfBIntuneGroup PolicyPassportForWorkRegistryTroubleshooting

Windows Hello for Business: Why Group Policy Beats Intune, One Setting at a Time

IA
Imran Awan
31 October 2026

Intune reports the Windows Hello for Business profile as applied. The value is in the registry, exactly as Intune sent it. And the laptop ignores it, because a Group Policy setting for the same thing got there first.

This is not a sync failure and not a broken device. It is Microsoft's documented precedence order for Hello policy doing what it says. The catch is that it works one setting at a time. A device can follow Intune for nine Hello settings and Group Policy for the tenth. The registry on the device is where you find out which.

The short version

For Windows Hello for Business, Group Policy beats Intune. Microsoft's order is user Group Policy, then computer Group Policy, then user CSP, then device CSP. When both set the same setting, Microsoft says "the conflicting CSP settings aren't applied until the group policy settings are cleared". MDMWinsOverGP does not change this: it only covers the Policy CSP, and Hello lives in the PassportForWork CSP. To see which source wins, read HKLM\SOFTWARE\Policies\Microsoft\PassportForWork (and the HKCU twin) next to HKLM\SOFTWARE\Microsoft\Policies\PassportForWork\<TenantId>\Device\Policies. Match settings by meaning, not by value name: Group Policy writes Enabled where the CSP writes UsePassportForWork. Fix it in the GPO, never with a registry script.

The problem: Intune says applied, the device follows Group Policy

Here is the shape of it, as I met it on one enterprise laptop. The numbers below are made up, but the pattern is real.

The Intune Hello policy sets a minimum PIN length of 10. Intune reports the policy as applied to the device. A user then sets up Windows Hello and picks a six-digit PIN. Windows accepts it.

The first instinct is that Intune did not deliver. So you check the registry, and Intune's value is there. These two reads show both sources on the same device:

PowerShell - read-only, illustrative output
# What Intune delivered (the PassportForWork CSP location, per tenant) (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Policies\PassportForWork\aaaaaaaa-0b0b-1c1c-2d2d-333333333333\Device\Policies\PINComplexity').MinimumPINLength 10 # What Group Policy wrote (the classic Policies location) (Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity').MinimumPINLength 6

Illustrative. The tenant ID is a Microsoft-style placeholder and the values are invented. On the real laptop the two values were different numbers, and the device enforced the Group Policy one.

Both reads are true. Intune delivered its value. Group Policy delivered a different one. Windows used the Group Policy value. Good looks like the second read failing because the key does not exist. Bad looks like this: two different values for one setting.

Two things make this hard to spot:

Why it happens: Hello has its own precedence order

Windows Hello for Business can be configured two ways. Microsoft's Configure Windows Hello for Business page lists them. A Configuration Service Provider (CSP) is what Mobile Device Management (MDM) tools like Intune use, and for Hello that is the PassportForWork CSP. Group Policy is the other. When both are present, the same page gives the order in which they are enforced.

The order

Microsoft says: "Windows Hello for Business policy settings are enforced using the following hierarchy". The list, highest first:

1. User - GPO→2. Computer - GPO→3. User - PassportForWork CSP→4. Device - PassportForWork CSP→5. Exchange ActiveSync - DeviceLock CSP

Both Group Policy entries sit above both CSP entries. So Intune can never outrank Group Policy for a Hello setting, whatever scope you assign the Intune policy to.

The same page says what happens when you mix them: "If you mix GPO and CSP policy settings, the conflicting CSP settings aren't applied until the group policy settings are cleared." Note the word conflicting. That matters later.

⚠ Gotcha: user beats computer, on both sides. Microsoft says "User policies take precedence over computer policies. If a user policy is set, the corresponded computer policy is ignored." So a Hello setting in a GPO's User Configuration wins over the same setting in Computer Configuration. If you only check HKLM, you can miss the user policy that is actually in charge. Check HKCU too.

Why MDMWinsOverGP does not help

Most Intune admins know the fix for Group Policy conflicts: set MDMWinsOverGP. It lives in the Policy CSP at ./Device/Vendor/MSFT/Policy/Config/ControlPolicyConflict/MDMWinsOverGP. Set to 1, Microsoft says "The MDM policy is used and the GP policy is blocked." But not for Hello.

The Hello configuration page is direct: "The MDMWinsOverGP policy setting doesn't apply to Windows Hello for Business. MDMWinsOverGP only applies to policies in the Policy CSP, while the Windows Hello for Business policies are in the PassportForWork CSP."

The ControlPolicyConflict CSP page says the same thing from the other side: "MDMWinsOverGP only applies to policies in Policy CSP." It also warns: "don't configure the same settings in both GPO and MDM policies unless the settings are under the control of MDMWinsOverGP."

📋 Note: do not use MDMWinsOverGP as evidence. A device with MDMWinsOverGP set to 1 can still follow Group Policy for every Hello setting. "MDM wins, so Intune controls Hello" is a wrong conclusion. The evidence is in the registry locations below.

Precedence is per setting, not per policy

Microsoft's wording is about conflicting settings, not whole policies. The CSP settings that Group Policy does not touch are not in conflict, so nothing holds them back.

That is exactly what I saw on the laptop. The GPO set one Hello setting: minimum PIN length. Intune set the full Hello profile. The device followed Intune for everything except PIN length, and Group Policy for PIN length.

So the question is never "Group Policy or Intune?" for the whole device. It is "which source wins for this setting?"

"Strictest wins" does not apply here

Microsoft does say "Windows enforces the strictest policy out of the set of governing policies", but only for DeviceLock CSP password settings against PassportForWork CSP PIN settings. It says nothing about Group Policy against the CSP. On the laptop I examined, the Group Policy PIN length was the shorter one, and it still won.

How to verify: read both registry locations side by side

Everything in this section only reads. Nothing is written, deleted or refreshed.

The locations

Microsoft documents both sides on the configure page, in the table for disabling Hello. These are the paths it gives:

SourceRegistry keyValue for "use Hello"
Group Policy, userHKEY_USERS\<UserSID>\SOFTWARE\Policies\Microsoft\PassportForWorkEnabled
Group Policy, computerHKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\PassportForWorkEnabled
CSP (Intune), userHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Policies\PassportForWork\<Tenant-ID>\UserSid\PoliciesUsePassportForWork
CSP (Intune), deviceHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Policies\PassportForWork\<Tenant-ID>\Device\PoliciesUsePassportForWork

The Group Policy user key is the user's own hive, so for the signed-in user you can read it as HKCU. The tenant ID in the CSP path is your Microsoft Entra tenant ID; Microsoft notes that CSP configuration of Hello requires it. On the devices I examined, settings with sub-nodes, such as PINComplexity, sat in subkeys below these keys. The Group Policy PIN length was in a PINComplexity subkey too, the same name the CSP uses.

Group Policy, computer: HKLM\SOFTWARE\Policies\Microsoft\PassportForWork
Group Policy, user: HKCU\SOFTWARE\Policies\Microsoft\PassportForWork
Intune, device: HKLM\SOFTWARE\Microsoft\Policies\PassportForWork\<TenantId>\Device\Policies
📋 Note: an empty PolicyManager node is normal. Admins used to Policy CSP settings often look under HKLM\SOFTWARE\Microsoft\PolicyManager\current\device first. Hello is not a Policy CSP setting. Microsoft says the Hello policies "are in the PassportForWork CSP". On healthy devices I have examined, there is no PassportForWork key under PolicyManager at all. That is not a delivery failure. It is the wrong place to look.

A read-only script that lines them up

This script reads all four locations and prints one row per setting. For each row it shows the value from each source and a status. It uses only Get-Item, Get-ChildItem and Test-Path, which read and never write.

Run it in the signed-in user's own session. Under another account, the user columns describe that account instead.

Compare-HelloPolicySources.ps1 - read-only, writes nothing
# Lists Windows Hello for Business policy values from Group Policy # and from Intune (PassportForWork CSP) side by side. $gpUserRoot = 'HKCU:\SOFTWARE\Policies\Microsoft\PassportForWork' $gpComputerRoot = 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork' $cspRoot = 'HKLM:\SOFTWARE\Microsoft\Policies\PassportForWork' # The same setting can use a different value name on each side. # Translate Group Policy names to CSP names before comparing. $gpToCsp = @{ 'Enabled' = 'UsePassportForWork' } function Get-HelloValues { param([string]$Root, [hashtable]$Rename = @{}) $values = @{} if (-not (Test-Path -LiteralPath $Root)) { return $values } $top = Get-Item -LiteralPath $Root $keys = @($top) + @(Get-ChildItem -LiteralPath $Root -Recurse) foreach ($key in $keys) { $sub = $key.Name.Substring($top.Name.Length).TrimStart('\') foreach ($name in $key.GetValueNames()) { if ($name -eq '') { continue } if ($sub -ne '') { $label = $sub + '\' + $name } elseif ($Rename.ContainsKey($name)) { $label = $Rename[$name] } else { $label = $name } $values[$label] = $key.GetValue($name) } } return $values } # The tenant key is the GUID-named subkey under the CSP root. $tenantId = $null if (Test-Path -LiteralPath $cspRoot) { $tenantId = Get-ChildItem -LiteralPath $cspRoot | Where-Object { $_.PSChildName -match '^\{?[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}\}?$' } | Select-Object -First 1 -ExpandProperty PSChildName } $userSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value # In Microsoft's precedence order, highest first. $sides = [ordered]@{ 'GP user' = Get-HelloValues -Root $gpUserRoot -Rename $gpToCsp 'GP computer' = Get-HelloValues -Root $gpComputerRoot -Rename $gpToCsp 'Intune user' = @{} 'Intune device' = @{} } if ($tenantId) { $sides['Intune user'] = Get-HelloValues -Root "$cspRoot\$tenantId\$userSid\Policies" $sides['Intune device'] = Get-HelloValues -Root "$cspRoot\$tenantId\Device\Policies" } $gpSides = @('GP user', 'GP computer') $allNames = $sides.Values | ForEach-Object { $_.Keys } | Sort-Object -Unique $rows = foreach ($n in $allNames) { $row = [ordered]@{ Setting = $n } foreach ($s in $sides.Keys) { $row[$s] = $sides[$s][$n] } $setBy = @($sides.Keys | Where-Object { $null -ne $sides[$_][$n] }) $fromGp = @($setBy | Where-Object { $gpSides -contains $_ }) $fromMdm = @($setBy | Where-Object { $gpSides -notcontains $_ }) $unique = @($setBy | ForEach-Object { $sides[$_][$n] } | Sort-Object -Unique) if ($fromGp.Count -gt 0 -and $fromMdm.Count -gt 0) { if ($unique.Count -gt 1) { $row['Status'] = 'CONFLICT - Group Policy wins' } else { $row['Status'] = 'Both set, same value' } } elseif ($fromGp.Count -gt 0) { $row['Status'] = 'Group Policy only' } else { $row['Status'] = 'Intune only' } [pscustomobject]$row } "Tenant ID : $tenantId" "User SID : $userSid" $rows | Format-Table -AutoSize

On the laptop from the problem section, the output looks like this:

Compare-HelloPolicySources.ps1 - output (illustrative)
Tenant ID : aaaaaaaa-0b0b-1c1c-2d2d-333333333333 User SID : S-1-12-1-1111111111-2222222222-3333333333-4444444444 Setting GP user GP computer Intune user Intune device Status ------- ------- ----------- ----------- ------------- ------ DisablePostLogonProvisioning 0 Intune only EnablePinRecovery 1 Intune only ExcludeSecurityDevices\TPM12 1 Intune only PINComplexity\MinimumPINLength 6 10 CONFLICT - Group Policy wins RequireSecurityDevice 1 Intune only UseCloudTrustForOnPremAuth 1 Intune only UsePassportForWork 1 Intune only

Illustrative output. Tenant ID, SID and values are invented. The setting names are the PassportForWork CSP node names from Microsoft's CSP reference.

How to read it:

The script covers the per-tenant settings only. The biometrics settings sit at ./Device/Vendor/MSFT/PassportForWork/Biometrics in the CSP, with no tenant ID in the path, so read those separately if they are in question.

If Tenant ID is empty, no PassportForWork CSP policy has reached this device at all. That is a delivery question, not a precedence one. The existing post on proving the Hello policy on the laptop covers that case.

The trap: the same setting has two names

Look again at Microsoft's table above. The setting that turns Hello on is called Enabled when Group Policy writes it, and UsePassportForWork when the CSP writes it. Same setting, same meaning, different value name. When I decoded the Hello GPO files on one estate, they showed exactly that: Enabled on the Group Policy side, UsePassportForWork on the Intune side.

That breaks the obvious conflict check. A script that lists value names on both sides and reports the names they share will never pair these two. It reports "no conflicts" while the most important Hello setting is contested.

This snippet shows the difference. It uses the Get-HelloValues function from the script above. Imagine a GPO sets Enabled to 0 while Intune sets UsePassportForWork to 1:

PowerShell - name matching vs meaning matching (illustrative)
# Naive: a conflict is a value name that appears on both sides $mdm = Get-HelloValues -Root "$cspRoot\$tenantId\Device\Policies" $gp = Get-HelloValues -Root $gpComputerRoot @($gp.Keys | Where-Object { $mdm.ContainsKey($_) }).Count 0 # Mapped: translate Group Policy names to CSP names first $gp = Get-HelloValues -Root $gpComputerRoot -Rename $gpToCsp $gp.Keys | Where-Object { $mdm.ContainsKey($_) } UsePassportForWork $gp['UsePassportForWork'], $mdm['UsePassportForWork'] 0 1

The naive check finds nothing. The mapped check finds the conflict, and the values show what it means. Group Policy wins, and Microsoft's policy settings page says that if you disable this setting, "the device doesn't provision Windows Hello for Business for any user". Intune says "use Hello". The device does not.

⚠ Gotcha: the map is only as good as what you put in it. Microsoft publishes the Group Policy value name for this one setting, on the configure page. It does not publish a full Group Policy registry name for every Hello setting. On the laptop I examined, the PIN complexity and TPM 1.2 settings used the same names on both sides. Do not assume that holds everywhere. Before you trust a "no conflicts" result, list the raw value names under the Group Policy key and make sure each one is either in your map or matches a CSP node name.

The fix: clear the setting in the GPO that sets it

The device is not broken, so there is nothing to repair on it. The fix is a change to Group Policy, made by whoever owns the GPO. Microsoft's own rule tells you why: "the conflicting CSP settings aren't applied until the group policy settings are cleared". Clear the Group Policy setting and the Intune value that is already on the device can take over.

⚠ Warning: do not delete or write these values with a script. While the GPO still applies, it still sets the value. On the laptop I examined, someone had deleted the Group Policy value by hand. It was back after the next Group Policy refresh, and the "after" evidence taken in that window was worthless. Writing CSP values by hand is no better: Microsoft says "It's not recommended to create Local GPO or registry settings that could conflict with an MDM policy." Report the conflict. Change the source.
  1. Find the GPO that carries the setting. Do not guess from GPO names. The one that matters may have nothing to do with Hello in its name. Find which GPOs applied to the device, then which of them contains the setting. The companion post find which GPO sets a registry value walks through that.
  2. Check Intune holds the value you want. As soon as Group Policy lets go, the device uses whatever Intune sent. Read the Intune column in the script output and confirm it is right before you change anything.
  3. Set that one setting to Not Configured. Use the Group Policy path from the table below. Change only the conflicting setting.
  4. Leave the GPO linked and applying. If the GPO carries other settings, it must keep applying for those. Do not deny it or unlink it to get rid of one Hello value. Setting the one value to Not Configured inside a GPO that still applies is the smallest change that works.
  5. Check every Hello setting in that GPO, not just the one you noticed. The script's CONFLICT and Both set rows are your list. Plan each one, so a future change in Intune is not silently overruled.

These are the paths for the two settings in this post. Both come from Microsoft's Windows Hello for Business policy settings page:

SettingGroup Policy pathCSP node (Intune)
Minimum PIN lengthComputer Configuration › Administrative Templates › System › PIN Complexity./Device/Vendor/MSFT/PassportForWork/{TenantId}/Policies/PINComplexity/MinimumPINLength, and the same under ./User/
Use Windows Hello for BusinessComputer Configuration › Administrative Templates › Windows Components › Windows Hello for Business, and the same under User Configuration./Device/Vendor/MSFT/PassportForWork/{TenantId}/Policies/UsePassportForWork

PIN complexity is not in the Windows Hello for Business folder. It has its own folder under System. This simulated view shows the change for the PIN length:

Computer Configuration › Administrative Templates › System › PIN Complexity › Minimum PIN length
Before: Enabled, with a value lower than the Intune policy
After: Not Configured
✅ Tip: plan the whole move, not one setting. If the goal is to move Hello off Group Policy entirely, record every Hello value each GPO sets, make sure Intune sets each one as you want, then clear the GPO side. The companion post move Hello policy from Group Policy to Intune covers that plan.

Proof it worked: the Group Policy column is empty

The GPO change reaches the device at its next Group Policy refresh. To test on one device without waiting, refresh Group Policy. Microsoft's gpupdate reference says /force "Reapplies all policy settings. By default, only policy settings that have changed are applied."

PowerShell - after the GPO change (illustrative)
# Reapply Group Policy on this one test device gpupdate /force # The Group Policy PIN complexity key should now be gone Test-Path 'HKLM:\SOFTWARE\Policies\Microsoft\PassportForWork\PINComplexity' False # And the side-by-side view should show Intune only for that row .\Compare-HelloPolicySources.ps1 Setting GP user GP computer Intune user Intune device Status ------- ------- ----------- ----------- ------------- ------ ... PINComplexity\MinimumPINLength 10 Intune only ...

Illustrative. gpupdate /force refreshes policy but changes no policy itself; the GPO change is what removes the value.

Check three things, in this order:

  1. The Group Policy value is gone. Test-Path returns False for the key, or the value is absent from it. If the value is still there, the GPO change has not reached the device, or a different GPO also sets it. Go back to finding the source. Do not delete it by hand.
  2. The script shows Intune only for that setting. No row should say CONFLICT. If one still does, it is a different setting, and it needs the same treatment.
  3. The behaviour matches Intune. For PIN length, Microsoft's policy settings page says: "If you configure this policy setting, the PIN length must be greater than or equal to this number." A new PIN shorter than the Intune value should now be refused.

What bad looks like: the Group Policy value comes back some time after someone deleted it by hand. In the case I worked, that looked like a leftover value at first. It was not. A GPO that was still applying wrote it again at the next refresh. Fix the GPO, and there is nothing left to write it back.

Keep checking after the fix. Microsoft's advice is to "Avoid mixing GPO and CSP policy settings for Windows Hello for Business, as it can lead to unexpected results." Run the script on a few devices after any GPO change that touches Hello or PIN Complexity.

References

Related reading on EndpointWeekly

The pattern in this post was observed read-only on one enterprise laptop. All values, IDs and output blocks are illustrative. Microsoft facts were checked against the pages above on 31 October 2026.

Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows Hello for Business
Intune Says the Hello Policy Applied. Here Is How to Prove It on…
Windows Hello for Business does not write to PolicyManager like other CSP policies, so…
Windows Hello for Business
NgcSet Says YES and Windows Hello Still Does Not Work: Triaging…
Windows Hello health lives on eight separate surfaces, and dsregcmd shows you one of…
Windows Hello for Business
Event ID 360: Every Prerequisite That Blocks Windows Hello for…
Event 360 in User Device Registration/Admin means WHfB provisioning will not launch.…