geenforce display dispatcher: resolve role from the server by FQDN, fall back to display-type.txt

The dispatcher now derives its FQDN (F<BIOS serial>.<domain>) and asks
/api/dashboarddefaults/display-role for its role/path, so changing a display's
type/location in Settings > Dashboard Defaults takes effect with no reimage. If
there is no serial, no server mapping, or the lookup fails, it falls back to the
local display-type.txt map (offline-safe). VM-verified both paths.
This commit is contained in:
cproudlock
2026-07-29 07:34:21 -04:00
parent e237cc2c05
commit b22701a444

View File

@@ -111,28 +111,48 @@ try {{
if ($shopdbConfig.BaseUrl) {{ $KioskBaseUrl = ([string]$shopdbConfig.BaseUrl).TrimEnd('/') }} if ($shopdbConfig.BaseUrl) {{ $KioskBaseUrl = ([string]$shopdbConfig.BaseUrl).TrimEnd('/') }}
}} catch {{}} }} catch {{}}
$displayTypeFile = 'C:\\Enrollment\\display-type.txt' # PREFERRED: resolve this display's role from the server by its FQDN, so a change
if (-not (Test-Path -LiteralPath $displayTypeFile)) {{ # in Settings > Dashboard Defaults takes effect with no reimage / local edit. The
Write-Host "display-type.txt not found at $displayTypeFile; nothing to configure." # FQDN is F<BIOS serial>.<domain> (GE device naming); domain from HKLM
# DisplayFqdnDomain or the default. display-role is a PUBLIC endpoint (no token).
$path = $null
$serial = ''
try {{ $serial = ([string](Get-CimInstance -ClassName Win32_BIOS -ErrorAction Stop).SerialNumber).Trim() }} catch {{}}
$fqdnDomain = 'device.geaerospace.net'
try {{
$ddom = Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\GE\\ShopDB' -Name DisplayFqdnDomain -ErrorAction Stop
if ($ddom.DisplayFqdnDomain) {{ $fqdnDomain = ([string]$ddom.DisplayFqdnDomain).Trim().Trim('.') }}
}} catch {{}}
if ($serial) {{
$fqdn = ('F' + $serial + '.' + $fqdnDomain).ToLower()
try {{
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$roleUri = "$KioskBaseUrl/api/dashboarddefaults/display-role?fqdn=$([uri]::EscapeDataString($fqdn))"
$resp = Invoke-RestMethod -Uri $roleUri -TimeoutSec 20 -ErrorAction Stop
if ($resp -and $resp.data -and $resp.data.path) {{
$path = [string]$resp.data.path
Write-Host "server role for $fqdn -> $path"
}}
}} catch {{ Write-Host "display-role lookup failed for $fqdn : $($_.Exception.Message)" }}
}}
# FALLBACK: the local display-type.txt map (offline, or no server mapping yet).
if (-not $path) {{
$displayTypeFile = 'C:\\Enrollment\\display-type.txt'
if (Test-Path -LiteralPath $displayTypeFile) {{
$displayType = (Get-Content -LiteralPath $displayTypeFile -Raw).Trim()
if (-not [string]::IsNullOrWhiteSpace($displayType)) {{
$matchedKey = $DisplayTypeTargets.Keys | Where-Object {{ $_ -ieq $displayType }} | Select-Object -First 1
if ($matchedKey) {{ $path = [string]$DisplayTypeTargets[$matchedKey]; Write-Host "local display-type '$displayType' -> $path" }}
}}
}}
}}
if (-not $path) {{
Write-Host 'No display role from server or display-type.txt; nothing to configure.'
return return
}} }}
$displayType = (Get-Content -LiteralPath $displayTypeFile -Raw).Trim() $kioskUrl = "$KioskBaseUrl$path"
if ([string]::IsNullOrWhiteSpace($displayType)) {{
Write-Host 'display-type.txt is empty; nothing to configure.'
return
}}
# Case-insensitive lookup so 'lobby' and 'Lobby' both resolve.
$matchedKey = $DisplayTypeTargets.Keys |
Where-Object {{ $_ -ieq $displayType }} |
Select-Object -First 1
if (-not $matchedKey) {{
Write-Host "Unknown display-type '$displayType'; known types: $($DisplayTypeTargets.Keys -join ', ')."
return
}}
$kioskUrl = "$KioskBaseUrl$($DisplayTypeTargets[$matchedKey])"
# Resolve msedge.exe (baked into the display image). # Resolve msedge.exe (baked into the display image).
$edge = $null $edge = $null