From 14d103a2485cd03e28b0919811988a210ea2bd59 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 15 Apr 2026 17:07:12 -0400 Subject: [PATCH] run-enrollment: switch provtool /source from BPRT to PSCmdlet BPRT was stopping after the first RestartRequired=true command (DotNet35). Test image captured 2026-04-15 showed 3 of 21 PPKG commands ran (PPKG Version Check, Lock Screen, DotNet35) before provtool exited 0 leaving Office / Chrome / Tanium / Activate-Windows / Enable-DeviceLockdown / Hide-SupportUser / 12 more scripts unexecuted. Symptom: criticalChecks said EntraID NOT joined (wrong -- it was), sessions.json showed a 'LogonIdleTask' session perpetually 'Not started', and the resulting PC was missing most of its fleet software. BPRT is the OOBE runtime source -- it expects the OOBE engine to own the post-DotNet35 reboot + resume. In our post-autounattend context there is no OOBE engine, so restart-required commands stall the pipeline. PSCmdlet is the source Install-ProvisioningPackage uses internally and has the correct resume semantics for post-OOBE application. The original motivation for BPRT (avoiding the 180s PowerShell timeout) does not apply because we invoke provtool.exe directly, not via the Install-ProvisioningPackage cmdlet. Co-Authored-By: Claude Opus 4.6 (1M context) --- playbook/shopfloor-setup/run-enrollment.ps1 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/playbook/shopfloor-setup/run-enrollment.ps1 b/playbook/shopfloor-setup/run-enrollment.ps1 index 428f488..b1495f8 100755 --- a/playbook/shopfloor-setup/run-enrollment.ps1 +++ b/playbook/shopfloor-setup/run-enrollment.ps1 @@ -60,12 +60,18 @@ $provtool = Join-Path $env:SystemRoot 'System32\provtool.exe' # then /source. No /log: or /ppkg: prefix - those are not valid provtool # flags and caused 0x80004005 E_FAIL in the first test. # -# /source BPRT keeps us in the bulk-provisioning code path used by the -# automatic OOBE PPKG runtime. PSCmdlet would give richer ETW/event-log -# diagnostics, but may change which actions in the PPKG actually execute -# (not verified against Microsoft docs). Stay on BPRT and enable logging -# manually below. -$provArgs = @("`"$($ppkgFile.FullName)`"", "/quiet", "/source", "BPRT") +# /source PSCmdlet matches what Install-ProvisioningPackage invokes +# internally and is the correct post-OOBE context. BPRT was tried first +# and verified to stop after the first RestartRequired command (DotNet35): +# only 3 of 21 commands ran (PPKG Version Check, Lock Screen, DotNet35), +# leaving Office/Chrome/Tanium/Activate-Windows etc never executed +# because BPRT expects the OOBE runtime to own the reboot-and-resume +# loop, and there is no OOBE runtime here. PSCmdlet registers a +# RunOnce-style resume handler so the remaining commands continue after +# the reboot Run-ShopfloorSetup issues. Timeout concerns that previously +# motivated BPRT don't apply here because we invoke provtool.exe +# directly, not via the 180s-capped Install-ProvisioningPackage cmdlet. +$provArgs = @("`"$($ppkgFile.FullName)`"", "/quiet", "/source", "PSCmdlet") # Enable the Provisioning-Diagnostics-Provider Admin channel so events # from the BPRT run land somewhere we can export afterward. This is