From 5a9c3db7afd8f1fb764db504ae1e2e07bd25c598 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 15 Apr 2026 08:35:35 -0400 Subject: [PATCH] run-enrollment.ps1: invoke provtool.exe directly, skip PowerShell cmdlet timeout Observed today on E8FHGDB4: Install-ProvisioningPackage timed out after the PowerShell cmdlet's hardcoded 180s limit on a 7.6 GB GCCH v4.10 PPKG. The catch-block fell through to Add-ProvisioningPackage, which returned "success" but the PPKG diagnostic bundle showed the child provtool.exe was called with empty packagePathsToAdd (session created, State=Not started, RebootCount=0). The PC was named, OOBE-completed, and BPRT apps ran, but the bulk enrollment never applied - PC was not Entra-joined. Microsoft Docs GitHub issue 502 confirms the 180s cmdlet timeout is hardcoded with no configuration option. Quest KB 4376269 suggests rebuilding the PPKG with the latest Windows Configuration Designer, but that is upstream and not under our control per PPKG. Switch to Start-Process -FilePath provtool.exe -Wait. The wait is on the actual child process, no caller-side timeout. provtool.exe is what the cmdlet was invoking anyway; we just bypass the wrapper that imposes the limit. Sources: https://support.quest.com/on-demand-migration/kb/4376269 https://github.com/MicrosoftDocs/windows-powershell-docs/issues/502 https://learn.microsoft.com/en-us/windows/configuration/provisioning-packages/provisioning-apply-package --- playbook/shopfloor-setup/run-enrollment.ps1 | 40 ++++++++++++--------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/playbook/shopfloor-setup/run-enrollment.ps1 b/playbook/shopfloor-setup/run-enrollment.ps1 index f2820fa..cd7bc1e 100755 --- a/playbook/shopfloor-setup/run-enrollment.ps1 +++ b/playbook/shopfloor-setup/run-enrollment.ps1 @@ -38,27 +38,35 @@ Rename-Computer -NewName $newName -Force -ErrorAction SilentlyContinue # enrollment PPKGs are designed to run during OOBE; on Windows 11 22H2+ they # can hang indefinitely if OOBE is already marked complete. # -# Install-ProvisioningPackage triggers an IMMEDIATE reboot. Nothing below -# this line executes. BPRT app installs (Chrome, Office, Tanium, etc.) happen -# on the next boot. The sync_intune scheduled task (registered by -# Run-ShopfloorSetup.ps1 before calling us) fires at the next logon to -# monitor Intune enrollment. +# We invoke provtool.exe directly instead of Install-ProvisioningPackage. +# The PowerShell cmdlet enforces a hardcoded 180-second timeout on the +# underlying provtool call, which a 7-8 GB GCCH PPKG often exceeds on +# slower disks. When the cmdlet times out it throws, and the Add- +# ProvisioningPackage fallback has been observed to invoke provtool with +# an empty packagePathsToAdd (session registered but never started), +# leaving the PC un-enrolled. provtool.exe directly has no caller-side +# timeout; Start-Process -Wait waits on the actual child process. +# +# The PPKG triggers an IMMEDIATE reboot once fully applied. Nothing below +# that point executes on the current boot. BPRT app installs (Chrome, +# Office, Tanium, etc.) happen on the next boot. The sync_intune +# scheduled task (registered by Run-ShopfloorSetup.ps1 before calling us) +# fires at the next logon to monitor Intune enrollment. $ppkgLogDir = "C:\Logs\PPKG" New-Item -ItemType Directory -Path $ppkgLogDir -Force -ErrorAction SilentlyContinue | Out-Null -Log "Installing provisioning package (PPKG will reboot immediately)..." +$provtool = Join-Path $env:SystemRoot 'System32\provtool.exe' +$provArgs = "/ppkg:`"$($ppkgFile.FullName)`" /quiet /log:`"$ppkgLogDir\provtool.log`"" +Log "Installing provisioning package via provtool.exe (no PowerShell timeout)..." +Log "Command: $provtool $provArgs" Log "PPKG diagnostic logs -> $ppkgLogDir" try { - Install-ProvisioningPackage -PackagePath $ppkgFile.FullName -ForceInstall -QuietInstall -LogsDirectoryPath $ppkgLogDir - Log "Install-ProvisioningPackage returned (reboot may be imminent)." -} catch { - Log "ERROR: Install-ProvisioningPackage failed: $_" - Log "Attempting fallback with Add-ProvisioningPackage..." - try { - Add-ProvisioningPackage -PackagePath $ppkgFile.FullName -ForceInstall -QuietInstall -LogsDirectoryPath $ppkgLogDir - Log "Add-ProvisioningPackage returned." - } catch { - Log "ERROR: Fallback also failed: $_" + $p = Start-Process -FilePath $provtool -ArgumentList $provArgs -Wait -PassThru -NoNewWindow -ErrorAction Stop + Log "provtool.exe exit code: $($p.ExitCode)" + if ($p.ExitCode -ne 0) { + Log "WARNING: provtool.exe returned non-zero exit code. Check $ppkgLogDir\provtool.log for details." } +} catch { + Log "ERROR: Failed to launch provtool.exe: $_" } # --- Set OOBE complete (only reached if PPKG didn't trigger immediate reboot) ---