Renumber PXE LAN from 10.9.100.0/24 to 172.16.9.0/24
Single-site bay-stuck issue at WJ: GE Intune Report IP script filters
Get-NetIPAddress on StartsWith("10.") and posts everything matching
to the GE Tines webhook. Bays at WJ get the PXE LAN 10.9.100.x IP
captured and reported -> GE backend tags bays as on a non-corp 10.x
subnet -> dynamic group eligibility for SFLD policy never matches.
Other GE sites work because their PXE LANs aren't on 10.x at all.
Renumber PXE LAN to RFC1918 172.16.9.0/24 so the GE filter naturally
skips wired PXE addresses without any disable-NIC dance.
Server-side already in flight (netplan dual-bound, dnsmasq scope +
boot URL repointed, blancco preferences + grub.cfg + iPXE GetPxeScript
all sed'd to 172.16.9.1). This commit is the playbook / scripts /
docs side: 109 hits across 35 files sed'd in one shot.
After this lands + boot.wim is rebuilt + bays renumber off DHCP,
the 10.9.100.1 binding will be dropped from netplan as the final
cleanup step.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,7 @@ Write-Host "================================================================"
|
||||
Write-Host ""
|
||||
|
||||
# Imaging-progress reporter. Posts coarse stage updates to the PXE webapp
|
||||
# at http://10.9.100.1:9009/imaging/status so the operator can watch
|
||||
# at http://172.16.9.1:9009/imaging/status so the operator can watch
|
||||
# progress in a browser. Best-effort: failures never block imaging.
|
||||
$pxeStatusLib = Join-Path $PSScriptRoot 'shopfloor-setup\Shopfloor\lib\Send-PxeStatus.ps1'
|
||||
if (Test-Path $pxeStatusLib) {
|
||||
|
||||
@@ -165,8 +165,12 @@ if (Test-Path -LiteralPath $machineNumFile) {
|
||||
# before UDC_Setup.exe runs means the installer's File.Copy (overwrite:true)
|
||||
# would overwrite it IF the share were reachable, but since it isn't, our
|
||||
# pre-staged file survives and UDC launches with correct settings.
|
||||
# UDC payload (settings backups + webserver settings) lives only in the
|
||||
# collections per-pc-type dir - UDC is the "C" of "collections". On nocoll
|
||||
# bays the dir doesn't exist; Test-Path skips silently.
|
||||
$udcCollDir = Join-Path (Split-Path $PSScriptRoot -Parent) 'gea-shopfloor-collections'
|
||||
if ($machineNum -and $machineNum -ne '9999') {
|
||||
$udcBackupDir = 'C:\Enrollment\shopfloor-setup\Standard\udc-backups'
|
||||
$udcBackupDir = Join-Path $udcCollDir 'udc-backups'
|
||||
$udcBackup = Join-Path $udcBackupDir "udc_settings_$machineNum.json"
|
||||
$udcTarget = 'C:\ProgramData\UDC\udc_settings.json'
|
||||
if (Test-Path -LiteralPath $udcBackup) {
|
||||
@@ -176,11 +180,11 @@ if ($machineNum -and $machineNum -ne '9999') {
|
||||
Copy-Item -Path $udcBackup -Destination $udcTarget -Force
|
||||
Write-PreInstallLog "Pre-staged UDC settings from $udcBackup -> $udcTarget"
|
||||
} else {
|
||||
Write-PreInstallLog "No UDC settings backup for machine $machineNum in $udcBackupDir"
|
||||
Write-PreInstallLog "No UDC settings backup for machine $machineNum at $udcBackup (skipping - normal for nocoll bays)"
|
||||
}
|
||||
}
|
||||
|
||||
$udcWebSrc = 'C:\Enrollment\shopfloor-setup\Standard\udc_webserver_settings.json'
|
||||
$udcWebSrc = Join-Path $udcCollDir 'udc_webserver_settings.json'
|
||||
$udcWebDst = 'C:\ProgramData\UDC\udc_webserver_settings.json'
|
||||
if (Test-Path -LiteralPath $udcWebSrc) {
|
||||
if (-not (Test-Path 'C:\ProgramData\UDC')) {
|
||||
@@ -189,7 +193,7 @@ if (Test-Path -LiteralPath $udcWebSrc) {
|
||||
Copy-Item -Path $udcWebSrc -Destination $udcWebDst -Force
|
||||
Write-PreInstallLog "Pre-staged UDC webserver settings from $udcWebSrc -> $udcWebDst"
|
||||
} else {
|
||||
Write-PreInstallLog "No UDC webserver settings file at $udcWebSrc" "WARN"
|
||||
Write-PreInstallLog "No UDC webserver settings file at $udcWebSrc (skipping - normal for nocoll bays)"
|
||||
}
|
||||
|
||||
# --- Suppress Windows Defender Firewall "Allow access" prompts globally for
|
||||
@@ -326,15 +330,27 @@ foreach ($app in $config.Applications) {
|
||||
if ($g -icontains $n) { foreach ($x in $g) { [void]$myNames.Add($x) } }
|
||||
}
|
||||
}
|
||||
# PCTypesStrict=true bypasses the alias-expansion matcher and requires
|
||||
# the actual pcType (or composite pcProfileKey) to literally equal one
|
||||
# of the allowedTypes entries. Used by UDC because the alias graph
|
||||
# transitively connects gea-shopfloor-collections <-> nocollections via
|
||||
# the legacy 'Standard' group, which would otherwise cause UDC to install
|
||||
# on nocoll bays even with PCTypes=['gea-shopfloor-collections'].
|
||||
$matchesType = ($allowedTypes -contains '*')
|
||||
if (-not $matchesType) {
|
||||
foreach ($t in $allowedTypes) {
|
||||
if ($myNames.Contains($t)) { $matchesType = $true; break }
|
||||
foreach ($g in $aliasGroups) {
|
||||
if ($g -icontains $t) {
|
||||
foreach ($x in $g) { if ($myNames.Contains($x)) { $matchesType = $true; break } }
|
||||
if ($app.PCTypesStrict) {
|
||||
foreach ($t in $allowedTypes) {
|
||||
if (($pcType -ieq $t) -or ($pcProfileKey -ieq $t)) { $matchesType = $true; break }
|
||||
}
|
||||
} else {
|
||||
foreach ($t in $allowedTypes) {
|
||||
if ($myNames.Contains($t)) { $matchesType = $true; break }
|
||||
foreach ($g in $aliasGroups) {
|
||||
if ($g -icontains $t) {
|
||||
foreach ($x in $g) { if ($myNames.Contains($x)) { $matchesType = $true; break } }
|
||||
}
|
||||
if ($matchesType) { break }
|
||||
}
|
||||
if ($matchesType) { break }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Reason: GE's Intune Proactive-Remediation "Report IP" script enumerates
|
||||
# Get-NetIPAddress and POSTs every IP it finds to a GE webhook. When a
|
||||
# shopfloor bay is still cabled to the air-gapped PXE LAN (10.9.100.0/24),
|
||||
# shopfloor bay is still cabled to the air-gapped PXE LAN (172.16.9.0/24),
|
||||
# the webhook sees 10.9.100.x as one of the device's IPs and tags the bay
|
||||
# "not on corp net". A dynamic group / assignment-filter at GE then excludes
|
||||
# the bay from receiving the SFLD ConfigurationProfile (Function + SasToken
|
||||
|
||||
@@ -66,6 +66,15 @@ if (Test-Path -LiteralPath $subtypeFile) {
|
||||
$pcSubtype = (Get-Content -LiteralPath $subtypeFile -First 1 -ErrorAction SilentlyContinue).Trim()
|
||||
}
|
||||
|
||||
# Display sub-type fallback: if pc-subtype.txt is absent (post-rename-reorg
|
||||
# default) but display-type.txt exists, use it as the subtype. Lets the
|
||||
# Display-Lobby / Display-Dashboard / gea-shopfloor-display-{lobby,dashboard}
|
||||
# profile keys resolve correctly for Display PCs.
|
||||
$displayTypeFile = 'C:\Enrollment\display-type.txt'
|
||||
if (-not $pcSubtype -and ($pcType -ieq 'gea-shopfloor-display' -or $pcType -ieq 'Display') -and (Test-Path -LiteralPath $displayTypeFile)) {
|
||||
$pcSubtype = (Get-Content -LiteralPath $displayTypeFile -First 1 -ErrorAction SilentlyContinue).Trim()
|
||||
}
|
||||
|
||||
# Build the profile key: "Standard-Machine", "CMM", "Display-Lobby", etc.
|
||||
$profileKey = if ($pcSubtype) { "$pcType-$pcSubtype" } else { $pcType }
|
||||
|
||||
@@ -82,6 +91,8 @@ $pcProfileAliasGroups = @(
|
||||
@('WaxAndTrace', 'gea-shopfloor-waxtrace'),
|
||||
@('Genspect', 'gea-shopfloor-genspect'),
|
||||
@('Display', 'gea-shopfloor-display'),
|
||||
@('Display-Lobby', 'gea-shopfloor-display-Lobby', 'gea-shopfloor-display-lobby'),
|
||||
@('Display-Dashboard', 'gea-shopfloor-display-Dashboard', 'gea-shopfloor-display-dashboard'),
|
||||
@('Heattreat', 'gea-shopfloor-heattreat')
|
||||
)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ function Send-PxeStatus {
|
||||
# Only available post-AAD-join; pass it from Monitor-IntuneProgress
|
||||
# once captured. The dashboard renders a QR of this value.
|
||||
[string]$IntuneDeviceId = '',
|
||||
[string]$PxeServer = '10.9.100.1',
|
||||
[string]$PxeServer = '172.16.9.1',
|
||||
[int]$Port = 9009,
|
||||
[int]$TimeoutSec = 5
|
||||
)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Set-OpenTextAutoStart.ps1 - place WJ Shopfloor.lnk in the All Users
|
||||
# Startup folder so HostExplorer's "WJ Shopfloor" session launches at
|
||||
# every login. Idempotent: re-running is a no-op when the .lnk already
|
||||
# exists at the same path.
|
||||
#
|
||||
# Used by per-pc-type 09-Setup scripts for shopfloor types whose only
|
||||
# business app is OpenText (common, waxtrace, genspect, heattreat).
|
||||
# collections + nocollections do NOT auto-start OpenText - their techs
|
||||
# pick which apps via Configure-PC.ps1.
|
||||
#
|
||||
# Source .lnk is created by the OpenText preinstall (Setup-OpenText.ps1)
|
||||
# on the public desktop. If the .lnk is missing, log a warning and exit
|
||||
# 0 - imaging chain still continues; auto-start can be re-attempted on a
|
||||
# subsequent login by re-running this script.
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
$startupDir = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp'
|
||||
$publicDesktop = 'C:\Users\Public\Desktop'
|
||||
|
||||
$candidates = @(
|
||||
Join-Path $publicDesktop 'WJ Shopfloor.lnk'
|
||||
Join-Path (Join-Path $publicDesktop 'Shopfloor Tools') 'WJ Shopfloor.lnk'
|
||||
)
|
||||
$src = $candidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1
|
||||
|
||||
if (-not $src) {
|
||||
Write-Warning "WJ Shopfloor.lnk not found on public desktop - OpenText auto-start NOT configured."
|
||||
Write-Warning " Searched: $($candidates -join ' ; ')"
|
||||
Write-Warning " Setup-OpenText.ps1 should create it during preinstall - check OpenText install state."
|
||||
return
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $startupDir)) {
|
||||
New-Item -Path $startupDir -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
$dst = Join-Path $startupDir 'WJ Shopfloor.lnk'
|
||||
try {
|
||||
Copy-Item -LiteralPath $src -Destination $dst -Force
|
||||
Write-Host "OpenText auto-start enabled: $dst (source: $src)"
|
||||
} catch {
|
||||
Write-Warning "Failed to copy WJ Shopfloor.lnk to startup: $_"
|
||||
}
|
||||
@@ -36,7 +36,7 @@ $siteConfig = Get-SiteConfig
|
||||
$siteName = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' }
|
||||
$siteNameCompact = if ($siteConfig) { $siteConfig.siteNameCompact } else { 'WestJefferson' }
|
||||
|
||||
$edncDir = "C:\Enrollment\shopfloor-setup\Standard\eDNC"
|
||||
$edncDir = Join-Path $PSScriptRoot 'eDNC'
|
||||
|
||||
if (-not (Test-Path $edncDir)) {
|
||||
Write-Warning "eDNC folder not found at $edncDir - skipping."
|
||||
|
||||
@@ -54,7 +54,11 @@ if (-not $machineNum -or $machineNum -eq '9999') {
|
||||
Write-Host "Machine number: $machineNum"
|
||||
|
||||
# ---- Locate local backup root (staged from PXE during imaging) ----
|
||||
$backupRoot = 'C:\Enrollment\shopfloor-setup\Standard\ntlars-backups'
|
||||
# Lives at C:\Enrollment\shopfloor-setup\_ntlars-backups (one shared dir
|
||||
# at the root of the staged shopfloor-setup tree, populated by Ansible
|
||||
# from playbook/shopfloor-setup/_ntlars-backups). Path is relative to
|
||||
# this script so it follows wherever per-pc-type dir is staged.
|
||||
$backupRoot = Join-Path $PSScriptRoot '..\_ntlars-backups'
|
||||
if (-not (Test-Path $backupRoot)) {
|
||||
Write-Host "ntlars-backups folder not staged at $backupRoot - skipping."
|
||||
try { Stop-Transcript | Out-Null } catch {}
|
||||
|
||||
@@ -6,7 +6,7 @@ REM 1. %~dp0Set-MachineNumber.ps1
|
||||
REM - .bat and .ps1 side-by-side (normal desktop-copied case, repo layout)
|
||||
REM 2. C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1
|
||||
REM - dispatcher-copied location, if this .bat lives somewhere else
|
||||
REM 3. C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1
|
||||
REM 3. C:\Enrollment\shopfloor-setup\gea-shopfloor-collections\Set-MachineNumber.ps1
|
||||
REM - canonical enrollment staging copy
|
||||
REM
|
||||
REM Goto-based dispatch - no nested if blocks, no literal parens in echo lines.
|
||||
@@ -21,13 +21,13 @@ if exist "%PS1%" goto :run
|
||||
set "PS1=C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1"
|
||||
if exist "%PS1%" goto :run
|
||||
|
||||
set "PS1=C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1"
|
||||
set "PS1=C:\Enrollment\shopfloor-setup\gea-shopfloor-collections\Set-MachineNumber.ps1"
|
||||
if exist "%PS1%" goto :run
|
||||
|
||||
echo ERROR: Set-MachineNumber.ps1 not found in any of:
|
||||
echo %~dp0Set-MachineNumber.ps1
|
||||
echo C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1
|
||||
echo C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1
|
||||
echo C:\Enrollment\shopfloor-setup\gea-shopfloor-collections\Set-MachineNumber.ps1
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
|
||||
BIN
playbook/shopfloor-setup/gea-shopfloor-collections/eDNC/eDNC_6-4-5.msi
Executable file
BIN
playbook/shopfloor-setup/gea-shopfloor-collections/eDNC/eDNC_6-4-5.msi
Executable file
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
# 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/09-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 ==="
|
||||
@@ -36,7 +36,7 @@ $siteConfig = Get-SiteConfig
|
||||
$siteName = if ($siteConfig) { $siteConfig.siteName } else { 'West Jefferson' }
|
||||
$siteNameCompact = if ($siteConfig) { $siteConfig.siteNameCompact } else { 'WestJefferson' }
|
||||
|
||||
$edncDir = "C:\Enrollment\shopfloor-setup\Standard\eDNC"
|
||||
$edncDir = Join-Path $PSScriptRoot 'eDNC'
|
||||
|
||||
if (-not (Test-Path $edncDir)) {
|
||||
Write-Warning "eDNC folder not found at $edncDir - skipping."
|
||||
|
||||
@@ -54,7 +54,8 @@ if (-not $machineNum -or $machineNum -eq '9999') {
|
||||
Write-Host "Machine number: $machineNum"
|
||||
|
||||
# ---- Locate local backup root (staged from PXE during imaging) ----
|
||||
$backupRoot = 'C:\Enrollment\shopfloor-setup\Standard\ntlars-backups'
|
||||
# Lives at C:\Enrollment\shopfloor-setup\_ntlars-backups (shared root dir).
|
||||
$backupRoot = Join-Path $PSScriptRoot '..\_ntlars-backups'
|
||||
if (-not (Test-Path $backupRoot)) {
|
||||
Write-Host "ntlars-backups folder not staged at $backupRoot - skipping."
|
||||
try { Stop-Transcript | Out-Null } catch {}
|
||||
|
||||
@@ -6,7 +6,7 @@ REM 1. %~dp0Set-MachineNumber.ps1
|
||||
REM - .bat and .ps1 side-by-side (normal desktop-copied case, repo layout)
|
||||
REM 2. C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1
|
||||
REM - dispatcher-copied location, if this .bat lives somewhere else
|
||||
REM 3. C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1
|
||||
REM 3. C:\Enrollment\shopfloor-setup\gea-shopfloor-nocollections\Set-MachineNumber.ps1
|
||||
REM - canonical enrollment staging copy
|
||||
REM
|
||||
REM Goto-based dispatch - no nested if blocks, no literal parens in echo lines.
|
||||
@@ -21,13 +21,13 @@ if exist "%PS1%" goto :run
|
||||
set "PS1=C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1"
|
||||
if exist "%PS1%" goto :run
|
||||
|
||||
set "PS1=C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1"
|
||||
set "PS1=C:\Enrollment\shopfloor-setup\gea-shopfloor-nocollections\Set-MachineNumber.ps1"
|
||||
if exist "%PS1%" goto :run
|
||||
|
||||
echo ERROR: Set-MachineNumber.ps1 not found in any of:
|
||||
echo %~dp0Set-MachineNumber.ps1
|
||||
echo C:\Users\SupportUser\Desktop\Set-MachineNumber.ps1
|
||||
echo C:\Enrollment\shopfloor-setup\Standard\Set-MachineNumber.ps1
|
||||
echo C:\Enrollment\shopfloor-setup\gea-shopfloor-nocollections\Set-MachineNumber.ps1
|
||||
echo.
|
||||
pause
|
||||
exit /b 1
|
||||
|
||||
BIN
playbook/shopfloor-setup/gea-shopfloor-nocollections/eDNC/eDNC_6-4-5.msi
Executable file
BIN
playbook/shopfloor-setup/gea-shopfloor-nocollections/eDNC/eDNC_6-4-5.msi
Executable file
Binary file not shown.
@@ -98,6 +98,30 @@
|
||||
]
|
||||
},
|
||||
|
||||
"gea-shopfloor-nocollections": {
|
||||
"_comment": "Shopfloor PC running eDNC + NTLARS + Defect Tracker but no UDC (no Collections). Same as Standard-Machine minus UDC pin/desktop/startup. Direct profile lookup (line 92 in Get-PCProfile.ps1) finds this BEFORE the alias-group fallback to Standard-Machine, so Standard-Machine's UDC entries do not leak through.",
|
||||
"machineappsSharePath": "\\\\tsgwp00525.wjs.geaerospace.net\\shared\\dt\\shopfloor\\main\\machineapps",
|
||||
"ntlarsBackupSharePath": "\\\\tsgwp00525.wjs.geaerospace.net\\shared\\dt\\shopfloor\\main\\ntlars-backups",
|
||||
"startupItems": [
|
||||
{ "label": "WJ Shopfloor", "type": "existing", "sourceLnk": "WJ Shopfloor.lnk" },
|
||||
{ "label": "Plant Apps", "type": "url", "urlKey": "plantApps" },
|
||||
{ "label": "eDNC", "type": "exe", "target": "C:\\Program Files (x86)\\Dnc\\bin\\DncMain.exe" }
|
||||
],
|
||||
"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": "eDNC", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\eDNC.lnk" },
|
||||
{ "name": "NTLARS", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\NTLARS.lnk" },
|
||||
{ "name": "Defect_Tracker", "lnkPath": "%PUBLIC%\\Desktop\\Shopfloor Tools\\Defect_Tracker.lnk" }
|
||||
],
|
||||
"desktopApps": [
|
||||
{ "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": "exe", "exePath": "C:\\Program Files (x86)\\WJF_Defect_Tracker\\Defect_Tracker.exe" }
|
||||
]
|
||||
},
|
||||
|
||||
"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 unified GE-Enforce dispatcher reads cmm/manifest.json on the tsgwp00525 share below and enforces versions on every user logon (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",
|
||||
|
||||
Reference in New Issue
Block a user