윈도우 3. 윈도우 설치 후 첫 부팅에 네트워크 어댑터가 전부 '사용 안 함'일 때: PowerShell 5.1 ConvertFrom-Json 과 HardwareInterface
원격으로 윈도우를 새로 깔 때, 설치하는 동안은 네트워크 어댑터를 꺼 두고 첫 부팅 때 다시 켜는 구조입니다. 끌 때 어댑터 목록을 network-adapters.json 에 적어 두고, 첫 부팅 스크립트가 그 파일을 읽어 다시 켭니다.
노트북으로 시험하는데, 설치가 끝나고 첫 로그인 화면이 5분쯤 멈춰 있더니 원격 지원 프로그램이 “Network connection” 실패로 끝났습니다. 장치 관리자를 보니 유선, 무선 둘 다 “사용 안 함” 이었습니다.
첫 번째 원인은 파일 읽는 줄이었습니다.
$adapters = @(Get-Content $path | ConvertFrom-Json)
이렇게 읽은 목록을 돌면서 각 어댑터의 GUID 로 찾아 켜는 식이었습니다. 첫 부팅 스크립트는 Windows PowerShell 5.1 에서 돕니다. 5.1 의 ConvertFrom-Json 은 JSON 배열을 원소 하나하나로 내보내지 않고 배열 덩어리 하나로 내보냅니다. 그걸 @() 로 감싸면 “배열 하나가 든 배열” 이 됩니다. 이 PC 에서 직접 해 보면 이렇습니다.
PS> $j = '[{"Guid":"{aaa}"},{"Guid":"{bbb}"}]'
PS> @($j | ConvertFrom-Json).Count
1
PS> foreach ($x in @($j | ConvertFrom-Json)) { "$($x.Guid)" }
{aaa} {bbb}
반복문이 한 번만 돌고, 그 안에서 .Guid 는 두 GUID 를 합친 문자열이 됩니다. 그런 이름의 어댑터는 없으니 아무것도 안 켜졌고, 기록 파일이 있으니 “기록이 없으면 다 켜기” 대비책도 건너뛰었습니다. 어댑터가 하나뿐인 PC 는 아무 문제가 없었으니 여태 몰랐던 겁니다. PowerShell 7 에서는 배열을 풀어서 내보내니 이 일이 없고, 5.1 에서는 @() 대신 변수에 먼저 담으면 풀립니다.
PS> $y = $j | ConvertFrom-Json
PS> $y.Count
2
생각해 보니 새로 깐 윈도우에는 일부러 꺼 둘 어댑터가 없습니다. 그래서 기록 파일에 기대지 말고 꺼진 하드웨어 어댑터를 전부 켜기로 했습니다.
Get-NetAdapter | Where-Object { $_.HardwareInterface -and $_.Status -eq 'Disabled' } | Enable-NetAdapter -Confirm:$false
같은 노트북에 다시 깔았습니다. 첫 로그인 화면은 새 문구대로 나왔는데, 어댑터는 여전히 둘 다 “사용 안 함” 이었습니다.
이번엔 HardwareInterface 가 문제였습니다. 꺼진 어댑터는 드라이버가 내려가 있어서 HardwareInterface 가 False 로 나옵니다. 꺼진 것만 골라 켜려고 붙인 조건이 정작 꺼진 어댑터를 빼 버린 거죠. Get-NetAdapter -Physical 이 꺼진 어댑터를 못 찾는 것도 같은 이유입니다.
그래서 HardwareInterface 로 거르지 않고 두 갈래로 켭니다.
Get-NetAdapter | Where-Object Status -eq 'Disabled' | ForEach-Object { Enable-NetAdapter -Name $_.Name -Confirm:$false }
Get-PnpDevice -Class Net | Where-Object ConfigManagerErrorCode -eq 22 | Enable-PnpDevice -Confirm:$false
문제 코드 22 가 장치 관리자의 “사용 안 함” 입니다. 이걸 최대 10번 확인하며 반복하고, 서버를 기다리는 3분 동안에도 15초마다 꺼진 게 남았는지 다시 봅니다. 시도할 때마다 hw= 값과 결과를 로그에 남기게 했으니, 다음에 또 안 되면 적어도 어디서 막혔는지는 바로 보일 겁니다.
꺼진 어댑터, Wi-Fi 첫 연결 실패, PnP 쪽에서만 꺼진 장치를 흉내 내 시험했을 때는 모두 켜졌습니다. 실제 노트북으로는 다음 설치 때 확인합니다.