# run-enrollment.ps1 # Installs GCCH enrollment provisioning package, waits for all PPKG apps # to finish installing, registers sync_intune as a persistent @logon task, # then reboots. # # Called by Run-ShopfloorSetup.ps1 AFTER all PreInstall + type-specific # apps are already installed (not as a FirstLogonCommand -- that was the # old flow). $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 = (Get-CimInstance Win32_BIOS).SerialNumber $newName = "E$serial" Log "Setting computer name to $newName" Rename-Computer -NewName $newName -Force -ErrorAction SilentlyContinue # --- Install provisioning package --- Log "Installing provisioning package..." try { Install-ProvisioningPackage -PackagePath $ppkgFile.FullName -ForceInstall -QuietInstall Log "Provisioning package installed successfully." } catch { Log "ERROR: Install-ProvisioningPackage failed: $_" Log "Attempting fallback with Add-ProvisioningPackage..." try { Add-ProvisioningPackage -PackagePath $ppkgFile.FullName -ForceInstall -QuietInstall Log "Provisioning package added successfully (fallback)." } catch { Log "ERROR: Fallback also failed: $_" return } } # --- Wait for PPKG provisioning to finish --- # Install-ProvisioningPackage is async -- it queues the provisioning engine # and returns immediately. The actual app installs (Chrome, Office, Tanium, # CyberArk, etc.) run in the background as BPRT steps. "Remove Staging # Locations" is the LAST step -- when its Log.txt exists, all provisioning # is done. $bprtMarker = 'C:\Logs\BPRT\Remove Staging Locations\Log.txt' $maxWait = 900 # 15 minutes (Office install can be slow) $pollInterval = 10 $elapsed = 0 Log "Waiting for PPKG provisioning to complete..." while (-not (Test-Path -LiteralPath $bprtMarker) -and $elapsed -lt $maxWait) { Start-Sleep -Seconds $pollInterval $elapsed += $pollInterval if ($elapsed % 30 -eq 0) { $completedSteps = @(Get-ChildItem 'C:\Logs\BPRT' -Directory -ErrorAction SilentlyContinue | Where-Object { Test-Path (Join-Path $_.FullName 'Log.txt') } | Select-Object -ExpandProperty Name) Log " $elapsed s elapsed, $($completedSteps.Count) BPRT steps done: $($completedSteps -join ', ')" } } if (Test-Path -LiteralPath $bprtMarker) { Log "PPKG provisioning complete after $elapsed s." } else { Log "WARNING: PPKG provisioning timeout after $maxWait s." } # --- Set OOBE complete --- 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 # --- Register sync_intune as persistent @logon scheduled task --- # sync_intune monitors the Intune enrollment lifecycle (5-phase status # table). It stays registered as a logon task until: # - Pre-reboot: monitors until Phase 1+2+3 done -> reboots # - Post-reboot: monitors until DSC install complete -> unregisters # itself, launches Configure-PC # # Runs as BUILTIN\Users (logged-in user) so it can show GUI (QR code, # status table). Needs the interactive session, NOT SYSTEM. $taskName = 'Shopfloor Intune Sync' $monitorScript = 'C:\Enrollment\shopfloor-setup\Shopfloor\lib\Monitor-IntuneProgress.ps1' $configureScript = 'C:\Enrollment\shopfloor-setup\Shopfloor\Configure-PC.ps1' if (Test-Path -LiteralPath $monitorScript) { try { $action = New-ScheduledTaskAction ` -Execute 'powershell.exe' ` -Argument "-NoProfile -NoExit -ExecutionPolicy Bypass -File `"$monitorScript`" -AsTask -ConfigureScript `"$configureScript`"" $trigger = New-ScheduledTaskTrigger -AtLogOn $principal = New-ScheduledTaskPrincipal ` -GroupId 'S-1-5-32-545' ` -RunLevel Limited $settings = New-ScheduledTaskSettingsSet ` -AllowStartIfOnBatteries ` -DontStopIfGoingOnBatteries ` -StartWhenAvailable ` -ExecutionTimeLimit (New-TimeSpan -Hours 2) Register-ScheduledTask ` -TaskName $taskName ` -Action $action ` -Trigger $trigger ` -Principal $principal ` -Settings $settings ` -Force ` -ErrorAction Stop | Out-Null Log "Registered '$taskName' logon task (persists until sync complete)." } catch { Log "WARNING: Failed to register sync task: $_" } } else { Log "WARNING: Monitor-IntuneProgress.ps1 not found at $monitorScript" } Log "=== Enrollment complete. Rebooting... ===" # Reboot -- PPKG file operations (Zscaler rename, cleanup) happen on next boot. # sync_intune fires at next logon via the scheduled task. shutdown /r /t 10