@echo off echo Please wait while 'WinPE' is being processed. This may take a few seconds. wpeinit powercfg /s 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c REM --- Wait for network (DHCP may take a moment after wpeinit) --- echo Waiting for network... :wait_net ping -n 2 172.16.9.1 >NUL 2>&1 if errorlevel 1 goto wait_net echo Network ready. REM --- BIOS update check (runs before imaging menu) --- REM Mounts [winpeapps_bios] share. CRITICAL: do NOT call check-bios.cmd REM inside an `if exist (...)` parens block - CMD's variable scoping for REM CALLed scripts inside parens does not propagate BIOS_STATUS back to REM this script reliably. Use goto-flow instead so the CALL runs at the REM top scope and BIOS_STATUS persists. set BIOS_STATUS=No BIOS check (share unavailable) net use B: \\172.16.9.1\winpeapps_bios /user:pxe-upload pxe /persistent:no 2>NUL if not exist B:\check-bios.cmd goto :bios_check_done echo. echo Checking for BIOS updates... call B:\check-bios.cmd :bios_check_done net use B: /delete 2>NUL :menu cls echo. echo ======================================== echo WinPE Setup Menu echo ======================================== echo Firmware: %BIOS_STATUS% echo. echo Please select an option: echo. echo 1. GEA Standard echo 2. GEA Engineer echo 3. GEA Shopfloor (sub-menu) echo 4. GE Standard echo 5. GE Engineer echo 6. GE Shopfloor Lockdown echo 7. GE Shopfloor MCE echo. echo ======================================== echo. set /p choice=Enter your choice (1-7): REM --- Shopfloor images (3,6,7) need GCCH enrollment + (for 3) PC-type sub-menu. REM Choice 3 = GEA Shopfloor: drill into sub-menu first to pick the gea-shopfloor-* REM sub-category, THEN the office menu, THEN machine number for collections+nocollections. set PPKG= if "%choice%"=="3" goto gea_shopfloor_submenu if "%choice%"=="6" goto enroll_menu if "%choice%"=="7" goto enroll_menu goto enroll_staged :gea_shopfloor_submenu cls echo. echo ======================================== echo GEA Shopfloor PC Sub-Type echo ======================================== echo. echo 1. Machine with Collections (eDNC + UDC + Plant Apps) echo 2. Machine without Collections (eDNC + Plant Apps, no UDC) echo 3. Common (Timeclock, Lab; WJ Shopfloor only) echo 4. Keyence (VR-3000 / VR-5000 / VR-6000 microscope) echo 5. CMM (Hexagon PC-DMIS + Protect Viewer) echo 6. Genspect echo 7. Heattreat (eDNC + HeatTreat app) echo 8. Wax and Trace echo 9. Display (kiosk dashboard) echo 10. Part Marker (eDNC + Telesis Mark) echo. set PCTYPE= set /p ges_choice=Enter your choice (1-10): if "%ges_choice%"=="1" set PCTYPE=gea-shopfloor-collections if "%ges_choice%"=="2" set PCTYPE=gea-shopfloor-nocollections if "%ges_choice%"=="3" set PCTYPE=gea-shopfloor-common if "%ges_choice%"=="4" set PCTYPE=gea-shopfloor-keyence if "%ges_choice%"=="5" set PCTYPE=gea-shopfloor-cmm if "%ges_choice%"=="6" set PCTYPE=gea-shopfloor-genspect if "%ges_choice%"=="7" set PCTYPE=gea-shopfloor-heattreat if "%ges_choice%"=="8" set PCTYPE=gea-shopfloor-waxtrace if "%ges_choice%"=="9" set PCTYPE=gea-shopfloor-display if "%ges_choice%"=="10" set PCTYPE=gea-shopfloor-partmarker if "%PCTYPE%"=="" goto gea_shopfloor_submenu if "%PCTYPE%"=="gea-shopfloor-display" goto display_submenu if "%PCTYPE%"=="gea-shopfloor-keyence" goto keyence_submenu if "%PCTYPE%"=="gea-shopfloor-cmm" goto cmm_submenu goto enroll_menu :keyence_submenu cls echo. echo ======================================== echo Keyence Model echo ======================================== echo. echo 1. VR-3000 G2 (older microscope/profilometer line) echo 2. VR-5000 (mid-range) echo 3. VR-6000 (current line) echo. set KEYENCEMODEL= set /p kmod_choice=Enter your choice (1-3): if "%kmod_choice%"=="1" set KEYENCEMODEL=vr3000 if "%kmod_choice%"=="2" set KEYENCEMODEL=vr5000 if "%kmod_choice%"=="3" set KEYENCEMODEL=vr6000 if "%KEYENCEMODEL%"=="" goto keyence_submenu echo Keyence model: %KEYENCEMODEL% goto enroll_menu :cmm_submenu cls echo. echo ======================================== echo CMM Bay Selection echo ======================================== echo. echo Loading CMM bay list from PXE share... REM Mount enrollment share early so the picker can read the CSV. net use Y: \\172.16.9.1\enrollment /user:pxe-upload pxe /persistent:no >NUL 2>NUL del X:\cmm-bay.txt 2>NUL set CMMID= set CMMVARIANT=standard if not exist "Y:\installers-post\cmm\select-cmm-bay.ps1" goto cmm_picker_skip powershell.exe -NoProfile -ExecutionPolicy Bypass -File "Y:\installers-post\cmm\select-cmm-bay.ps1" -ConfigPath "Y:\installers-post\cmm\cmm-bay-config.csv" -OutFile "X:\cmm-bay.txt" :cmm_picker_skip if exist X:\cmm-bay.txt set /p CMMID=NUL 2>NUL del X:\waxtrace-asset.txt 2>NUL if not exist "Y:\installers-post\waxtrace\select-waxtrace-asset.ps1" goto waxtrace_picker_skip powershell.exe -NoProfile -ExecutionPolicy Bypass -File "Y:\installers-post\waxtrace\select-waxtrace-asset.ps1" -IndexPath "Y:\installers-post\waxtrace\bay-config.csv" -OutFile "X:\waxtrace-asset.txt" :waxtrace_picker_skip set MACHINENUM= if exist X:\waxtrace-asset.txt set /p MACHINENUM= X:\Boot.tag if "%choice%"=="1" goto gea-standard if "%choice%"=="2" goto gea-engineer if "%choice%"=="3" goto gea-shopfloor if "%choice%"=="4" goto ge-standard if "%choice%"=="5" goto ge-engineer if "%choice%"=="6" goto ge-shopfloor-lockdown if "%choice%"=="7" goto ge-shopfloor-mce echo Invalid choice. Please try again. pause goto menu :gea-standard echo. echo Starting GEA Standard setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\gea-standard /user:pxe-upload pxe /persistent:no goto end :gea-engineer echo. echo Starting GEA Engineer setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\gea-engineer /user:pxe-upload pxe /persistent:no goto end :gea-shopfloor echo. echo Starting GEA Shopfloor setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\gea-shopfloor /user:pxe-upload pxe /persistent:no goto end :ge-standard echo. echo Starting GE Standard setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\ge-standard /user:pxe-upload pxe /persistent:no goto end :ge-engineer echo. echo Starting GE Engineer setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\ge-engineer /user:pxe-upload pxe /persistent:no goto end :ge-shopfloor-lockdown echo. echo Starting GE Shopfloor Lockdown setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\ge-shopfloor-lockdown /user:pxe-upload pxe /persistent:no goto end :ge-shopfloor-mce echo. echo Starting GE Shopfloor MCE setup... start "FlatApp" %SYSTEMDRIVE%\GESetup\FlatSetupLoader.exe for /l %%i in (1,1,2000000) do rem net use Z: \\172.16.9.1\winpeapps\ge-shopfloor-mce /user:pxe-upload pxe /persistent:no goto end :end echo. REM --- Push initial "WinPE staging" status to PXE webapp --- REM Externalized to Y:\scripts\winpe-status-push.ps1 so future edits don't REM require a boot.wim rebuild. Best-effort; the script logs to REM X:\Windows\Temp\winpe-status-push.log and swallows all errors. if exist "Y:\scripts\winpe-status-push.ps1" ( powershell -NoProfile -ExecutionPolicy Bypass -File "Y:\scripts\winpe-status-push.ps1" ) echo Waiting for PESetup.exe to start... :wait_start ping -n 3 127.0.0.1 >NUL wmic process where "name='PESetup.exe'" get name 2>NUL | find /I "PESetup" >NUL if errorlevel 1 goto wait_start echo PESetup.exe is running. Waiting for imaging to complete... REM --- Copy enrollment package and shopfloor setup as soon as Windows partition appears --- if "%PPKG%"=="" if "%PCTYPE%"=="" goto wait_finish echo Waiting for Windows partition at W: ... :wait_enroll ping -n 11 127.0.0.1 >NUL if not exist W:\Windows\System32\config\system goto wait_enroll echo Found Windows at W: mkdir W:\Enrollment 2>NUL REM Log all copy operations to a file that persists on the target disk. REM Tech can check C:\Enrollment\winpe-staging.log post-imaging. REM Each echo in the copy block below also appends to this file via REM the >> redirect after the screen echo. robocopy /LOG+ appends its REM own output directly. set STAGELOG=W:\Enrollment\winpe-staging.log echo [%DATE% %TIME%] WinPE staging started >> "%STAGELOG%" echo PCTYPE=%PCTYPE% PPKG=%PPKG% MACHINENUM=%MACHINENUM% CMMID=%CMMID% >> "%STAGELOG%" REM --- Copy site config (drives site-specific values in all setup scripts) --- if exist "Y:\config\site-config.json" ( robocopy "Y:\config" "W:\Enrollment" "site-config.json" /R:1 /W:1 /NFL /NDL /NJH /NJS echo Copied site-config.json. echo [%TIME%] Copied site-config.json >> "%STAGELOG%" ) else ( echo WARNING: site-config.json not found on enrollment share. echo [%TIME%] WARNING: site-config.json not found >> "%STAGELOG%" ) REM --- Copy PPKG if selected (renames from SOURCE to BPRT-tagged filename) --- if "%PPKG%"=="" goto copy_pctype robocopy "Y:\ppkgs" "W:\Enrollment" "%SOURCE_PPKG%" /R:1 /W:1 /NFL /NDL /NJH /NJS REM robocopy exit codes: 0-7 = success, 8+ = failure (inverse of copy's 0/1). if errorlevel 8 ( echo WARNING: Failed to copy enrollment package. echo [%TIME%] WARNING: Failed to copy PPKG %SOURCE_PPKG% >> "%STAGELOG%" goto copy_pctype ) REM robocopy keeps the source name; rename to the BPRT-tagged target name. if not "%SOURCE_PPKG%"=="%PPKG%" ren "W:\Enrollment\%SOURCE_PPKG%" "%PPKG%" echo [%TIME%] Copied PPKG %SOURCE_PPKG% as %PPKG% >> "%STAGELOG%" robocopy "Y:\scripts" "W:\Enrollment" "run-enrollment.ps1" "wait-for-internet.ps1" "migrate-to-wifi.ps1" /R:1 /W:1 /NFL /NDL /NJH /NJS echo [%TIME%] Copied enrollment scripts >> "%STAGELOG%" REM --- Create enroll.cmd at drive root as manual fallback --- > W:\enroll.cmd ( echo @echo off echo echo Waiting for network... echo :waitnet echo ping -n 2 8.8.8.8 ^>NUL 2^>^&1 echo if errorlevel 1 goto waitnet echo echo Network connected. Running enrollment... echo powershell.exe -ExecutionPolicy Bypass -File "C:\run-enrollment.ps1" ) echo Manual fallback created at W:\enroll.cmd :copy_pctype REM --- Copy shopfloor PC type setup scripts --- if "%PCTYPE%"=="" goto cleanup_enroll echo %PCTYPE%> W:\Enrollment\pc-type.txt REM 2026-05-04 rename reorg: pc-subtype.txt no longer written. REM display-type.txt IS still written for gea-shopfloor-display because REM Install-KioskApp.cmd reads it to pick Lobby vs Dashboard installer REM and Get-PCProfile.ps1 reads it to build the Display-{type} profile key. if not "%DISPLAYTYPE%"=="" echo %DISPLAYTYPE%> W:\Enrollment\display-type.txt if not "%MACHINENUM%"=="" echo %MACHINENUM%> W:\Enrollment\machine-number.txt REM Keyence model goes to BOTH keyence-model.txt (read by 09-Setup-Keyence) AND REM pc-subtype.txt (read by GE-Enforce for per-model dispatch via existing REM PCSubType wiring: looks for gea-shopfloor-keyence-\manifest.json on share). if not "%KEYENCEMODEL%"=="" ( echo %KEYENCEMODEL%> W:\Enrollment\keyence-model.txt echo %KEYENCEMODEL%> W:\Enrollment\pc-subtype.txt ) REM CMM bay ID + resolved config. CMMID comes from the bay picker (e.g. CMM4). REM Written to machine-number.txt (same field collections/waxtrace use) so REM TargetMachineNumbers on the SFLD share manifest gates per-bay entries. REM resolve-cmm-bay-config.ps1 reads the CSV and writes version.txt + doda.txt REM to W:\Enrollment\cmm\ for 09-Setup-CMM.ps1 to consume. if "%CMMID%"=="" goto cmm_id_done echo %CMMID%> W:\Enrollment\machine-number.txt mkdir W:\Enrollment\cmm 2>NUL if exist "Y:\installers-post\cmm\resolve-cmm-bay-config.ps1" ( powershell.exe -NoProfile -ExecutionPolicy Bypass -File "Y:\installers-post\cmm\resolve-cmm-bay-config.ps1" -ConfigPath "Y:\installers-post\cmm\cmm-bay-config.csv" -CmmId "%CMMID%" -OutDir "W:\Enrollment\cmm" ) REM Read doda flag to set pc-subtype.txt for GE-Enforce manifest gating. REM goto-flow avoids CMD variable scoping issues inside parens blocks. if not exist W:\Enrollment\cmm\doda.txt goto cmm_id_done set /p CMMDODA= W:\Enrollment\pc-subtype.txt :cmm_id_done robocopy "Y:\shopfloor-setup" "W:\Enrollment" "Run-ShopfloorSetup.ps1" /R:1 /W:1 /NFL /NDL /NJH /NJS REM Post-boot bulk re-fetch. WinPE staging below is best-effort (it can fail if REM the Y: mount went idle-dead during the WIM apply); Fetch-StagingPayload.ps1 REM re-pulls the shopfloor-setup tree + preinstall bundle at first logon on a REM FRESH mount. The unattend FirstLogonCommands runs it before the PowerShell 7 REM MSI + Run-ShopfloorSetup. Stage the script + its source coords here. robocopy "Y:\shopfloor-setup" "W:\Enrollment" "Fetch-StagingPayload.ps1" /R:1 /W:1 /NFL /NDL /NJH /NJS REM Stage the staging self-heal directly too, so the unattend Order 5 heal step REM runs even if Fetch-StagingPayload itself did not land. Small, reliable copy. robocopy "Y:\shopfloor-setup" "W:\Enrollment" "Verify-And-Heal-Staging.ps1" /R:1 /W:1 /NFL /NDL /NJH /NJS > W:\Enrollment\fetch-source.txt ( echo \\172.16.9.1\enrollment echo pxe-upload echo pxe ) REM --- Always copy Shopfloor baseline scripts --- mkdir W:\Enrollment\shopfloor-setup 2>NUL robocopy "Y:\shopfloor-setup" "W:\Enrollment\shopfloor-setup" "backup_lockdown.bat" /R:1 /W:1 /NFL /NDL /NJH /NJS if exist "Y:\shopfloor-setup\Shopfloor" ( mkdir W:\Enrollment\shopfloor-setup\Shopfloor 2>NUL robocopy "Y:\shopfloor-setup\Shopfloor" "W:\Enrollment\shopfloor-setup\Shopfloor" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: shopfloor-setup\Shopfloor robocopy exit %ERRORLEVEL% echo Copied Shopfloor baseline setup files. echo [%TIME%] Copied Shopfloor baseline >> "%STAGELOG%" ) REM --- Always copy common/ (cross-PC-type GE-Enforce dispatcher + lib live here post-v2) --- if exist "Y:\shopfloor-setup\common" ( mkdir W:\Enrollment\shopfloor-setup\common 2>NUL robocopy "Y:\shopfloor-setup\common" "W:\Enrollment\shopfloor-setup\common" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: shopfloor-setup\common robocopy exit %ERRORLEVEL% echo Copied common setup files. echo [%TIME%] Copied common >> "%STAGELOG%" ) REM --- Copy _ntlars-backups (147 per-bay .reg files restored by gea-shopfloor-{collections,nocollections}\03-RestoreEDncConfig.ps1) --- REM Same root level as common/, referenced by 03-RestoreEDncConfig.ps1 via Join-Path $PSScriptRoot '..\_ntlars-backups'. if exist "Y:\shopfloor-setup\_ntlars-backups" ( mkdir W:\Enrollment\shopfloor-setup\_ntlars-backups 2>NUL robocopy "Y:\shopfloor-setup\_ntlars-backups" "W:\Enrollment\shopfloor-setup\_ntlars-backups" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: _ntlars-backups robocopy exit %ERRORLEVEL% echo Copied _ntlars-backups. echo [%TIME%] Copied _ntlars-backups >> "%STAGELOG%" ) REM --- Copy type-specific scripts on top of baseline --- if exist "Y:\shopfloor-setup\%PCTYPE%" ( mkdir "W:\Enrollment\shopfloor-setup\%PCTYPE%" 2>NUL robocopy "Y:\shopfloor-setup\%PCTYPE%" "W:\Enrollment\shopfloor-setup\%PCTYPE%" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: shopfloor-setup\%PCTYPE% robocopy exit %ERRORLEVEL% echo Copied %PCTYPE% setup files. echo [%TIME%] Copied %PCTYPE% type-specific >> "%STAGELOG%" ) else ( echo WARNING: No setup files found for PC type %PCTYPE%. echo [%TIME%] WARNING: No setup files for %PCTYPE% >> "%STAGELOG%" ) REM --- Stage preinstall bundle (apps installed locally to save Azure bandwidth) --- if exist "Y:\pre-install\preinstall.json" ( mkdir W:\PreInstall 2>NUL mkdir W:\PreInstall\installers 2>NUL robocopy "Y:\pre-install" "W:\PreInstall" "preinstall.json" /R:1 /W:1 /NFL /NDL /NJH /NJS if exist "Y:\pre-install\installers" ( robocopy "Y:\pre-install\installers" "W:\PreInstall\installers" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: pre-install\installers robocopy exit %ERRORLEVEL% echo Staged preinstall bundle to W:\PreInstall. echo [%TIME%] Staged preinstall bundle >> "%STAGELOG%" ) else ( echo WARNING: Y:\pre-install\installers not found - preinstall.json staged without installers. ) if exist "Y:\pre-install\udc-backups" ( robocopy "Y:\pre-install\udc-backups" "W:\PreInstall\udc-backups" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: pre-install\udc-backups robocopy exit %ERRORLEVEL% echo Staged UDC settings backups to W:\PreInstall\udc-backups. echo [%TIME%] Staged UDC backups >> "%STAGELOG%" ) ) else ( echo No preinstall bundle on PXE server - skipping. ) REM --- Stage CMM bootstrap bundle (CMM-type PCs only) --- REM Copies the Hexagon installer bundle (~1.9 GB) from the PXE server enrollment REM share onto the target disk so 09-Setup-CMM.ps1 can install from local disk. REM The tsgwp00525 SFLD share that holds the canonical copy is not yet reachable REM during shopfloor-setup (Azure DSC provisions those creds later), so this REM bootstrap exists to get the first-install through. Post-imaging, the REM unified GE-Enforce dispatcher takes over from the share for ongoing updates. if /i not "%PCTYPE%"=="gea-shopfloor-cmm" goto skip_cmm_stage if exist "Y:\installers-post\cmm\cmm-manifest.json" ( mkdir W:\CMM-Install 2>NUL REM /XD the backups tree: it holds EVERY bay's settings backup (some 240 MB REM each). Copying all of it to every imaged CMM would waste GBs. The bulk REM copy excludes it; the selected bay's backup is staged separately below. robocopy "Y:\installers-post\cmm" "W:\CMM-Install" /E /XD "Y:\installers-post\cmm\backups" /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: cmm robocopy exit %ERRORLEVEL% echo Staged CMM bootstrap to W:\CMM-Install. echo [%TIME%] Staged CMM bootstrap >> "%STAGELOG%" ) else ( echo WARNING: Y:\cmm-installers not found - CMM PC cannot install Hexagon apps at imaging time. ) REM Stage ONLY the selected bay's settings backup. 09-Setup-CMM's Restore-CMM REM reads W:\CMM-Install\backups\%CMMID%\ to restore PC-DMIS + goCMM settings. if not defined CMMID goto skip_cmm_stage if exist "Y:\installers-post\cmm\backups\%CMMID%" ( robocopy "Y:\installers-post\cmm\backups\%CMMID%" "W:\CMM-Install\backups\%CMMID%" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" echo Staged %CMMID% settings backup for restore. echo [%TIME%] Staged %CMMID% backup >> "%STAGELOG%" ) :skip_cmm_stage REM --- Stage Keyence per-model bootstrap bundle (Keyence PCs only) --- REM Copies only the selected model's MSI + Data cabs from the PXE enrollment REM share to the target disk. installers-post/keyence// contains: REM manifest.json REM installers/{MSI, Data1.cab, [Data11.cab for vr3000], 1033.mst} REM drivers/ (vr6000 only - older external .inf; vr3000/vr5000 drivers REM are embedded in their MSIs) REM 09-Setup-Keyence.ps1 reads C:\Enrollment\keyence-model.txt to know which. if /i not "%PCTYPE%"=="gea-shopfloor-keyence" goto skip_keyence_stage if "%KEYENCEMODEL%"=="" goto skip_keyence_stage if exist "Y:\installers-post\keyence\%KEYENCEMODEL%\manifest.json" ( mkdir W:\KeyenceInstall 2>NUL mkdir W:\KeyenceInstall\%KEYENCEMODEL% 2>NUL robocopy "Y:\installers-post\keyence\%KEYENCEMODEL%" "W:\KeyenceInstall\%KEYENCEMODEL%" /E /MT:16 /R:1 /W:1 /NFL /NDL /LOG+:"%STAGELOG%" if errorlevel 8 echo WARNING: keyence\%KEYENCEMODEL% robocopy exit %ERRORLEVEL% echo Staged Keyence %KEYENCEMODEL% bootstrap to W:\KeyenceInstall\%KEYENCEMODEL%\. echo [%TIME%] Staged Keyence %KEYENCEMODEL% >> "%STAGELOG%" ) else ( echo WARNING: Y:\installers-post\keyence\%KEYENCEMODEL% not found - Keyence %KEYENCEMODEL% cannot install at imaging time. ) :skip_keyence_stage REM --- Stage WaxTrace bootstrap bundle (wax/trace gea-shopfloor-waxtrace only) --- REM Three-step process: REM 1. robocopy installers-post\waxtrace -> W:\WaxTrace-Install (everything REM EXCEPT the formtracepak\ subdir, via /XD - that subdir carries all REM 7 vendor ISOs and we only need one of them) REM 2. resolve-bay-config.ps1: reads bay-config.csv + asset_tag, writes REM W:\Enrollment\waxtrace\{version,model,userid}.txt for 09-Setup to read REM 3. robocopy ONLY the bay's matching FORMTRACEPAK-V.iso from REM Y:\installers-post\waxtrace\formtracepak\ onto the target disk REM (so 09-Setup-WaxAndTrace.ps1 mounts the right version per bay) if /i not "%PCTYPE%"=="gea-shopfloor-waxtrace" goto skip_waxtrace_stage if not exist "Y:\installers-post\waxtrace\waxtrace-manifest.json" goto skip_waxtrace_missing mkdir W:\WaxTrace-Install 2>NUL REM robocopy /XD excludes the formtracepak\ dir up front so we don't waste REM disk + time copying 12+ GB of vendor ISOs only to delete them. The REM matched FTPak ISO gets cherry-picked below into the same target dir. REM /NFL/NDL keep the listing manageable; output left visible (no >NUL) so REM any failure is debuggable from the install log. robocopy exit codes REM 0-7 are "OK" (per Microsoft); 8+ is real failure. robocopy "Y:\installers-post\waxtrace" "W:\WaxTrace-Install" /E /XD formtracepak /MT:16 /R:1 /W:1 /NFL /NDL if errorlevel 8 echo WARNING: robocopy exit %ERRORLEVEL% - some files may not have copied. mkdir W:\WaxTrace-Install\formtracepak 2>NUL echo Staged WaxTrace bootstrap minus formtracepak\ to W:\WaxTrace-Install. REM Resolve bay-config: writes W:\Enrollment\waxtrace\{version,model,userid}.txt mkdir W:\Enrollment\waxtrace 2>NUL if not "%MACHINENUM%"=="" ( powershell.exe -NoProfile -ExecutionPolicy Bypass -File "Y:\installers-post\waxtrace\resolve-bay-config.ps1" -Asset "%MACHINENUM%" -OutDir "W:\Enrollment\waxtrace" ) else ( echo WARNING: no MACHINENUM set - skipping bay-config resolve. 09-Setup-WaxAndTrace will abort cleanly with no version. ) REM Read the resolved version + robocopy ONLY that FTPak ISO (avoids dumping REM 12 GB of ISOs on the bay disk; only the matched ~2 GB ISO lands locally). set WTVER= if exist W:\Enrollment\waxtrace\version.txt set /p WTVER=.zip REM as part of the robocopy bundle above (backups\ is not in the /XD list). REM 09-Setup-WaxAndTrace.ps1 Step 3b reads C:\WaxTrace-Install\backups\ REM .zip post-vendor-MSI and runs Install-FormtracepakSettings.ps1 REM -RestoreData -RestoreConfig. Total ~17 MB on disk for the whole set, no REM cherry-pick needed. if not "%MACHINENUM%"=="" ( if exist "W:\WaxTrace-Install\backups\%MACHINENUM%.zip" ( echo Backup ZIP %MACHINENUM%.zip is in the bundle - 09-Setup Step 3b will restore. ) else ( echo INFO: No backup ZIP for %MACHINENUM% in W:\WaxTrace-Install\backups - 09-Setup will skip the restore step. ) ) goto skip_waxtrace_stage :skip_waxtrace_missing echo WARNING: Y:\installers-post\waxtrace not found - WaxTrace PC cannot install FormTracePak at imaging time. :skip_waxtrace_stage :pctype_done if defined STAGELOG echo [%TIME%] WinPE staging complete >> "%STAGELOG%" REM --- BIOS update sub-stage push (fires AFTER W: copies complete) --- REM check-bios.cmd drops X:\bios-fired.flag iff it actually flashed or REM staged a firmware update. Reading the flag file is more reliable than REM scanning BIOS_STATUS for substrings (caret escaping inside quoted SET REM is subtle in WinPE cmd.exe). Push must happen before Y: cleanup since REM the push script lives on the share. if exist X:\bios-fired.flag ( if exist "Y:\scripts\winpe-status-push.ps1" ( powershell -NoProfile -ExecutionPolicy Bypass -File "Y:\scripts\winpe-status-push.ps1" -CurrentStage "WinPE: BIOS firmware update" ) ) :cleanup_enroll net use Y: /delete 2>NUL :wait_finish ping -n 11 127.0.0.1 >NUL wmic process where "name='PESetup.exe'" get name 2>NUL | find /I "PESetup" >NUL if not errorlevel 1 goto wait_finish echo. echo Imaging complete. Rebooting in 15 seconds... echo Press Ctrl+C to cancel. ping -n 16 127.0.0.1 >NUL wpeutil reboot