Extract site-specific values to site-config.json

New site-config.json file at C:\Enrollment\ (staged by startnet.cmd from
the enrollment share) contains all West Jefferson-specific values that were
previously hardcoded across 7 scripts. To deploy at a different GE site,
clone site-config.json and change the values - scripts need zero changes.

Config schema (v1.0):
  siteName / siteNameCompact  - UDC/eDNC site args
  urls{}                      - Edge startup tab fallback URLs
  edgeStartupTabs[]           - ordered tab list with .url file basenames
  opentext{}                  - excluded .hep profiles and .lnk shortcuts
  startupItems[]              - Configure-PC toggle list (exe/existing/url)
  taskbarPins[]               - 07-TaskbarLayout pin order with lnk paths
  desktopApps[]               - 06-OrganizeDesktop Phase 2 app list

Every script uses the same inline Get-SiteConfig helper that reads the
JSON and returns $null if missing/corrupt. All consumers fall back to the
current hardcoded West Jefferson defaults when $siteConfig is null, so
PXE servers without a site-config.json continue working identically.

Scripts updated:
  06-OrganizeDesktop.ps1   - desktopApps array from config
  07-TaskbarLayout.ps1     - pinSpec array from config
  08-EdgeDefaultBrowser.ps1 - startup tab loop from config
  Configure-PC.ps1         - startup items + site name from config
  Check-MachineNumber.ps1  - site name from config
  Set-MachineNumber.ps1    - site name from config
  01-eDNC.ps1              - siteName + siteNameCompact from config
  startnet.cmd             - copies site-config.json from enrollment share

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-04-10 11:11:35 -04:00
parent 45ff163eea
commit 0aaf049942
9 changed files with 379 additions and 122 deletions

View File

