Files
pxe-server/playbook/shopfloor-setup/run-enrollment.ps1
cproudlock 5a9c3db7af 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
2026-04-15 08:35:35 -04:00

79 lines
3.6 KiB
PowerShell
Executable File

# run-enrollment.ps1
# Installs GCCH enrollment provisioning package. That's it.
#
# Install-ProvisioningPackage triggers an immediate reboot -- nothing after
# that call executes. The sync_intune task and all other post-enrollment
# setup are registered by Run-ShopfloorSetup.ps1 BEFORE calling this script.
$ErrorActionPreference = 'Continue'
$logFile = "C:\Logs\enrollment.log"
New-Item -ItemType Directory -Path "C:\Logs" -Force -ErrorAction SilentlyContinue | Out-Null
function Log {
param([string]$Message)
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$line = "$ts $Message"
Write-Host $line
Add-Content -Path $logFile -Value $line
}
Log "=== GE Aerospace GCCH Enrollment ==="
# --- Find the .ppkg ---
$ppkgFile = Get-ChildItem "C:\Enrollment\*.ppkg" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $ppkgFile) {
Log "No .ppkg found in C:\Enrollment\ - skipping enrollment."
return
}
Log "Package: $($ppkgFile.Name)"
# --- Set computer name to E<serial> ---
$serial = (Get-CimInstance Win32_BIOS).SerialNumber
$newName = "E$serial"
Log "Setting computer name to $newName"
Rename-Computer -NewName $newName -Force -ErrorAction SilentlyContinue
# --- Install provisioning package ---
# IMPORTANT: The PPKG must be installed BEFORE OOBEComplete is set. Bulk
# enrollment PPKGs are designed to run during OOBE; on Windows 11 22H2+ they
# can hang indefinitely if OOBE is already marked complete.
#
# 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
$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 {
$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) ---
Log "Setting OOBE as complete..."
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE" /v OOBEComplete /t REG_DWORD /d 1 /f | Out-Null
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE" /v SetupDisplayedEula /t REG_DWORD /d 1 /f | Out-Null
# If we get here, the PPKG didn't reboot immediately. Unlikely but handle it.
Log "PPKG did not trigger immediate reboot. Returning to caller."