From 1886857c0f523790fab6c81670c9d865dd77f9cc Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 22 Apr 2026 12:51:05 -0400 Subject: [PATCH] Use [Environment]::MachineName instead of $env:COMPUTERNAME Live kernel NetBIOS name instead of the PowerShell process-env cache. $env:COMPUTERNAME is populated when PowerShell starts and does not update if the PC gets renamed (common on Intune-managed Autopilot / AADJ devices that come up with a DESKTOP-XXXXXXXX name and get renamed by policy post-imaging). Until the next reboot, the env var stays stale while 'hostname.exe' already reports the new name. That mismatch showed up live on the first production retrofit: the status.json was written under _outputs/logs/DESKTOP-XXXXXXXX/ instead of under the device's current name, and the TargetHostnames filter and monitor drift-check would likewise see the stale name. [Environment]::MachineName reads from the kernel on each call, so it always returns the current NetBIOS name. Swapped at all five callsites in GE-Enforce.ps1, Register-GEEnforce.ps1, and Install-FromManifest.ps1. Co-Authored-By: Claude Opus 4.7 (1M context) --- playbook/shopfloor-setup/common/GE-Enforce.ps1 | 8 ++++++-- playbook/shopfloor-setup/common/Register-GEEnforce.ps1 | 2 +- .../shopfloor-setup/common/lib/Install-FromManifest.ps1 | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/playbook/shopfloor-setup/common/GE-Enforce.ps1 b/playbook/shopfloor-setup/common/GE-Enforce.ps1 index 4651a14..688e5b2 100644 --- a/playbook/shopfloor-setup/common/GE-Enforce.ps1 +++ b/playbook/shopfloor-setup/common/GE-Enforce.ps1 @@ -182,7 +182,11 @@ try { # continues if the share path is not writable. # ------------------------------------------------------------------ try { - $statusDir = Join-Path (Join-Path $driveLetter '_outputs') (Join-Path 'logs' $env:COMPUTERNAME) + # Live NetBIOS name from kernel - not $env:COMPUTERNAME, which is + # cached in the process env block and goes stale after a post-image + # rename on Intune-managed PCs. + $hostname = [System.Environment]::MachineName + $statusDir = Join-Path (Join-Path $driveLetter '_outputs') (Join-Path 'logs' $hostname) if (-not (Test-Path $statusDir)) { New-Item -Path $statusDir -ItemType Directory -Force -ErrorAction Stop | Out-Null } @@ -223,7 +227,7 @@ try { } $status = [ordered]@{ - hostname = $env:COMPUTERNAME + hostname = $hostname lastCheckIn = (Get-Date).ToUniversalTime().ToString('o') pcType = $pcType pcSubType = $pcSubType diff --git a/playbook/shopfloor-setup/common/Register-GEEnforce.ps1 b/playbook/shopfloor-setup/common/Register-GEEnforce.ps1 index 0d6f0c5..b4405bd 100644 --- a/playbook/shopfloor-setup/common/Register-GEEnforce.ps1 +++ b/playbook/shopfloor-setup/common/Register-GEEnforce.ps1 @@ -62,7 +62,7 @@ $action = New-ScheduledTaskAction ` # FIPS 180-4 approved. $hostHash = [System.BitConverter]::ToUInt32( [System.Security.Cryptography.SHA256]::Create().ComputeHash( - [System.Text.Encoding]::UTF8.GetBytes($env:COMPUTERNAME)), 0) + [System.Text.Encoding]::UTF8.GetBytes([System.Environment]::MachineName)), 0) $offsetMin = $hostHash % 5 # 0..4 $startToday = (Get-Date -Hour 0 -Minute $offsetMin -Second 0).AddSeconds(0) diff --git a/playbook/shopfloor-setup/common/lib/Install-FromManifest.ps1 b/playbook/shopfloor-setup/common/lib/Install-FromManifest.ps1 index 04ea5ae..6ec23dc 100644 --- a/playbook/shopfloor-setup/common/lib/Install-FromManifest.ps1 +++ b/playbook/shopfloor-setup/common/lib/Install-FromManifest.ps1 @@ -375,7 +375,11 @@ function Test-PCTypeMatches { function Test-HostnameMatches { param($App) if (-not $App.TargetHostnames -or $App.TargetHostnames.Count -eq 0) { return $true } - $myName = $env:COMPUTERNAME + # [System.Environment]::MachineName reads the live NetBIOS name from the + # kernel. $env:COMPUTERNAME is cached in the process environment at PS + # startup and is stale after a PC rename until the next reboot - which + # matters on Intune-managed PCs that get renamed post-imaging. + $myName = [System.Environment]::MachineName foreach ($h in $App.TargetHostnames) { if ($h -ieq $myName) { return $true } if ($myName -ilike $h) { return $true } # glob patterns: WJS-*, *-SHOP-* @@ -405,7 +409,7 @@ foreach ($app in $config.Applications) { } if (-not (Test-HostnameMatches -App $app)) { - Write-InstallLog " TargetHostnames filter: entry targets $($app.TargetHostnames -join ',') but PC is $env:COMPUTERNAME - skipping" + Write-InstallLog " TargetHostnames filter: entry targets $($app.TargetHostnames -join ',') but PC is $([System.Environment]::MachineName) - skipping" $pcFiltered++ continue }