@@ -46,6 +46,21 @@ if (-not $isAdmin) {
exit 1
}
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
$publicDesktop = 'C:\Users\Public\Desktop'
$shopfloorToolsDir = Join-Path $publicDesktop 'Shopfloor Tools'
$scriptPath = $MyInvocation.MyCommand.Path
@@ -277,13 +292,22 @@ function Add-ShopfloorToolsApps {
#
# Kind = 'exe' -> build a fresh .lnk from ExePath
# Kind = 'existing' -> copy an existing .lnk via Find-ExistingLnk
$apps = @(
@{ Name = 'UDC'; Kind = 'exe'; ExePath = 'C:\Program Files\UDC\UDC.exe' }
@{ Name = 'eDNC'; Kind = 'exe'; ExePath = 'C:\Program Files (x86)\Dnc\bin\DncMain.exe' }
@{ Name = 'NTLARS'; Kind = 'exe'; ExePath = 'C:\Program Files (x86)\Dnc\Common\NTLARS.exe' }
@{ Name = 'WJ Shopfloor'; Kind = 'existing'; SourceName = 'WJ Shopfloor.lnk' }
@{ Name = 'Defect_Tracker'; Kind = 'existing'; SourceName = 'Defect_Tracker.lnk' }
)
if ($siteConfig -and $siteConfig.desktopApps) {
$apps = @($siteConfig.desktopApps | ForEach-Object {
$entry = @{ Name = $_.name; Kind = $_.kind }
if ($_.kind -eq 'exe') { $entry.ExePath = $_.exePath }
if ($_.kind -eq 'existing') { $entry.SourceName = $_.sourceName }
$entry
})
} else {
$apps = @(
@{ Name = 'UDC'; Kind = 'exe'; ExePath = 'C:\Program Files\UDC\UDC.exe' }
@{ Name = 'eDNC'; Kind = 'exe'; ExePath = 'C:\Program Files (x86)\Dnc\bin\DncMain.exe' }
@{ Name = 'NTLARS'; Kind = 'exe'; ExePath = 'C:\Program Files (x86)\Dnc\Common\NTLARS.exe' }
@{ Name = 'WJ Shopfloor'; Kind = 'existing'; SourceName = 'WJ Shopfloor.lnk' }
@{ Name = 'Defect_Tracker'; Kind = 'existing'; SourceName = 'Defect_Tracker.lnk' }
)
}
# Lazy folder creation - only create Shopfloor Tools\ the first time
# we have an app that's actually going to land in it. PC types with

View File

@@ -30,6 +30,21 @@ if (-not $isAdmin) {
exit 1
}
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
$publicDesktop = 'C:\Users\Public\Desktop'
$shopfloorToolsDir = Join-Path $publicDesktop 'Shopfloor Tools'
$defaultUserShell = 'C:\Users\Default\AppData\Local\Microsoft\Windows\Shell'
@@ -42,40 +57,48 @@ $layoutXmlPath = Join-Path $defaultUserShell 'LayoutModification.xml'
# it; all other entries reference C:\Users\Public\Desktop\Shopfloor Tools\
# which 06-OrganizeDesktop.ps1 populates.
# ============================================================================
$pinSpec = @(
@{
Name = 'Microsoft Edge'
Path = '%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk'
# Resolved literal path used to check existence (can't Test-Path an
# unexpanded env var reliably on older PS versions)
Literal = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk'
}
@{
Name = 'WJ Shopfloor'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\WJ Shopfloor.lnk'
Literal = (Join-Path $shopfloorToolsDir 'WJ Shopfloor.lnk')
}
@{
Name = 'UDC'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\UDC.lnk'
Literal = (Join-Path $shopfloorToolsDir 'UDC.lnk')
}
@{
Name = 'eDNC'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\eDNC.lnk'
Literal = (Join-Path $shopfloorToolsDir 'eDNC.lnk')
}
@{
Name = 'NTLARS'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\NTLARS.lnk'
Literal = (Join-Path $shopfloorToolsDir 'NTLARS.lnk')
}
@{
Name = 'Defect_Tracker'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\Defect_Tracker.lnk'
Literal = (Join-Path $shopfloorToolsDir 'Defect_Tracker.lnk')
}
)
if ($siteConfig -and $siteConfig.taskbarPins) {
$pinSpec = @($siteConfig.taskbarPins | ForEach-Object {
@{
Name = $_.name
Path = $_.lnkPath
Literal = [Environment]::ExpandEnvironmentVariables($_.lnkPath)
}
})
} else {
$pinSpec = @(
@{
Name = 'Microsoft Edge'
Path = '%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk'
Literal = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Edge.lnk'
}
@{
Name = 'WJ Shopfloor'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\WJ Shopfloor.lnk'
Literal = (Join-Path $shopfloorToolsDir 'WJ Shopfloor.lnk')
}
@{
Name = 'UDC'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\UDC.lnk'
Literal = (Join-Path $shopfloorToolsDir 'UDC.lnk')
}
@{
Name = 'eDNC'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\eDNC.lnk'
Literal = (Join-Path $shopfloorToolsDir 'eDNC.lnk')
}
@{
Name = 'NTLARS'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\NTLARS.lnk'
Literal = (Join-Path $shopfloorToolsDir 'NTLARS.lnk')
}
@{
Name = 'Defect_Tracker'
Path = '%PUBLIC%\Desktop\Shopfloor Tools\Defect_Tracker.lnk'
Literal = (Join-Path $shopfloorToolsDir 'Defect_Tracker.lnk')
}
)
}
# ============================================================================
# Build the pin list - skip any whose .lnk is missing

View File

@@ -53,6 +53,21 @@ if (-not $isAdmin) {
exit 1
}
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
# ----------------------------------------------------------------------------
# Sanity: Edge must be installed for this to mean anything
# ----------------------------------------------------------------------------
@@ -196,14 +211,22 @@ function Resolve-StartupUrl {
# Tab order as requested: Plant Apps, Shop Floor Homepage, Shopfloor Dashboard
$startupTabs = @()
$plantApps = Resolve-StartupUrl -BaseName 'Plant Apps' -Fallback 'https://mes-wjefferson.apps.lr.geaerospace.net/run/?app_name=Plant%20Applications'
if ($plantApps) { $startupTabs += $plantApps }
if ($siteConfig -and $siteConfig.edgeStartupTabs) {
foreach ($tab in $siteConfig.edgeStartupTabs) {
$fallback = if ($tab.fallbackUrlKey -and $siteConfig.urls) { $siteConfig.urls.$($tab.fallbackUrlKey) } else { '' }
$url = Resolve-StartupUrl -BaseName $tab.baseName -Fallback $fallback
if ($url) { $startupTabs += $url }
}
} else {
$plantApps = Resolve-StartupUrl -BaseName 'Plant Apps' -Fallback 'https://mes-wjefferson.apps.lr.geaerospace.net/run/?app_name=Plant%20Applications'
if ($plantApps) { $startupTabs += $plantApps }
$shopFloorHome = Resolve-StartupUrl -BaseName 'WJ Shop Floor Homepage' -Fallback 'http://tsgwp00524.logon.ds.ge.com/'
if ($shopFloorHome) { $startupTabs += $shopFloorHome }
$shopFloorHome = Resolve-StartupUrl -BaseName 'WJ Shop Floor Homepage' -Fallback 'http://tsgwp00524.logon.ds.ge.com/'
if ($shopFloorHome) { $startupTabs += $shopFloorHome }
$dashboard = Resolve-StartupUrl -BaseName 'Shopfloor Dashboard' -Fallback 'https://tsgwp00525.wjs.geaerospace.net/shopdb/shopfloor-dashboard/'
if ($dashboard) { $startupTabs += $dashboard }
$dashboard = Resolve-StartupUrl -BaseName 'Shopfloor Dashboard' -Fallback 'https://tsgwp00525.wjs.geaerospace.net/shopdb/shopfloor-dashboard/'
if ($dashboard) { $startupTabs += $dashboard }
}
if ($startupTabs.Count -eq 0) {
Write-Warning "No startup tab URLs resolved - skipping Edge startup config."

View File

@@ -20,6 +20,21 @@ 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
Add-Type -AssemblyName Microsoft.VisualBasic
Add-Type -AssemblyName System.Windows.Forms
@@ -27,7 +42,7 @@ $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 = 'West Jefferson'
$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' }
# --- Read current values ---
$currentUdc = $null

View File

@@ -28,6 +28,21 @@ Write-Host "Transcript: $transcriptPath"
Write-Host "Started: $(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
$startupDir = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup'
$publicDesktop = 'C:\Users\Public\Desktop'
@@ -119,82 +134,147 @@ $edgePath = @(
# Startup item definitions
# ============================================================================
$items = @(
@{
Num = 1
Label = 'UDC'
Detail = 'UDC.exe'
Available = (Test-Path 'C:\Program Files\UDC\UDC.exe')
CreateLnk = {
return (New-StartupLnk -Name 'UDC' -Target 'C:\Program Files\UDC\UDC.exe')
}
}
@{
Num = 2
Label = 'eDNC'
Detail = 'DncMain.exe'
Available = (Test-Path 'C:\Program Files (x86)\Dnc\bin\DncMain.exe')
CreateLnk = {
return (New-StartupLnk -Name 'eDNC' -Target 'C:\Program Files (x86)\Dnc\bin\DncMain.exe')
}
}
@{
Num = 3
Label = 'Defect Tracker'
Detail = 'ClickOnce app'
Available = $true
CreateLnk = {
$src = @(
(Join-Path $publicDesktop 'Defect_Tracker.lnk'),
(Join-Path (Join-Path $publicDesktop 'Shopfloor Tools') 'Defect_Tracker.lnk')
) | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1
if ($src) {
$dst = Join-Path $startupDir 'Defect Tracker.lnk'
try { Copy-Item -LiteralPath $src -Destination $dst -Force; return $true }
catch { Write-Warning "Failed to copy Defect Tracker: $_"; return $false }
} else {
Write-Warning "Defect_Tracker.lnk not found on desktop"
return $false
if ($siteConfig -and $siteConfig.startupItems) {
$items = @()
$num = 0
foreach ($si in $siteConfig.startupItems) {
$num++
switch ($si.type) {
'exe' {
$target = $si.target
$items += @{
Num = $num
Label = $si.label
Detail = (Split-Path -Leaf $target)
Available = (Test-Path $target)
CreateLnk = [scriptblock]::Create("return (New-StartupLnk -Name '$($si.label)' -Target '$target')")
}
}
'existing' {
$srcLnk = $si.sourceLnk
$label = $si.label
$items += @{
Num = $num
Label = $label
Detail = 'shortcut'
Available = $true
CreateLnk = [scriptblock]::Create(@"
`$src = @(
(Join-Path `$publicDesktop '$srcLnk'),
(Join-Path (Join-Path `$publicDesktop 'Shopfloor Tools') '$srcLnk')
) | Where-Object { Test-Path -LiteralPath `$_ } | Select-Object -First 1
if (`$src) {
`$dst = Join-Path `$startupDir '$label.lnk'
try { Copy-Item -LiteralPath `$src -Destination `$dst -Force; return `$true }
catch { Write-Warning "Failed to copy $label`: `$_"; return `$false }
} else {
Write-Warning "$srcLnk not found on desktop"
return `$false
}
"@)
}
}
'url' {
$urlKey = $si.urlKey
$label = $si.label
$fallback = if ($urlKey -and $siteConfig.urls) { $siteConfig.urls.$urlKey } else { '' }
$items += @{
Num = $num
Label = $label
Detail = 'opens in Edge'
Available = [bool]$edgePath
CreateLnk = [scriptblock]::Create(@"
`$fallback = '$fallback'
`$url = Get-UrlFromFile '$label'
if (-not `$url) {
Write-Host " $label .url not found on desktop, using known URL."
`$url = `$fallback
}
Write-Host " URL: `$url"
return (New-StartupLnk -Name '$label' -Target `$edgePath -Arguments "--new-window ```"`$url```"")
"@)
}
}
}
}
@{
Num = 4
Label = 'WJ Shopfloor'
Detail = 'HostExplorer session'
Available = $true
CreateLnk = {
$src = @(
(Join-Path $publicDesktop 'WJ Shopfloor.lnk'),
(Join-Path (Join-Path $publicDesktop 'Shopfloor Tools') 'WJ Shopfloor.lnk')
) | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1
if ($src) {
$dst = Join-Path $startupDir 'WJ Shopfloor.lnk'
try { Copy-Item -LiteralPath $src -Destination $dst -Force; return $true }
catch { Write-Warning "Failed to copy WJ Shopfloor: $_"; return $false }
} else {
Write-Warning "WJ Shopfloor.lnk not found on desktop"
return $false
} else {
$items = @(
@{
Num = 1
Label = 'UDC'
Detail = 'UDC.exe'
Available = (Test-Path 'C:\Program Files\UDC\UDC.exe')
CreateLnk = {
return (New-StartupLnk -Name 'UDC' -Target 'C:\Program Files\UDC\UDC.exe')
}
}
}
@{
Num = 5
Label = 'Plant Apps'
Detail = 'opens in Edge'
Available = [bool]$edgePath
CreateLnk = {
$fallback = 'https://mes-wjefferson.apps.lr.geaerospace.net/run/?app_name=Plant%20Applications'
$url = Get-UrlFromFile 'Plant Apps'
if (-not $url) {
Write-Host " Plant Apps .url not found on desktop, using known URL."
$url = $fallback
@{
Num = 2
Label = 'eDNC'
Detail = 'DncMain.exe'
Available = (Test-Path 'C:\Program Files (x86)\Dnc\bin\DncMain.exe')
CreateLnk = {
return (New-StartupLnk -Name 'eDNC' -Target 'C:\Program Files (x86)\Dnc\bin\DncMain.exe')
}
Write-Host " URL: $url"
return (New-StartupLnk -Name 'Plant Apps' -Target $edgePath -Arguments "--new-window `"$url`"")
}
}
)
@{
Num = 3
Label = 'Defect Tracker'
Detail = 'ClickOnce app'
Available = $true
CreateLnk = {
$src = @(
(Join-Path $publicDesktop 'Defect_Tracker.lnk'),
(Join-Path (Join-Path $publicDesktop 'Shopfloor Tools') 'Defect_Tracker.lnk')
) | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1
if ($src) {
$dst = Join-Path $startupDir 'Defect Tracker.lnk'
try { Copy-Item -LiteralPath $src -Destination $dst -Force; return $true }
catch { Write-Warning "Failed to copy Defect Tracker: $_"; return $false }
} else {
Write-Warning "Defect_Tracker.lnk not found on desktop"
return $false
}
}
}
@{
Num = 4
Label = 'WJ Shopfloor'
Detail = 'HostExplorer session'
Available = $true
CreateLnk = {
$src = @(
(Join-Path $publicDesktop 'WJ Shopfloor.lnk'),
(Join-Path (Join-Path $publicDesktop 'Shopfloor Tools') 'WJ Shopfloor.lnk')
) | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1
if ($src) {
$dst = Join-Path $startupDir 'WJ Shopfloor.lnk'
try { Copy-Item -LiteralPath $src -Destination $dst -Force; return $true }
catch { Write-Warning "Failed to copy WJ Shopfloor: $_"; return $false }
} else {
Write-Warning "WJ Shopfloor.lnk not found on desktop"
return $false
}
}
}
@{
Num = 5
Label = 'Plant Apps'
Detail = 'opens in Edge'
Available = [bool]$edgePath
CreateLnk = {
$fallback = 'https://mes-wjefferson.apps.lr.geaerospace.net/run/?app_name=Plant%20Applications'
$url = Get-UrlFromFile 'Plant Apps'
if (-not $url) {
Write-Host " Plant Apps .url not found on desktop, using known URL."
$url = $fallback
}
Write-Host " URL: $url"
return (New-StartupLnk -Name 'Plant Apps' -Target $edgePath -Arguments "--new-window `"$url`"")
}
}
)
}
# Machine-number logon task is item 6
$machineNumTaskName = 'Check Machine Number'
@@ -255,7 +335,8 @@ if ($needsMachineNumber) {
# Relaunch UDC
if ((Test-Path $udcExePath) -and $updated -contains 'UDC') {
try {
Start-Process -FilePath $udcExePath -ArgumentList @('-site', '"West Jefferson"', '-machine', $newNum)
$site = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' }
Start-Process -FilePath $udcExePath -ArgumentList @('-site', "`"$site`"", '-machine', $newNum)
Write-Host " UDC.exe relaunched."
} catch {}
}