From 7c8eb6899da33d6bb56b2cd27b293a6b3a49b0d9 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Fri, 10 Apr 2026 11:44:10 -0400 Subject: [PATCH] Shared machine-number helper, site-config for OpenText + PreInstall, placeholder type dirs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three optimization batches from the pipeline audit: 1. Shared Update-MachineNumber.ps1 helper (lib/) Extracts duplicated machine-number update logic from Configure-PC.ps1, Check-MachineNumber.ps1, and Set-MachineNumber.ps1 into a shared dot-sourceable helper at Shopfloor/lib/Update-MachineNumber.ps1. Exports: Get-CurrentMachineNumber → @{ Udc = $string; Ednc = $string } Update-MachineNumber -NewNumber [-Site ] → @{ UdcUpdated; EdncUpdated; Errors } All three consumers now dot-source the helper instead of duplicating ~50 lines each. Set-MachineNumber.ps1 also migrated from inline Get-SiteConfig to dot-sourcing Get-PCProfile.ps1 for consistency. 2. Site-config integration for remaining scripts Setup-OpenText.ps1: exclude lists (profiles + shortcuts) now read from site-config.json opentext section, falling back to West Jefferson defaults. Inline Get-SiteConfig since the script runs from C:\PreInstall\installers\opentext\ (can't dot-source Get-PCProfile). 00-PreInstall-MachineApps.ps1: after parsing preinstall.json, scans InstallArgs for "West Jefferson" and replaces with site-config siteName if different. Inline Get-SiteConfig for same reason. 3. Placeholder type-specific directories Created skeleton 01-Setup-*.ps1 scripts for all PC types so the directory structure is in place and Run-ShopfloorSetup's type-specific loop has something to iterate over: Genspect/01-Setup-Genspect.ps1 Keyence/01-Setup-Keyence.ps1 WaxAndTrace/01-Setup-WaxAndTrace.ps1 Lab/01-Setup-Lab.ps1 Each logs a "no type-specific apps configured yet" banner and exits. Fill in app installs when details are finalized; for share-based installs, copy the CMM/01-Setup-CMM.ps1 pattern. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../preinstall/opentext/Setup-OpenText.ps1 | 56 +++++---- .../Genspect/01-Setup-Genspect.ps1 | 26 ++-- .../Keyence/01-Setup-Keyence.ps1 | 26 ++-- playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 | 12 ++ .../Shopfloor/00-PreInstall-MachineApps.ps1 | 27 +++++ .../Shopfloor/Check-MachineNumber.ps1 | 81 ++----------- .../Shopfloor/Configure-PC.ps1 | 68 +++-------- .../Shopfloor/lib/Update-MachineNumber.ps1 | 103 ++++++++++++++++ .../Standard/Set-MachineNumber.ps1 | 111 ++++-------------- .../WaxAndTrace/01-Setup-WaxAndTrace.ps1 | 26 ++-- 10 files changed, 262 insertions(+), 274 deletions(-) create mode 100644 playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 create mode 100644 playbook/shopfloor-setup/Shopfloor/lib/Update-MachineNumber.ps1 diff --git a/playbook/preinstall/opentext/Setup-OpenText.ps1 b/playbook/preinstall/opentext/Setup-OpenText.ps1 index e71b5e4..16abdf2 100644 --- a/playbook/preinstall/opentext/Setup-OpenText.ps1 +++ b/playbook/preinstall/opentext/Setup-OpenText.ps1 @@ -41,6 +41,18 @@ if (-not $SourceDir) { $SourceDir = $PSScriptRoot } +# --- Inline site-config reader (this script runs from C:\PreInstall\installers\opentext\, +# NOT from C:\Enrollment\shopfloor-setup\, so it can't dot-source Get-PCProfile.ps1) --- +function Get-SiteConfig { + $configPath = 'C:\Enrollment\site-config.json' + if (-not (Test-Path $configPath)) { return $null } + try { + return Get-Content $configPath -Raw | ConvertFrom-Json + } catch { + return $null + } +} + # --- Logging (set up FIRST so any startup error - missing version.txt, broken # bundled file, etc. - lands in the log file instead of disappearing into the # runner's stdout void) --- @@ -201,6 +213,25 @@ if ($mspExit -ne 0 -and $mspExit -ne 3010) { Write-SetupLog "" Write-SetupLog "Step 3: Deploying profiles/keymaps/menus/macros..." +# --- Resolve exclude lists from site-config.json (falls back to West Jefferson defaults) --- +$siteConfig = Get-SiteConfig +$profileExcludes = if ($siteConfig -and $siteConfig.opentext -and $siteConfig.opentext.excludeProfiles) { + @($siteConfig.opentext.excludeProfiles) +} else { + @('WJ_Office.hep', 'IBM_qks.hep', 'mmcs.hep') # West Jefferson defaults +} +$shortcutExcludes = if ($siteConfig -and $siteConfig.opentext -and $siteConfig.opentext.excludeShortcuts) { + @($siteConfig.opentext.excludeShortcuts) +} else { + @('WJ_Office.lnk', 'IBM_qks.lnk', 'mmcs.lnk') +} +if ($siteConfig) { + Write-SetupLog "Site config loaded - profile excludes: $($profileExcludes -join ', ')" + Write-SetupLog "Site config loaded - shortcut excludes: $($shortcutExcludes -join ', ')" +} else { + Write-SetupLog "No site-config.json found - using West Jefferson defaults for excludes" +} + # Map of source subdir -> destination subdir relative to the Hummingbird root. # Optional Exclude list drops specific filenames from both the source-to-dest # copy AND from the destination if they were left over from a prior install. @@ -208,15 +239,7 @@ $contentMap = @( @{ Src = 'Profile' Dst = 'Profile' - # West Jefferson site-specific: these three .hep sessions aren't used - # on shopfloor PCs and just clutter the HostExplorer session picker. - # Leaving the .hep files in the bundled source for rollback, just - # skipping the deploy step. - Exclude = @( - 'WJ_Office.hep', - 'IBM_qks.hep', - 'mmcs.hep' - ) + Exclude = $profileExcludes } @{ Src = 'Accessories\EB'; Dst = 'Accessories\EB' } @{ Src = 'HostExplorer\Keymap'; Dst = 'HostExplorer\Keymap' } @@ -280,22 +303,15 @@ foreach ($u in $userDirs) { } # --- Step 4: Public Desktop shortcuts --- -# Same exclusion list as the Profile step: these three sessions aren't -# used on shopfloor PCs, so we skip deploying their .lnk files AND -# remove any that a prior install left behind. +# Uses $shortcutExcludes (resolved from site-config.json above) to skip +# deploying unwanted .lnk files AND remove any a prior install left behind. Write-SetupLog "" Write-SetupLog "Step 4: Deploying public desktop shortcuts..." $shortcutSrc = Join-Path $SourceDir 'W10shortcuts' $publicDesktop = 'C:\Users\Public\Desktop' -$excludeShortcuts = @( - 'WJ_Office.lnk', - 'IBM_qks.lnk', - 'mmcs.lnk' -) - # Clean up stale copies from prior installs first -foreach ($name in $excludeShortcuts) { +foreach ($name in $shortcutExcludes) { $stale = Join-Path $publicDesktop $name if (Test-Path -LiteralPath $stale) { try { @@ -310,7 +326,7 @@ foreach ($name in $excludeShortcuts) { if (Test-Path $shortcutSrc) { $lnkFiles = Get-ChildItem -Path $shortcutSrc -Filter '*.lnk' -File -ErrorAction SilentlyContinue foreach ($l in $lnkFiles) { - if ($excludeShortcuts -contains $l.Name) { + if ($shortcutExcludes -contains $l.Name) { Write-SetupLog " skip (excluded): $($l.Name)" continue } diff --git a/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 b/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 index d5a7010..016879a 100644 --- a/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 +++ b/playbook/shopfloor-setup/Genspect/01-Setup-Genspect.ps1 @@ -1,14 +1,12 @@ -# 01-Setup-Genspect.ps1 — Genspect-specific setup (runs after Shopfloor baseline) - -Write-Host "=== Genspect Setup ===" - -# --- Add Genspect credentials --- -# cmdkey /generic:genspect-server /user:domain\genspectuser /pass:password - -# --- Install Genspect applications --- -# Start-Process msiexec.exe -ArgumentList '/i "C:\Enrollment\shopfloor-setup\Genspect\GenspectApp.msi" /qn' -Wait - -# --- Genspect configuration --- -# Set-ItemProperty -Path "HKLM:\SOFTWARE\CompanyName" -Name "PCType" -Value "Genspect" - -Write-Host "=== Genspect Setup Complete ===" +# 01-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 +# (credential lookup + share mount + install from share). + +Write-Host "=== Genspect Setup ===" +Write-Host " (no type-specific apps configured yet)" +Write-Host "=== Genspect Setup Complete ===" diff --git a/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 b/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 index 1377245..d49c6ec 100644 --- a/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 +++ b/playbook/shopfloor-setup/Keyence/01-Setup-Keyence.ps1 @@ -1,14 +1,12 @@ -# 01-Setup-Keyence.ps1 — Keyence-specific setup (runs after Shopfloor baseline) - -Write-Host "=== Keyence Setup ===" - -# --- Add Keyence credentials --- -# cmdkey /generic:keyence-server /user:domain\keyenceuser /pass:password - -# --- Install Keyence applications --- -# Start-Process msiexec.exe -ArgumentList '/i "C:\Enrollment\shopfloor-setup\Keyence\KeyenceApp.msi" /qn' -Wait - -# --- Keyence configuration --- -# Set-ItemProperty -Path "HKLM:\SOFTWARE\CompanyName" -Name "PCType" -Value "Keyence" - -Write-Host "=== Keyence Setup Complete ===" +# 01-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 +# (credential lookup + share mount + install from share). + +Write-Host "=== Keyence Setup ===" +Write-Host " (no type-specific apps configured yet)" +Write-Host "=== Keyence Setup Complete ===" diff --git a/playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 b/playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 new file mode 100644 index 0000000..53f3fe4 --- /dev/null +++ b/playbook/shopfloor-setup/Lab/01-Setup-Lab.ps1 @@ -0,0 +1,12 @@ +# 01-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 +# (credential lookup + share mount + install from share). + +Write-Host "=== Lab Setup ===" +Write-Host " (no type-specific apps configured yet)" +Write-Host "=== Lab Setup Complete ===" diff --git a/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 b/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 index 2c72959..6111719 100644 --- a/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/00-PreInstall-MachineApps.ps1 @@ -17,6 +17,19 @@ $installerDir = Join-Path $preInstallDir "installers" $logDir = "C:\Logs\PreInstall" $logFile = Join-Path $logDir "install.log" +# --- Inline site-config reader (same pattern as Setup-OpenText.ps1; this script +# runs from C:\Enrollment\shopfloor-setup\Shopfloor\ but Get-PCProfile.ps1 may +# not be available yet, so keep the lookup self-contained) --- +function Get-SiteConfig { + $configPath = 'C:\Enrollment\site-config.json' + if (-not (Test-Path $configPath)) { return $null } + try { + return Get-Content $configPath -Raw | ConvertFrom-Json + } catch { + return $null + } +} + # --- Setup logging --- # IMPORTANT: do NOT wipe the log on each run. The runner can get killed by an # installer-triggered reboot mid-execution. On the next autologon, the dispatcher @@ -102,6 +115,20 @@ if (-not $config.Applications) { Write-PreInstallLog "Staged installer dir: $installerDir" Write-PreInstallLog "Found $($config.Applications.Count) app entries in preinstall.json" +# --- Site-name override: replace "West Jefferson" in InstallArgs if site-config says otherwise --- +$siteConfig = Get-SiteConfig +if ($siteConfig -and $siteConfig.siteName -and $siteConfig.siteName -ne 'West Jefferson') { + Write-PreInstallLog "Site config loaded - siteName: $($siteConfig.siteName)" + foreach ($app in $config.Applications) { + if ($app.InstallArgs -and $app.InstallArgs -match 'West Jefferson') { + $app.InstallArgs = $app.InstallArgs -replace 'West Jefferson', $siteConfig.siteName + Write-PreInstallLog " Overrode site name in $($app.Name) args: $($app.InstallArgs)" + } + } +} else { + Write-PreInstallLog "No site-config override for siteName (using defaults in preinstall.json)" +} + # --- Detection helper (mirrors Simple-Install.ps1's Test-ApplicationInstalled) --- function Test-AppInstalled { param($App) diff --git a/playbook/shopfloor-setup/Shopfloor/Check-MachineNumber.ps1 b/playbook/shopfloor-setup/Shopfloor/Check-MachineNumber.ps1 index e72362a..26fe439 100644 --- a/playbook/shopfloor-setup/Shopfloor/Check-MachineNumber.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/Check-MachineNumber.ps1 @@ -20,46 +20,19 @@ try { Start-Transcript -Path $transcriptPath -Append -Force | Out-Null } catch { Write-Host "Check-MachineNumber.ps1 starting $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Write-Host "Running as: $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" -function Get-SiteConfig { - $configPath = 'C:\Enrollment\site-config.json' - if (-not (Test-Path -LiteralPath $configPath)) { - Write-Host "site-config.json not found - using defaults" -ForegroundColor DarkGray - return $null - } - try { - return (Get-Content -LiteralPath $configPath -Raw -ErrorAction Stop | ConvertFrom-Json) - } catch { - Write-Warning "Failed to parse site-config.json: $_" - return $null - } -} -$siteConfig = Get-SiteConfig +. "$PSScriptRoot\lib\Get-PCProfile.ps1" +. "$PSScriptRoot\lib\Update-MachineNumber.ps1" Add-Type -AssemblyName Microsoft.VisualBasic Add-Type -AssemblyName System.Windows.Forms -$taskName = 'Check Machine Number' -$udcSettingsPath = 'C:\ProgramData\UDC\udc_settings.json' -$udcExePath = 'C:\Program Files\UDC\UDC.exe' -$ednRegPath = 'HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC\General' -$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } +$taskName = 'Check Machine Number' +$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } # --- Read current values --- -$currentUdc = $null -$currentEdnc = $null - -if (Test-Path $udcSettingsPath) { - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $currentUdc = $json.GeneralSettings.MachineNumber - } catch {} -} - -if (Test-Path $ednRegPath) { - try { - $currentEdnc = (Get-ItemProperty -Path $ednRegPath -Name MachineNo -ErrorAction Stop).MachineNo - } catch {} -} +$currentMN = Get-CurrentMachineNumber +$currentUdc = $currentMN.Udc +$currentEdnc = $currentMN.Ednc # --- Check if placeholder --- Write-Host "UDC machine number: $(if ($currentUdc) { $currentUdc } else { '(not found)' })" @@ -111,41 +84,13 @@ if ($new -notmatch '^\d+$') { exit 0 } -# --- Update UDC --- +# --- Update via shared helper --- +$mnResult = Update-MachineNumber -NewNumber $new -Site $site + $results = @() -if (Test-Path $udcSettingsPath) { - # Stop UDC first - Get-Process UDC -ErrorAction SilentlyContinue | ForEach-Object { - try { $_.Kill(); $_.WaitForExit(5000) | Out-Null } catch {} - } - Start-Sleep -Seconds 1 - - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $json.GeneralSettings.MachineNumber = $new - $json | ConvertTo-Json -Depth 99 | Set-Content -Path $udcSettingsPath -Encoding UTF8 - $results += "UDC updated to $new" - } catch { - $results += "UDC FAILED: $_" - } -} - -# --- Update eDNC --- -if (Test-Path $ednRegPath) { - try { - Set-ItemProperty -Path $ednRegPath -Name MachineNo -Value $new -Type String -Force - $results += "eDNC updated to $new" - } catch { - $results += "eDNC FAILED: $_" - } -} - -# --- Relaunch UDC --- -if (Test-Path $udcExePath) { - try { - Start-Process -FilePath $udcExePath -ArgumentList @('-site', "`"$site`"", '-machine', $new) - } catch {} -} +if ($mnResult.UdcUpdated) { $results += "UDC updated to $new" } +if ($mnResult.EdncUpdated) { $results += "eDNC updated to $new" } +foreach ($err in $mnResult.Errors) { $results += $err -replace '^', 'FAILED: ' } # --- Show result --- $summary = ($results -join "`n") + "`n`nTo apply eDNC changes, restart any running DncMain.exe." diff --git a/playbook/shopfloor-setup/Shopfloor/Configure-PC.ps1 b/playbook/shopfloor-setup/Shopfloor/Configure-PC.ps1 index c987aa2..dc9cf85 100644 --- a/playbook/shopfloor-setup/Shopfloor/Configure-PC.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/Configure-PC.ps1 @@ -31,6 +31,7 @@ Write-Host "Running as: $([System.Security.Principal.WindowsIdentity]::GetCurren # Load site config + PC profile (resolves pc-type.txt + pc-subtype.txt # into a profile from site-config.json's pcProfiles section) . "$PSScriptRoot\lib\Get-PCProfile.ps1" +. "$PSScriptRoot\lib\Update-MachineNumber.ps1" $startupDir = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup' $publicDesktop = 'C:\Users\Public\Desktop' @@ -88,25 +89,9 @@ function New-StartupLnk { # Machine number - read current state # ============================================================================ -$udcSettingsPath = 'C:\ProgramData\UDC\udc_settings.json' -$udcExePath = 'C:\Program Files\UDC\UDC.exe' -$ednRegPath = 'HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC\General' - -$currentUdc = $null -$currentEdnc = $null - -if (Test-Path $udcSettingsPath) { - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $currentUdc = $json.GeneralSettings.MachineNumber - } catch {} -} - -if (Test-Path $ednRegPath) { - try { - $currentEdnc = (Get-ItemProperty -Path $ednRegPath -Name MachineNo -ErrorAction Stop).MachineNo - } catch {} -} +$currentMN = Get-CurrentMachineNumber +$currentUdc = $currentMN.Udc +$currentEdnc = $currentMN.Ednc $needsMachineNumber = ($currentUdc -eq '9999' -or $currentEdnc -eq '9999') @@ -296,44 +281,19 @@ if ($needsMachineNumber) { $newNum = $newNum.Trim() if ($newNum -and $newNum -match '^\d+$') { - $updated = @() + $site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } + $mnResult = Update-MachineNumber -NewNumber $newNum -Site $site - # Stop UDC before editing its JSON - Get-Process UDC -ErrorAction SilentlyContinue | ForEach-Object { - try { $_.Kill(); $_.WaitForExit(5000) | Out-Null } catch {} + if ($mnResult.UdcUpdated) { + Write-Host " UDC : $currentUdc -> $newNum" -ForegroundColor Green + $currentUdc = $newNum } - Start-Sleep -Seconds 1 - - # UDC JSON - if (Test-Path $udcSettingsPath) { - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $json.GeneralSettings.MachineNumber = $newNum - $json | ConvertTo-Json -Depth 99 | Set-Content -Path $udcSettingsPath -Encoding UTF8 - Write-Host " UDC : $currentUdc -> $newNum" -ForegroundColor Green - $updated += 'UDC' - $currentUdc = $newNum - } catch { Write-Warning " UDC update failed: $_" } - } - - # eDNC registry - if (Test-Path $ednRegPath) { - try { - Set-ItemProperty -Path $ednRegPath -Name MachineNo -Value $newNum -Type String -Force - Write-Host " eDNC : $currentEdnc -> $newNum" -ForegroundColor Green - $updated += 'eDNC' - $currentEdnc = $newNum - } catch { Write-Warning " eDNC update failed: $_" } - } - - # Relaunch UDC - if ((Test-Path $udcExePath) -and $updated -contains 'UDC') { - try { - $site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } - Start-Process -FilePath $udcExePath -ArgumentList @('-site', "`"$site`"", '-machine', $newNum) - Write-Host " UDC.exe relaunched." - } catch {} + if ($mnResult.EdncUpdated) { + Write-Host " eDNC : $currentEdnc -> $newNum" -ForegroundColor Green + $currentEdnc = $newNum } + foreach ($err in $mnResult.Errors) { Write-Warning " $err" } + if ($mnResult.UdcUpdated) { Write-Host " UDC.exe relaunched." } $needsMachineNumber = ($currentUdc -eq '9999' -or $currentEdnc -eq '9999') } elseif ($newNum) { diff --git a/playbook/shopfloor-setup/Shopfloor/lib/Update-MachineNumber.ps1 b/playbook/shopfloor-setup/Shopfloor/lib/Update-MachineNumber.ps1 new file mode 100644 index 0000000..fedee2c --- /dev/null +++ b/playbook/shopfloor-setup/Shopfloor/lib/Update-MachineNumber.ps1 @@ -0,0 +1,103 @@ +# Update-MachineNumber.ps1 - Shared helper for reading and updating the +# machine number in UDC and eDNC. Dot-source from any script that needs +# machine-number operations: +# +# . "$PSScriptRoot\lib\Update-MachineNumber.ps1" (from Shopfloor\ scripts) +# . "$PSScriptRoot\..\Shopfloor\lib\Update-MachineNumber.ps1" (from Standard\ scripts) +# . "$PSScriptRoot\Update-MachineNumber.ps1" (from lib\ scripts) +# +# Exported functions: +# Get-CurrentMachineNumber - returns @{ Udc = $string_or_null; Ednc = $string_or_null } +# Update-MachineNumber - updates both, returns @{ UdcUpdated = $bool; EdncUpdated = $bool; Errors = @() } +# +# Both handle missing files/keys gracefully (app not installed = skip, not error). + +$script:UdcSettingsPath = 'C:\ProgramData\UDC\udc_settings.json' +$script:UdcExePath = 'C:\Program Files\UDC\UDC.exe' +$script:EdncRegPath = 'HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC\General' + +function Get-CurrentMachineNumber { + <# + .SYNOPSIS + Reads the current machine number from UDC settings JSON and eDNC registry. + .OUTPUTS + Hashtable with keys Udc ($string or $null) and Ednc ($string or $null). + #> + $result = @{ Udc = $null; Ednc = $null } + + if (Test-Path $script:UdcSettingsPath) { + try { + $json = Get-Content $script:UdcSettingsPath -Raw | ConvertFrom-Json + $result.Udc = $json.GeneralSettings.MachineNumber + } catch {} + } + + if (Test-Path $script:EdncRegPath) { + try { + $result.Ednc = (Get-ItemProperty -Path $script:EdncRegPath -Name MachineNo -ErrorAction Stop).MachineNo + } catch {} + } + + return $result +} + +function Update-MachineNumber { + <# + .SYNOPSIS + Updates UDC + eDNC machine number in one step. Stops UDC before writing, + relaunches after. + .PARAMETER NewNumber + The new machine number (digits only - caller validates). + .PARAMETER Site + Site name passed to UDC.exe -site argument. Defaults to 'West Jefferson'. + .OUTPUTS + Hashtable: @{ UdcUpdated = $bool; EdncUpdated = $bool; Errors = @() } + #> + param( + [Parameter(Mandatory)] + [string]$NewNumber, + + [string]$Site = 'West Jefferson' + ) + + $out = @{ UdcUpdated = $false; EdncUpdated = $false; Errors = @() } + + # --- Stop UDC before editing its JSON (avoid stale shutdown write) --- + Get-Process UDC -ErrorAction SilentlyContinue | ForEach-Object { + try { $_.Kill(); $_.WaitForExit(5000) | Out-Null } catch {} + } + Start-Sleep -Seconds 1 + + # --- Update UDC settings JSON --- + if (Test-Path $script:UdcSettingsPath) { + try { + $json = Get-Content $script:UdcSettingsPath -Raw | ConvertFrom-Json + $json.GeneralSettings.MachineNumber = $NewNumber + $json | ConvertTo-Json -Depth 99 | Set-Content -Path $script:UdcSettingsPath -Encoding UTF8 + $out.UdcUpdated = $true + } catch { + $out.Errors += "UDC update failed: $_" + } + } + + # --- Update eDNC registry --- + if (Test-Path $script:EdncRegPath) { + try { + Set-ItemProperty -Path $script:EdncRegPath -Name MachineNo -Value $NewNumber -Type String -Force + $out.EdncUpdated = $true + } catch { + $out.Errors += "eDNC update failed: $_" + } + } + + # --- Relaunch UDC with new args --- + if ((Test-Path $script:UdcExePath) -and $out.UdcUpdated) { + try { + Start-Process -FilePath $script:UdcExePath -ArgumentList @('-site', "`"$Site`"", '-machine', $NewNumber) + } catch { + $out.Errors += "UDC relaunch failed: $_" + } + } + + return $out +} diff --git a/playbook/shopfloor-setup/Standard/Set-MachineNumber.ps1 b/playbook/shopfloor-setup/Standard/Set-MachineNumber.ps1 index 4372de9..9625ba0 100644 --- a/playbook/shopfloor-setup/Standard/Set-MachineNumber.ps1 +++ b/playbook/shopfloor-setup/Standard/Set-MachineNumber.ps1 @@ -18,46 +18,15 @@ Add-Type -AssemblyName Microsoft.VisualBasic Add-Type -AssemblyName System.Windows.Forms -function Get-SiteConfig { - $configPath = 'C:\Enrollment\site-config.json' - if (-not (Test-Path -LiteralPath $configPath)) { - Write-Host "site-config.json not found - using defaults" -ForegroundColor DarkGray - return $null - } - try { - return (Get-Content -LiteralPath $configPath -Raw -ErrorAction Stop | ConvertFrom-Json) - } catch { - Write-Warning "Failed to parse site-config.json: $_" - return $null - } -} -$siteConfig = Get-SiteConfig +. "$PSScriptRoot\..\Shopfloor\lib\Get-PCProfile.ps1" +. "$PSScriptRoot\..\Shopfloor\lib\Update-MachineNumber.ps1" -$udcSettingsPath = "C:\ProgramData\UDC\udc_settings.json" -$udcExePath = "C:\Program Files\UDC\UDC.exe" -$ednRegPath = "HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC\General" -$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } +$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' } # --- Read current values for display --- -$currentUdc = $null -$currentEdnc = $null - -if (Test-Path $udcSettingsPath) { - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $currentUdc = $json.GeneralSettings.MachineNumber - } catch { - $currentUdc = "(unreadable: $_)" - } -} - -if (Test-Path $ednRegPath) { - try { - $currentEdnc = (Get-ItemProperty -Path $ednRegPath -Name MachineNo -ErrorAction Stop).MachineNo - } catch { - $currentEdnc = $null - } -} +$currentMN = Get-CurrentMachineNumber +$currentUdc = $currentMN.Udc +$currentEdnc = $currentMN.Ednc # --- Show prompt with current state --- $promptLines = @() @@ -87,66 +56,28 @@ if ($new -notmatch '^\d+$') { exit 1 } +$mnResult = Update-MachineNumber -NewNumber $new -Site $site + $results = @() - -# --- 1. Stop UDC.exe before editing its JSON (avoid stale shutdown write) --- -$udcProcs = Get-Process UDC -ErrorAction SilentlyContinue -if ($udcProcs) { - Write-Host "Stopping UDC.exe ($($udcProcs.Count) instance(s))..." - $udcProcs | ForEach-Object { - try { - $_.Kill() - $_.WaitForExit(5000) | Out-Null - } catch { - Write-Warning "Failed to stop UDC.exe (PID $($_.Id)): $_" - } - } - Start-Sleep -Seconds 1 -} - -# --- 2. Update UDC settings JSON --- -if (Test-Path $udcSettingsPath) { - try { - $json = Get-Content $udcSettingsPath -Raw | ConvertFrom-Json - $json.GeneralSettings.MachineNumber = $new - $json | ConvertTo-Json -Depth 99 | Set-Content -Path $udcSettingsPath -Encoding UTF8 - Write-Host "UDC: $currentUdc -> $new" - $results += "UDC updated to $new" - } catch { - Write-Warning "Failed to update UDC settings: $_" - $results += "UDC FAILED: $_" - } -} else { - Write-Warning "UDC settings file not found at $udcSettingsPath. Run UDC.exe at least once to initialize." +if ($mnResult.UdcUpdated) { + Write-Host "UDC: $currentUdc -> $new" + $results += "UDC updated to $new" +} elseif (-not (Test-Path 'C:\ProgramData\UDC\udc_settings.json')) { $results += "UDC: settings file missing (run UDC.exe once first)" } - -# --- 3. Update eDNC MachineNo registry value --- -if (Test-Path $ednRegPath) { - try { - Set-ItemProperty -Path $ednRegPath -Name MachineNo -Value $new -Type String -Force - Write-Host "eDNC: $currentEdnc -> $new" - $results += "eDNC updated to $new" - } catch { - Write-Warning "Failed to update eDNC MachineNo: $_" - $results += "eDNC FAILED: $_" - } -} else { - Write-Warning "eDNC registry key not found at $ednRegPath. Is eDNC installed?" +if ($mnResult.EdncUpdated) { + Write-Host "eDNC: $currentEdnc -> $new" + $results += "eDNC updated to $new" +} elseif (-not (Test-Path 'HKLM:\SOFTWARE\WOW6432Node\GE Aircraft Engines\DNC\General')) { $results += "eDNC: registry key missing (eDNC not installed?)" } - -# --- 4. Relaunch UDC.exe with new args (if installed) --- -if (Test-Path $udcExePath) { - try { - Start-Process -FilePath $udcExePath -ArgumentList @("-site", "`"$site`"", "-machine", $new) - Write-Host "UDC.exe relaunched." - } catch { - Write-Warning "Failed to relaunch UDC.exe: $_" - } +foreach ($err in $mnResult.Errors) { + Write-Warning $err + $results += $err } +if ($mnResult.UdcUpdated) { Write-Host "UDC.exe relaunched." } -# --- 5. Show summary --- +# --- Show summary --- $summary = ($results -join "`n") + "`n`nTo apply eDNC changes, restart any running DncMain.exe." [System.Windows.Forms.MessageBox]::Show( $summary, diff --git a/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 b/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 index 3851da3..ca63f6e 100644 --- a/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 +++ b/playbook/shopfloor-setup/WaxAndTrace/01-Setup-WaxAndTrace.ps1 @@ -1,14 +1,12 @@ -# 01-Setup-WaxAndTrace.ps1 — Wax and Trace-specific setup (runs after Shopfloor baseline) - -Write-Host "=== Wax and Trace Setup ===" - -# --- Add Wax and Trace credentials --- -# cmdkey /generic:wax-server /user:domain\waxuser /pass:password - -# --- Install Wax and Trace applications --- -# Start-Process msiexec.exe -ArgumentList '/i "C:\Enrollment\shopfloor-setup\WaxAndTrace\WaxApp.msi" /qn' -Wait - -# --- Wax and Trace configuration --- -# Set-ItemProperty -Path "HKLM:\SOFTWARE\CompanyName" -Name "PCType" -Value "WaxAndTrace" - -Write-Host "=== Wax and Trace Setup Complete ===" +# 01-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 +# (credential lookup + share mount + install from share). + +Write-Host "=== Wax and Trace Setup ===" +Write-Host " (no type-specific apps configured yet)" +Write-Host "=== Wax and Trace Setup Complete ==="