# Set-FmsHostsEntry.ps1 - idempotently pin FMS host in C:\Windows\System32\drivers\etc\hosts. # # Why pinned: # eDNC's FMS prescan (CPreScan::Initialise_Sockets in DncMain.exe and # CDoPersonnel::InitializeSocket in DNCdll.dll) resolves the FMS host # via MFC CSocket, which calls inet_addr first then gethostbyname. The # legacy WinSock1 resolver path fails on the GE corporate network for # wjfms3.ae.ge.com (modern getaddrinfo path used by PowerShell works # fine, but eDNC does not use it). Hosts file entry is consulted by # gethostbyname before any DNS query, so the pin short-circuits the # broken legacy path. # # Idempotent: adds line if missing, leaves it alone if already present. # Safe to run every cycle (DetectionMethod=Always in manifest). $ErrorActionPreference = 'Stop' $hostsPath = Join-Path $env:windir 'System32\drivers\etc\hosts' $ip = '10.233.112.158' $fqdn = 'WJFMS3.AE.GE.COM' $line = "$ip`t$fqdn" if (-not (Test-Path $hostsPath)) { Write-Host "hosts file not found at $hostsPath - aborting" exit 1 } $content = Get-Content -LiteralPath $hostsPath -ErrorAction Stop # Match any non-comment line that maps either the IP or the FQDN. # Drops stale or wrong mappings of the same FQDN/IP, then appends the canonical pin. $pattern = '(?i)^\s*[^#\s]+\s+\S*' + [regex]::Escape($fqdn) + '\b|^\s*' + [regex]::Escape($ip) + '\s' $existing = $content | Where-Object { $_ -match $pattern } $canonical = ($existing | Where-Object { $_ -match "^\s*$([regex]::Escape($ip))\s+$([regex]::Escape($fqdn))\s*$" }) if ($canonical -and $existing.Count -eq @($canonical).Count) { # Already pinned correctly. No change. exit 0 } # Either no entry, or an entry exists with wrong IP/FQDN/casing/whitespace. Rewrite. $kept = $content | Where-Object { $_ -notmatch $pattern } $new = @($kept) + $line Set-Content -LiteralPath $hostsPath -Value $new -Encoding ascii -ErrorAction Stop Write-Host "Wrote FMS hosts pin: $line" exit 0