# Detect-ComputerName.ps1 # Exit 0 = compliant, Exit 1 = not compliant $StartNumber = 2001 $LabMode = $true $LabSuffix = "-LAB" $regPath = "HKLM:\SOFTWARE\EA\ComputerNaming" $modeTag = if ($LabMode) { "LAB" } else { "PROD" } function Test-OOBEComplete { # Returns $true if OOBE is complete, $false otherwise. # Uses documented OOBEComplete() API first, then registry fallback. try { if (-not ([System.Management.Automation.PSTypeName]'Api.Kernel32').Type) { $TypeDef = @" using System; using System.Runtime.InteropServices; namespace Api { public class Kernel32 { [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int OOBEComplete(ref int bIsOOBEComplete); } } "@ Add-Type -TypeDefinition $TypeDef -Language CSharp -ErrorAction Stop } $state = 0 $ok = [Api.Kernel32]::OOBEComplete([ref] $state) if ($ok -ne 0) { return ($state -ne 0) } } catch { # Ignore and fall back } # Registry fallback: Setup state try { $k = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State" -ErrorAction Stop $s = $k.StateName if (-not $s) { $s = $k.ImageState } if ($s) { return ($s -eq "IMAGE_STATE_COMPLETE") } } catch {} # Last fallback: during OOBE, DefaultUserName is often defaultuser0 try { $du = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -ErrorAction Stop).DefaultUserName if ($du -and $du -ieq "defaultuser0") { return $false } } catch {} # Safe default: assume OOBE not complete return $false } # ---- OOBE GUARD ---- # During OOBE/ESP, mark compliant so remediation won't run yet. if (-not (Test-OOBEComplete)) { exit 0 } function Get-IsLaptop { $isLaptop = $false $chassisTypes = (Get-CimInstance -ClassName Win32_SystemEnclosure -ErrorAction SilentlyContinue).ChassisTypes if ($chassisTypes | Where-Object { $_ -in 8,9,10,14,30,31,32 }) { $isLaptop = $true } if (-not $isLaptop) { $isLaptop = @(Get-CimInstance -ClassName Win32_Battery -ErrorAction SilentlyContinue).Count -gt 0 } return $isLaptop } function Test-CompliantName { param( [string]$Name, [bool]$IsLaptop, [int]$StartNumber, [bool]$LabMode, [string]$LabSuffix ) $patterns = @() if ($LabMode) { # LabMode: Accept BOTH prod names and lab-suffixed names $patterns += '^EA(\d+)(L|D)$' $patterns += ('^EA(\d+)(L|D)' + [regex]::Escape($LabSuffix) + '$') } else { # ProdMode: Only accept prod names $patterns += '^EA(\d+)(L|D)$' } foreach ($rx in $patterns) { $m = [regex]::Match($Name, $rx, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) if ($m.Success) { $num = [int]$m.Groups[1].Value $suffix = $m.Groups[2].Value.ToUpperInvariant() if ($num -lt $StartNumber) { return $false } if ($IsLaptop -and $suffix -ne 'L') { return $false } if (-not $IsLaptop -and $suffix -ne 'D') { return $false } return $true } } return $false } # Pending rename: compliant only if the TARGET is compliant (or matches our stored assignment) $activeName = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' -ErrorAction SilentlyContinue).ComputerName $targetName = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' -ErrorAction SilentlyContinue).ComputerName $pendingRename = ($activeName -and $targetName -and ($activeName -ne $targetName)) $isLaptop = Get-IsLaptop $assignedName = $null $assignedMode = $null try { $p = Get-ItemProperty -Path $regPath -ErrorAction Stop $assignedName = $p.AssignedName $assignedMode = $p.AssignedMode } catch {} $hasValidAssignment = ($assignedName -and ($assignedMode -eq $modeTag)) if ($pendingRename) { if ($hasValidAssignment) { if ($targetName -ieq $assignedName) { exit 0 } else { exit 1 } } else { if (Test-CompliantName -Name $targetName -IsLaptop $isLaptop -StartNumber $StartNumber -LabMode $LabMode -LabSuffix $LabSuffix) { exit 0 } else { exit 1 } } } # If assignment exists and matches current mode, enforce it if ($hasValidAssignment) { if ($env:COMPUTERNAME -ieq $assignedName) { exit 0 } else { exit 1 } } # Otherwise just check compliance (LabMode accepts both formats) if (Test-CompliantName -Name $env:COMPUTERNAME -IsLaptop $isLaptop -StartNumber $StartNumber -LabMode $LabMode -LabSuffix $LabSuffix) { exit 0 } else { exit 1 }