04-SetControllerNicIP.ps1 (imaging-time, runs once via Run-ShopfloorSetup): - Finds the Realtek physical Ethernet adapter (controller NIC on every collections bay; corp LAN is Intel) - Skips any candidate with a DHCP default gateway (that one is the corp LAN, not the controller) - Skips any candidate already on 192.168.1.2 - Sets static 192.168.1.2/24, no gateway, clears DNS - matches the manual procedure documented in post-deploy-debug-flowchart.md section 2B - Refuses to guess when multiple Realtek NICs remain ambiguous - Imaging-time only, not enforced via GE-Enforce so the tech can override on a specific bay if needed without the drift-catcher reverting Set-ControllerCredential.ps1 + manifest-entry-controller-credential.json: - Break-glass cmdkey /add for the controller SMB share (\\192.168.1.1\md1 used by DNC). Scoped to the 12 Okuma LOC650 machine numbers (3201-3212). - Manifest entry is detection-less so it runs every enforce cycle if the script is armed (.ps1 extension); disarmed by default (.ps1.bak on the share) so a coach can rename when a bay loses its credential without the enforcer overwriting per-bay deviations between events. - Smoke-tested end-to-end on win11 VM via QGA: SYSTEM context cmdkey /add succeeds, cmdkey /list shows the entry. DNC service runs as LocalSystem so SYSTEM vault is the right target. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
143 lines
6.2 KiB
PowerShell
143 lines
6.2 KiB
PowerShell
# 04-SetControllerNicIP.ps1 - Auto-configure the controller-facing Realtek NIC
|
|
# at imaging time on gea-shopfloor-collections bays.
|
|
#
|
|
# Standard config (per post-deploy-debug-flowchart.md, section 2B):
|
|
# IP: 192.168.1.2
|
|
# Mask: 255.255.255.0 (/24)
|
|
# Gateway: (blank)
|
|
# DNS: (none - cleared)
|
|
#
|
|
# Logic:
|
|
# 1. Find physical Ethernet adapters whose vendor description contains
|
|
# 'Realtek'. (Shopfloor PCs ship with a Realtek PCIe GbE add-in card
|
|
# for the controller; the corp LAN NIC is typically Intel.)
|
|
# 2. Skip any candidate that already has a DHCP-assigned default gateway
|
|
# (that's the corp LAN NIC, not the controller).
|
|
# 3. Skip any candidate that already has 192.168.1.2 - already configured.
|
|
# 4. For the single remaining candidate, set manual IP / mask, clear DNS.
|
|
# 5. If multiple Realtek NICs remain after filtering, log + bail (manual
|
|
# investigation needed; the script will NOT guess which is controller).
|
|
#
|
|
# Imaging-time only - run once during Run-ShopfloorSetup for collections
|
|
# bays. Not registered as a GE-Enforce drift-catcher because once set,
|
|
# manual changes by the tech are intentional and should not be reverted.
|
|
#
|
|
# Log: C:\Logs\Shopfloor\controller-nic.log
|
|
|
|
$ErrorActionPreference = 'Continue'
|
|
|
|
$logDir = 'C:\Logs\Shopfloor'
|
|
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
|
|
$logFile = Join-Path $logDir 'controller-nic.log'
|
|
|
|
function Write-NicLog {
|
|
param([string]$Message, [string]$Level = 'INFO')
|
|
$line = '[{0}] [{1}] {2}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Level, $Message
|
|
Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue
|
|
Write-Host $line
|
|
}
|
|
|
|
$targetIP = '192.168.1.2'
|
|
$prefixLen = 24
|
|
|
|
Write-NicLog "=== 04-SetControllerNicIP start ==="
|
|
|
|
# Enumerate physical Ethernet adapters with Realtek in the vendor description.
|
|
$candidates = Get-NetAdapter -Physical -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.InterfaceDescription -match 'Realtek' -and $_.MediaType -eq '802.3' }
|
|
|
|
if (-not $candidates) {
|
|
Write-NicLog "No Realtek physical Ethernet adapters found - nothing to configure (PC may have no controller NIC)."
|
|
exit 0
|
|
}
|
|
|
|
Write-NicLog "Found $($candidates.Count) Realtek adapter(s):"
|
|
foreach ($c in $candidates) {
|
|
Write-NicLog " $($c.Name) ($($c.InterfaceDescription)) [status=$($c.Status)]"
|
|
}
|
|
|
|
# Filter out anything that already looks like the corp LAN NIC (has a
|
|
# DHCP-assigned default gateway -- corp DHCP servers always hand one out).
|
|
$filtered = @()
|
|
foreach ($c in $candidates) {
|
|
$ipCfg = Get-NetIPConfiguration -InterfaceIndex $c.ifIndex -ErrorAction SilentlyContinue
|
|
$gw = $null
|
|
if ($ipCfg -and $ipCfg.IPv4DefaultGateway) {
|
|
$gw = ($ipCfg.IPv4DefaultGateway | Select-Object -First 1).NextHop
|
|
}
|
|
if ($gw) {
|
|
Write-NicLog " Skipping $($c.Name) - has IPv4 default gateway $gw (likely corp LAN, not controller)"
|
|
continue
|
|
}
|
|
|
|
# Skip if it already has 192.168.1.2 - already configured.
|
|
$existing = Get-NetIPAddress -InterfaceIndex $c.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.IPAddress -eq $targetIP }
|
|
if ($existing) {
|
|
Write-NicLog " Skipping $($c.Name) - already has $targetIP/$prefixLen (configured previously)"
|
|
continue
|
|
}
|
|
|
|
$filtered += $c
|
|
}
|
|
|
|
if ($filtered.Count -eq 0) {
|
|
Write-NicLog "After filtering, no candidate remains - either already configured or all Realtek adapters look like corp LAN. Nothing to do."
|
|
exit 0
|
|
}
|
|
if ($filtered.Count -gt 1) {
|
|
Write-NicLog "Multiple unconfigured Realtek adapters found ($($filtered.Count)). Refusing to guess which is the controller NIC. Manual configuration required." 'WARN'
|
|
foreach ($f in $filtered) { Write-NicLog " Ambiguous: $($f.Name) ($($f.InterfaceDescription))" 'WARN' }
|
|
exit 0
|
|
}
|
|
|
|
$target = $filtered[0]
|
|
Write-NicLog "Selected controller NIC: $($target.Name) ($($target.InterfaceDescription)) [ifIndex=$($target.ifIndex)]"
|
|
|
|
# Wipe any existing IPv4 addresses + gateways on this interface so the new
|
|
# static doesn't conflict with stale DHCP leases or APIPA addresses.
|
|
try {
|
|
Get-NetIPAddress -InterfaceIndex $target.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue |
|
|
Remove-NetIPAddress -Confirm:$false -ErrorAction SilentlyContinue
|
|
Get-NetRoute -InterfaceIndex $target.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.DestinationPrefix -eq '0.0.0.0/0' } |
|
|
Remove-NetRoute -Confirm:$false -ErrorAction SilentlyContinue
|
|
Write-NicLog "Cleared existing IPv4 addresses + default route on $($target.Name)"
|
|
} catch {
|
|
Write-NicLog "Failed to clear existing IPv4 state on $($target.Name): $_" 'WARN'
|
|
}
|
|
|
|
# Switch the interface to manual IP assignment + set the static.
|
|
try {
|
|
Set-NetIPInterface -InterfaceIndex $target.ifIndex -Dhcp Disabled -ErrorAction Stop
|
|
New-NetIPAddress -InterfaceIndex $target.ifIndex -IPAddress $targetIP `
|
|
-PrefixLength $prefixLen -ErrorAction Stop | Out-Null
|
|
Write-NicLog "Set $targetIP/$prefixLen on $($target.Name) (no gateway)"
|
|
} catch {
|
|
Write-NicLog "Failed to set static IP on $($target.Name): $_" 'ERROR'
|
|
exit 1
|
|
}
|
|
|
|
# Clear DNS so the corp resolver doesn't get queried for controller-side hostnames.
|
|
try {
|
|
Set-DnsClientServerAddress -InterfaceIndex $target.ifIndex -ResetServerAddresses -ErrorAction Stop
|
|
Write-NicLog "Cleared DNS servers on $($target.Name)"
|
|
} catch {
|
|
Write-NicLog "Failed to clear DNS on $($target.Name): $_" 'WARN'
|
|
}
|
|
|
|
# Verify what landed.
|
|
try {
|
|
$finalCfg = Get-NetIPConfiguration -InterfaceIndex $target.ifIndex -ErrorAction SilentlyContinue
|
|
$finalIPs = ($finalCfg.IPv4Address | ForEach-Object { "$($_.IPAddress)/$($_.PrefixLength)" }) -join ', '
|
|
$finalGw = if ($finalCfg.IPv4DefaultGateway) { ($finalCfg.IPv4DefaultGateway | Select-Object -First 1).NextHop } else { '(none)' }
|
|
$finalDns = ($finalCfg.DNSServer | Where-Object AddressFamily -eq 2 | Select-Object -ExpandProperty ServerAddresses) -join ', '
|
|
if (-not $finalDns) { $finalDns = '(none)' }
|
|
Write-NicLog "Verify: $($target.Name) IPs=$finalIPs Gateway=$finalGw DNS=$finalDns"
|
|
} catch {
|
|
Write-NicLog "Verification readback failed: $_" 'WARN'
|
|
}
|
|
|
|
Write-NicLog "=== 04-SetControllerNicIP end ==="
|
|
exit 0
|