diff --git a/playbook/shopfloor-setup/CMM/01-Setup-CMM.ps1 b/playbook/shopfloor-setup/CMM/09-Setup-CMM.ps1 similarity index 97% rename from playbook/shopfloor-setup/CMM/01-Setup-CMM.ps1 rename to playbook/shopfloor-setup/CMM/09-Setup-CMM.ps1 index 02124b7..c341d5f 100644 --- a/playbook/shopfloor-setup/CMM/01-Setup-CMM.ps1 +++ b/playbook/shopfloor-setup/CMM/09-Setup-CMM.ps1 @@ -1,4 +1,4 @@ -# 01-Setup-CMM.ps1 - CMM type setup (runs during shopfloor-setup phase). +# 09-Setup-CMM.ps1 - CMM type setup (runs during shopfloor-setup phase). # # At imaging time the tsgwp00525 SFLD share is NOT yet reachable - Azure DSC # has not provisioned the share credentials that early. So we install from a @@ -17,7 +17,7 @@ # 5. Delete C:\CMM-Install to reclaim the ~2 GB of bootstrap installers. # The share-side enforcer takes over from here. # -# Log: C:\Logs\CMM\01-Setup-CMM.log (stdout from this script) plus the +# Log: C:\Logs\CMM\09-Setup-CMM.log (stdout from this script) plus the # install-time log at C:\Logs\CMM\install.log written by Install-FromManifest. $ErrorActionPreference = 'Continue' @@ -34,14 +34,14 @@ $runtimeEnforce = Join-Path $runtimeRoot 'CMM-Enforce.ps1' $logDir = 'C:\Logs\CMM' $logFile = Join-Path $logDir 'install.log' -$transcriptLog = Join-Path $logDir '01-Setup-CMM.log' +$transcriptLog = Join-Path $logDir '09-Setup-CMM.log' if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory -Force | Out-Null } # Independent transcript in addition to whatever Run-ShopfloorSetup.ps1 is -# capturing at the top level. Lets a tech open C:\Logs\CMM\01-Setup-CMM.log +# capturing at the top level. Lets a tech open C:\Logs\CMM\09-Setup-CMM.log # and see the entire CMM-type setup run without scrolling through the # monolithic shopfloor-setup.log. try { Start-Transcript -Path $transcriptLog -Append -Force | Out-Null } catch {} diff --git a/playbook/shopfloor-setup/CMM/cmm-manifest.json b/playbook/shopfloor-setup/CMM/cmm-manifest.json index 945063b..e0a295c 100644 --- a/playbook/shopfloor-setup/CMM/cmm-manifest.json +++ b/playbook/shopfloor-setup/CMM/cmm-manifest.json @@ -1,6 +1,6 @@ { "Version": "2.0", - "_comment": "CMM machine-app manifest. Consumed by both 01-Setup-CMM.ps1 (at imaging time, reading from C:\\CMM-Install\\) and CMM-Enforce.ps1 (on logon, reading from the tsgwp00525 share). Option 3 (patched-MSI) install strategy: we bypass Hexagon's Burn bundle entirely for PC-DMIS 2016 and 2019 R2. The main PC-DMIS MSIs have been patched via COM SQL UPDATE (msibuild-style) to force the Condition column to '0' for two custom actions: ProcessLicensingFromBundle (which would otherwise spin for ~13 minutes trying to activate against licensing.wilcoxassoc.com with empty credentials) and IsLicenseDateValid (which would fail the install with 'no valid license'). With both CAs disabled, the MSI installs cleanly with no license present; PCDLRN.exe installs and loads at runtime and the tech activates a real license via clmadmin.exe after imaging. VS 2010/2012 x64 runtime prereqs are handled by the shared preinstall.json VC++ x64 entries (which run before this manifest). CLM Tools 1.5/1.7 chained MSIs from the original bundles are intentionally SKIPPED; CLM 1.8.73 standalone provides the admin + runtime interfaces. Protect Viewer is kept because it's useful alongside PC-DMIS 2019 R2.", + "_comment": "CMM machine-app manifest. Consumed by both 09-Setup-CMM.ps1 (at imaging time, reading from C:\\CMM-Install\\) and CMM-Enforce.ps1 (on logon, reading from the tsgwp00525 share). Option 3 (patched-MSI) install strategy: we bypass Hexagon's Burn bundle entirely for PC-DMIS 2016 and 2019 R2. The main PC-DMIS MSIs have been patched via COM SQL UPDATE (msibuild-style) to force the Condition column to '0' for two custom actions: ProcessLicensingFromBundle (which would otherwise spin for ~13 minutes trying to activate against licensing.wilcoxassoc.com with empty credentials) and IsLicenseDateValid (which would fail the install with 'no valid license'). With both CAs disabled, the MSI installs cleanly with no license present; PCDLRN.exe installs and loads at runtime and the tech activates a real license via clmadmin.exe after imaging. VS 2010/2012 x64 runtime prereqs are handled by the shared preinstall.json VC++ x64 entries (which run before this manifest). CLM Tools 1.5/1.7 chained MSIs from the original bundles are intentionally SKIPPED; CLM 1.8.73 standalone provides the admin + runtime interfaces. Protect Viewer is kept because it's useful alongside PC-DMIS 2019 R2.", "Applications": [ { "_comment": "PC-DMIS 2016 main MSI (PATCHED). ProcessLicensingFromBundle + IsLicenseDateValid custom actions have been pre-disabled by SQL UPDATE of InstallExecuteSequence.Condition to '0'. Install args: INSTALLFOLDER/APPLICATIONFOLDER paths have embedded double quotes to survive the runner's command-line concatenation when the path contains spaces. USINGWPFINSTALLER=1 mirrors the Burn bundle default and ensures HandleLicenseChoice CA (seq 783) stays skipped. HEIP=0 disables Hexagon telemetry. INSTALLPDFCONVERTER=0 skips the Nitro PDF converter. The patched MSI has a HashMismatch signature, which is expected and accepted by Windows Installer in /qn mode.", diff --git a/playbook/shopfloor-setup/CMM/lib/Install-FromManifest.ps1 b/playbook/shopfloor-setup/CMM/lib/Install-FromManifest.ps1 index 58c195f..b0c5280 100644 --- a/playbook/shopfloor-setup/CMM/lib/Install-FromManifest.ps1 +++ b/playbook/shopfloor-setup/CMM/lib/Install-FromManifest.ps1 @@ -10,7 +10,7 @@ # separate now avoids touching the Standard PC imaging path. # # Called from: -# - 01-Setup-CMM.ps1 at imaging time with InstallerRoot=C:\CMM-Install +# - 09-Setup-CMM.ps1 at imaging time with InstallerRoot=C:\CMM-Install # - CMM-Enforce.ps1 on logon with InstallerRoot= # # Returns via exit code: 0 if every required app is either already installed diff --git a/playbook/shopfloor-setup/Display/01-Setup-Display.ps1 b/playbook/shopfloor-setup/Display/09-Setup-Display.ps1 similarity index 92% rename from playbook/shopfloor-setup/Display/01-Setup-Display.ps1 rename to playbook/shopfloor-setup/Display/09-Setup-Display.ps1 index 0d85555..9578aec 100644 --- a/playbook/shopfloor-setup/Display/01-Setup-Display.ps1 +++ b/playbook/shopfloor-setup/Display/09-Setup-Display.ps1 @@ -1,4 +1,4 @@ -# 01-Setup-Display.ps1 -- Display-specific setup (runs after Shopfloor baseline) +# 09-Setup-Display.ps1 -- Display-specific setup (runs after Shopfloor baseline) # Reads display-type.txt to install either LobbyDisplay or Dashboard kiosk app. $enrollDir = "C:\Enrollment" diff --git a/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 b/playbook/shopfloor-setup/Genspect/09-Setup-Genspect.ps1 similarity index 77% rename from playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 rename to playbook/shopfloor-setup/Genspect/09-Setup-Genspect.ps1 index 016879a..e3cd99a 100644 --- a/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 +++ b/playbook/shopfloor-setup/Genspect/09-Setup-Genspect.ps1 @@ -1,10 +1,10 @@ -# 01-Setup-Genspect.ps1 - Genspect-specific setup (runs after Shopfloor baseline) +# 09-Setup-Genspect.ps1 - Genspect-specific setup (runs after Shopfloor baseline) # # PLACEHOLDER: add type-specific app installs when details are finalized. # This script will be called by Run-ShopfloorSetup.ps1 as part of the # type-specific phase, after all baseline scripts have completed. # -# For share-based installs, copy the pattern from CMM/01-Setup-CMM.ps1 +# For share-based installs, copy the pattern from CMM/09-Setup-CMM.ps1 # (credential lookup + share mount + install from share). Write-Host "=== Genspect Setup ===" diff --git a/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 b/playbook/shopfloor-setup/Keyence/09-Setup-Keyence.ps1 similarity index 77% rename from playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 rename to playbook/shopfloor-setup/Keyence/09-Setup-Keyence.ps1 index d49c6ec..02dd721 100644 --- a/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 +++ b/playbook/shopfloor-setup/Keyence/09-Setup-Keyence.ps1 @@ -1,10 +1,10 @@ -# 01-Setup-Keyence.ps1 - Keyence-specific setup (runs after Shopfloor baseline) +# 09-Setup-Keyence.ps1 - Keyence-specific setup (runs after Shopfloor baseline) # # PLACEHOLDER: add type-specific app installs when details are finalized. # This script will be called by Run-ShopfloorSetup.ps1 as part of the # type-specific phase, after all baseline scripts have completed. # -# For share-based installs, copy the pattern from CMM/01-Setup-CMM.ps1 +# For share-based installs, copy the pattern from CMM/09-Setup-CMM.ps1 # (credential lookup + share mount + install from share). Write-Host "=== Keyence Setup ===" diff --git a/playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 b/playbook/shopfloor-setup/Lab/09-Setup-Lab.ps1 similarity index 76% rename from playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 rename to playbook/shopfloor-setup/Lab/09-Setup-Lab.ps1 index 53f3fe4..c92aecb 100644 --- a/playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 +++ b/playbook/shopfloor-setup/Lab/09-Setup-Lab.ps1 @@ -1,10 +1,10 @@ -# 01-Setup-Lab.ps1 - Lab-specific setup (runs after Shopfloor baseline) +# 09-Setup-Lab.ps1 - Lab-specific setup (runs after Shopfloor baseline) # # PLACEHOLDER: add type-specific app installs when details are finalized. # This script will be called by Run-ShopfloorSetup.ps1 as part of the # type-specific phase, after all baseline scripts have completed. # -# For share-based installs, copy the pattern from CMM/01-Setup-CMM.ps1 +# For share-based installs, copy the pattern from CMM/09-Setup-CMM.ps1 # (credential lookup + share mount + install from share). Write-Host "=== Lab Setup ===" diff --git a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 index a9ef6c2..660c389 100644 --- a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 +++ b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 @@ -35,18 +35,16 @@ reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogo # Cancel any pending reboot so it doesn't interrupt setup cmd /c "shutdown /a 2>nul" *>$null -# Prompt user to unplug from PXE switch before re-enabling wired adapters -Write-Host "" -Write-Host "========================================" -ForegroundColor Yellow -Write-Host " UNPLUG the ethernet cable from the" -ForegroundColor Yellow -Write-Host " PXE imaging switch NOW." -ForegroundColor Yellow -Write-Host "========================================" -ForegroundColor Yellow -Write-Host "" -Write-Host "Press any key to continue..." -ForegroundColor Yellow -$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") - -# Re-enable wired adapters -Get-NetAdapter -Physical | Where-Object { $_.InterfaceDescription -notmatch 'Wi-Fi|Wireless' } | Enable-NetAdapter -Confirm:$false -ErrorAction SilentlyContinue +# Wired NIC state handling moved to sync_intune (Monitor-IntuneProgress.ps1). +# Previously this script prompted the tech to unplug the PXE cable and +# then re-enabled wired adapters interactively - that blocked the whole +# imaging chain on human keypress. The new flow leaves the wired state +# exactly as Order 5 (migrate-to-wifi.ps1) left it: +# - Tower (no WiFi): wired stays enabled, Run-ShopfloorSetup runs on wired. +# - Laptop (WiFi): wired disabled, Run-ShopfloorSetup runs on WiFi. +# Sync_intune re-enables wired at the start of its monitor loop, by which +# time the tech has had ample wall-clock time to physically unplug PXE +# and re-cable into production without blocking the chain on a keypress. $enrollDir = "C:\Enrollment" $typeFile = Join-Path $enrollDir "pc-type.txt" diff --git a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 index c8e43ba..25e090d 100644 --- a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 @@ -83,6 +83,26 @@ Write-Host "=== Monitor-IntuneProgress.ps1 starting $(Get-Date -Format 'yyyy-MM- Write-Host "Transcript: $transcriptPath" Write-Host "" +# ============================================================================ +# Re-enable any wired NICs that Order 5 (migrate-to-wifi.ps1) disabled during +# first-logon. Previously Run-ShopfloorSetup.ps1 did this with a blocking +# interactive "unplug PXE cable, press any key" prompt. By moving it here +# - to the start of sync_intune, which runs AFTER PPKG reboot + auto-login +# - the tech has had ample wall-clock time (minutes) to physically unplug +# the PXE cable and plug into the production ethernet without us blocking +# the imaging chain on a keypress. Tower (no WiFi) case is a no-op because +# Order 5's WiFi detection left the wired NIC enabled to begin with. +# ============================================================================ +try { + Get-NetAdapter -Physical -ErrorAction SilentlyContinue | + Where-Object { $_.InterfaceDescription -notmatch 'Wi-Fi|Wireless' } | + Enable-NetAdapter -Confirm:$false -ErrorAction SilentlyContinue + Write-Host "Wired NICs re-enabled (was migrate-to-wifi.ps1 had disabled them on laptops)." +} catch { + Write-Warning "Failed to re-enable wired NICs: $_" +} +Write-Host "" + # ============================================================================ # Console resize - the QR code is ~30 lines and the 5-phase status table is # ~25 lines. Default cmd window is 25 rows, so the QR scrolls off the top. diff --git a/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 b/playbook/shopfloor-setup/WaxAndTrace/09-Setup-WaxAndTrace.ps1 similarity index 77% rename from playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 rename to playbook/shopfloor-setup/WaxAndTrace/09-Setup-WaxAndTrace.ps1 index ca63f6e..098c2ec 100644 --- a/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 +++ b/playbook/shopfloor-setup/WaxAndTrace/09-Setup-WaxAndTrace.ps1 @@ -1,10 +1,10 @@ -# 01-Setup-WaxAndTrace.ps1 - Wax and Trace-specific setup (runs after Shopfloor baseline) +# 09-Setup-WaxAndTrace.ps1 - Wax and Trace-specific setup (runs after Shopfloor baseline) # # PLACEHOLDER: add type-specific app installs when details are finalized. # This script will be called by Run-ShopfloorSetup.ps1 as part of the # type-specific phase, after all baseline scripts have completed. # -# For share-based installs, copy the pattern from CMM/01-Setup-CMM.ps1 +# For share-based installs, copy the pattern from CMM/09-Setup-CMM.ps1 # (credential lookup + share mount + install from share). Write-Host "=== Wax and Trace Setup ===" diff --git a/playbook/shopfloor-setup/site-config.json b/playbook/shopfloor-setup/site-config.json index 62699d8..b5e039d 100644 --- a/playbook/shopfloor-setup/site-config.json +++ b/playbook/shopfloor-setup/site-config.json @@ -99,17 +99,23 @@ "CMM": { "_comment": "Hexagon CMM apps (CLM 1.8, goCMM, PC-DMIS 2016, PC-DMIS 2019 R2). At imaging time they install from a WinPE-staged local bootstrap at C:\\CMM-Install (put there by startnet.cmd when pc-type=CMM, source is the PXE server enrollment share). Post-imaging, the 'GE CMM Enforce' scheduled task runs CMM-Enforce.ps1 on user logon and enforces versions against the tsgwp00525 share below (the SFLD creds Azure DSC provisions unlock the mount). cmmSharePath is the ongoing-enforcement source, not the imaging-time source.", "cmmSharePath": "\\\\tsgwp00525.wjs.geaerospace.net\\shared\\dt\\shopfloor\\cmm\\machineapps", - "startupItems": [ - { "label": "WJ Shopfloor", "type": "existing", "sourceLnk": "WJ Shopfloor.lnk" } - ], + "startupItems": [], "taskbarPins": [ { "name": "Microsoft Edge", "lnkPath": "%ALLUSERSPROFILE%\\Microsoft\\Windows\\Start Menu\\Programs\\Microsoft Edge.lnk" }, - { "name": "WJ Shopfloor", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\WJ Shopfloor.lnk" }, - { "name": "Defect_Tracker", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\Defect_Tracker.lnk" } + { "name": "WJ Shopfloor", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\WJ Shopfloor.lnk" }, + { "name": "Defect_Tracker", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\Defect_Tracker.lnk" }, + { "name": "PC-DMIS 2016", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\PC-DMIS 2016.lnk" }, + { "name": "PC-DMIS 2019 R2", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\PC-DMIS 2019 R2.lnk" }, + { "name": "CLM Admin", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\CLM Admin.lnk" }, + { "name": "goCMM", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\goCMM.lnk" } ], "desktopApps": [ - { "name": "WJ Shopfloor", "kind": "existing", "sourceName": "WJ Shopfloor.lnk" }, - { "name": "Defect_Tracker", "kind": "existing", "sourceName": "Defect_Tracker.lnk" } + { "name": "WJ Shopfloor", "kind": "existing", "sourceName": "WJ Shopfloor.lnk" }, + { "name": "Defect_Tracker", "kind": "existing", "sourceName": "Defect_Tracker.lnk" }, + { "name": "PC-DMIS 2016", "kind": "exe", "exePath": "C:\\Program Files\\Hexagon\\PC-DMIS 2016.0 64-bit\\PCDLRN.exe" }, + { "name": "PC-DMIS 2019 R2", "kind": "exe", "exePath": "C:\\Program Files\\Hexagon\\PC-DMIS 2019 R2 64-bit\\PCDLRN.exe" }, + { "name": "CLM Admin", "kind": "exe", "exePath": "C:\\Program Files\\Hexagon\\CLM Admin 1.8 64-bit\\clmadmin.exe" }, + { "name": "goCMM", "kind": "exe", "exePath": "C:\\Program Files (x86)\\General Electric\\goCMM\\goCMM.exe" } ], "edgeHomepage": "http://tsgwp00524.logon.ds.ge.com/", "edgeStartupTabs": [ diff --git a/playbook/startnet.cmd b/playbook/startnet.cmd index 003c05b..6cbcfdf 100644 --- a/playbook/startnet.cmd +++ b/playbook/startnet.cmd @@ -323,7 +323,7 @@ if exist "Y:\preinstall\preinstall.json" ( 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 01-Setup-CMM.ps1 can install from local disk. +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 logon- diff --git a/startnet-template.cmd b/startnet-template.cmd index 003c05b..6cbcfdf 100644 --- a/startnet-template.cmd +++ b/startnet-template.cmd @@ -323,7 +323,7 @@ if exist "Y:\preinstall\preinstall.json" ( 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 01-Setup-CMM.ps1 can install from local disk. +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 logon-