Windows Hello for Business (WHfB) is one of those technologies that looks clean in the Microsoft docs but creates a very specific failure pattern in the real world: a device is Azure AD joined, the user has a valid Primary Refresh Token, Conditional Access is enforcing passwordless — and yet WHfB is still not set up. NgcSet = NO. The user gets a prompt they don't understand, calls the service desk, and an engineer walks them through five screens they'll forget by next week.
This post covers the two-script Intune Proactive Remediation solution I built to detect that gap, repair the parts a script can safely repair, and say plainly when it cannot — automatically, at scale, without touching a healthy device.
NgcSet = NO on a device that looks perfectly healthy is one of the most common WHfB failure patterns. Here is the two-script Intune Proactive Remediation that detects it, repairs the parts a script can safely repair, and reports the Hello key state instead of deleting it — without touching a healthy device.
Why WHfB breaks silently
The WHfB provisioning flow requires three things to line up: the device must be registered, the user must have an active PRT, and the NGC cryptographic key must be provisioned. Any one of these can break independently, and none of them will surface as a clean alert in the Intune console.
The most common failure pattern is NgcSet = NO on an otherwise healthy device — the device is joined, the PRT is present, the TPM is fine, but the NGC key is gone. Deleted by a cleanup operation, corrupted, or never fully provisioned after a re-enrolment. Standard compliance policies won't catch this cleanly.
Run dsregcmd /status on a broken device and you'll see:
AzureAdJoined : YES
DomainJoined : YES
AzureAdPrt : YES
NgcSet : NO <-- WHfB not provisioned
NgcKeyId : <-- empty
That is the gap these scripts look for. Whether a script can close it depends on why the key is missing, see the update note below.
The solution: two scripts, one Intune Remediation
The automation runs as an Intune Proactive Remediation — a detection/remediation pair that Intune runs on a schedule. The detection script evaluates the device and returns an exit code. If non-compliant, Intune automatically runs the remediation script.
| Script | Role | Run context |
|---|---|---|
Detect-WHfB.ps1 | Checks 6 health conditions, exits 0 or 1 | User for the full picture, SYSTEM for the repair package (see deployment) |
Remediate-WHfB.ps1 | Repairs what is safe in 5 steps; the last step only reports | SYSTEM |
What the detection script checks
The script parses dsregcmd /status and evaluates six conditions. Each check outputs a colour-coded result — green for pass, red for fail, yellow for warnings:
- Azure AD / Hybrid Join — device must be AAD or Hybrid Joined
- Primary Refresh Token (PRT) — user must have an active PRT
- NGC key provisioning — NgcSet must be YES with a valid KeyId
- TPM health — present, enabled, ready, TPM 2.0 recommended
- Required services — KeyIso, NgcSvc, NgcCtnrSvc, TokenBroker all running
- WHfB policy — registry must not have Enabled = 0
Exit 0 = compliant (Intune takes no action). Exit 1 = non-compliant (Intune runs the remediation script).
When it runs as SYSTEM, the detection script now skips the PRT and NGC checks and says why, because dsregcmd /status only returns valid values for them in the user's context. When the PRT is missing it also reads the PRT diagnostics and classifies the cause: None, NetworkOrTransport, ServerRejected or HelloKeyNotInEntra. The last line of output is machine readable: WHFB-STATE ctx=... join=... prt=... ngc=... issue=... aadsts=... failures=....
[Screenshot: detection script output with colour-coded PASS/FAIL lines]
What the remediation script does
dsregcmd /cleanupaccounts and triggered UserTask-Roam. That folder is shared by every user on the device, so it removed every enrolled user's Hello credential, and no Microsoft page documents it as a repair. It is gone: step 5 now only reports the Hello key state. The dsregcmd /forcerecovery fallback is gone too. AzureAdPrt and NgcSet are now read in the user's context, because Microsoft says the command “must run in a user context to retrieve a valid status”; read as SYSTEM, healthy devices looked broken. And before any PRT refresh, Remediate-WHfB.ps1 reads the PRT diagnostics: an AADSTS answer such as AADSTS130004 (“The user principal doesn't have the NGC ID key configured”) means Entra ID refused the request, so it stops and exits 1 instead of retrying every schedule. See when the Hello key is missing in Entra and which Hello and PRT fixes are safe to automate. The diagnostics parser has 22 tests, including Microsoft's own sample output. The user-context scheduled-task steps are parse-checked but I have not run them on a live device yet, so pilot first.The remediation script runs as SYSTEM, using one-off scheduled tasks to run user-context operations as the logged-on user where required:
| Step | Action | Always runs? |
|---|---|---|
| 1 | Restart WHfB services (KeyIso, NgcSvc, NgcCtnrSvc, TokenBroker) | Yes |
| 2 | Read the PRT and NGC state in the user's context. If the PRT diagnostics hold an AADSTS error, stop (exit 1). Otherwise, only if the PRT is missing, refresh it with dsregcmd /refreshprt as the logged-on user | Yes |
| 3 | Re-trigger Hybrid AAD Join task | Only if domain-joined but not AAD-joined |
| 4 | Trigger Intune MDM sync (3 methods) | Yes |
| 5 | Report the Hello key state. Changes nothing | Yes (report only) |
Step 5 is report only. If the Hello key is missing, the script logs the state and tells you what a person should do. Microsoft's supported way to remove one user's Hello container is certutil -deletehellocontainer, run by that user and not elevated, and it needs advance preparation: on current Windows 11 it also clears passkeys stored on the device. That is a decision for a person on one device, not for a schedule.
[Screenshot from the earlier version of the script: remediation output with green OK, cyan ACTION, and yellow WARN lines]
Step-by-step: Add to Intune Proactive Remediations
Proactive Remediations are under Intune > Devices > Remediations.
Step 1 — Create a new script package
Go to Devices → Remediations → + Create script package. Name it something clear like WHfB Health Check and Repair.
Step 2 — Upload both scripts
Under Settings, upload the detection and remediation scripts:
- Detection script file:
Detect-WHfB.ps1 - Remediation script file:
Remediate-WHfB.ps1 - Run script in 64-bit PowerShell: Yes
- Run using logged-on credentials: No (SYSTEM context) for the repair package. Intune sets this once per script package, not per script (Microsoft's Remediations page lists it as one setting on the Settings step). For the full detection, including the PRT and the Hello key, create a second, report-only package with
Detect-WHfB.ps1only and this setting on Yes
Step 3 — Set the schedule
Under Assignments, set the schedule to Every 1 hour or Daily. Hourly catches broken devices faster.
Step 4 — Assign to your device group
Assign to your Windows 10/11 device group. Start with a pilot group — your IT team — before rolling to the full estate.
Reading the results
After deployment, go to Devices → Remediations → your package → Device status:
- Without issues — detection exited 0, WHfB is healthy
- With issues (remediated) — detection exited 1, remediation ran and completed
- Remediation failed — check the log at
C:\ProgramData\WHfB-Repair\on the device
The last line of the remediation output is machine readable: WHFB-REMEDIATE result=<ok|partial|stopped|failed> issue=... aadsts=... actions=.... stopped is deliberate: Entra ID refused the sign-in (for example AADSTS130004), a script cannot fix that, and exit code 1 keeps the device visible in Intune.
For devices showing remediated but still with NgcSet = NO in the post-state: the user needs to sign out and sign back in to complete WHfB PIN setup. Everything fixable in SYSTEM context is handled automatically — the final PIN creation requires the user. If the Hello key is still missing after that, the log records the state and a person decides the next step.
Get the scripts
Both scripts are available on GitHub. Download, review the comments, and deploy.
🔗 View on GitHub — Imran76Awan/WHFB/Intune Remediation
Detect-WHfB.ps1 first to confirm exit code 1, then run Remediate-WHfB.ps1 as admin. The colour-coded output (green = OK, red = FAIL, cyan = ACTION) lets you follow exactly what the script is doing at each step. The full log is written to C:\ProgramData\WHfB-Repair\.