2014-10-03 3 views
1

저는 PowerShell을 매우 신중하게 생각하며 프로그래머가 아니기 때문에 제 문제의 원인이 아마도 여러분에게 상당히 분명합니다. 기본적으로 내 스크립트 오류Powershell 해시 테이블 foreach 루프를 다시 사용하십시오.

"null 배열을 인덱싱 할 수 없습니다."

정적으로 구성된 멀티 홈 서버에서 각 네트워크 어댑터의 속성을 수집하는 과정이 반복됩니다. 디버그 문은 foreach와 if가 예상대로 작동 함을 보여 주지만 foreach 루프에서 해시 테이블을 다시 사용할 수없는 것처럼 보입니다. 여기에 올바른 방법은 무엇입니까? (참고 : 이것은 가능하면 해시 테이블을 사용할 필요가 있으므로 해시 테이블 주위에 집중적으로 배치되는 400 줄 스크립트의 일부입니다.

# hugely truncated. 

    $this = @() # initialise results table as an array. 
    $ip = "myserver.mydomain.com" 


    foreach ($connected_nic in ($Adapter = Get-WmiObject -computer $ip win32_networkadapter -filter "NetConnectionStatus='2'" | where {$_.PNPDeviceID -notmatch "1394"})) { # Find electrically connected adapters, which are not firewire. 

    Write-host -ForegroundColor Green $Connected_nic 

    if ($cfg=($dns=(Get-WmiObject -ComputerName $ip Win32_NetworkAdapterConfiguration -filter "Index = '$($connected_nic.Index)'")).IPaddress -like "192.168.*") { # test each connected adapter to see if it's IP = 192.168.X.X 

    $ips = $dns | select -expandproperty Ipaddress 
    $dns # check return is as expected. 

    $results = [ordered] @{ 

    'Netbios Name' = $dns.DNSHostname 
    'IPv4 Address' = $ips[0] #cope with ipv6 
    'Subnet Mask' = [String]$dns.IpSubnet 
    'Default Gateway' = [String]$dns.DefaultIPGateway 
    'Primary DNS Server' = $dns.DNSServerSearchOrder[0] 
    'Secondary DNS Server' = $dns.DNSServerSearchOrder[1] 
    'MAC Address' = $dns.MACaddress 
    } 

    $dnsout = New-Object PSObject -Property $results # Create a new row for the report from our hash table. 
    $this += $dnsout # Add this row to the main report. 

    } # Configurations of interest test. 
    } # End connected adapter test 


    #output 



    Netbios Name   : server 
    IPv4 Address   : 192.168.228.54 
    Subnet Mask   : 255.255.255.0 
    Default Gateway  : 192.168.228.5 
    Primary DNS Server : 192.168.228.51 
    Secondary DNS Server : 192.168.224.51 
    MAC Address   : 00:23:7D:22:1C:52 

    Netbios Name   : server 
    IPv4 Address   : 192.168.228.54 
    Subnet Mask   : 255.255.255.0 
    Default Gateway  : 192.168.228.5 
    Primary DNS Server : 192.168.228.51 
    Secondary DNS Server : 192.168.224.51 
    MAC Address   : 00:23:7D:22:1C:52 

    Netbios Name   : server 
    IPv4 Address   : 192.168.228.54 
    Subnet Mask   : 255.255.255.0 
    Default Gateway  : 192.168.228.5 
    Primary DNS Server : 192.168.228.51 
    Secondary DNS Server : 192.168.224.51 
    MAC Address   : 00:23:7D:22:1C:52 


    Connected adapter configurations 

    DHCPEnabled  : False 
    IPAddress  : {192.168.228.54} 
    DefaultIPGateway : {192.168.228.5} 
    DNSDomain  : 
    ServiceName  : l2nd 
    Description  : HP NC373i Multifunction Gigabit Server Adapter #2 
    Index   : 2 

    DHCPEnabled  : False 
    IPAddress  : {192.168.1.1} 
    DefaultIPGateway : 
    DNSDomain  : 
    ServiceName  : VMnetAdapter 
    Description  : VMware Virtual Ethernet Adapter for VMnet1 
    Index   : 9 

    DHCPEnabled  : False 
    IPAddress  : {192.168.18.1} 
    DefaultIPGateway : 
    DNSDomain  : 
    ServiceName  : VMnetAdapter 
    Description  : VMware Virtual Ethernet Adapter for VMnet8 
    Index   : 10 

편집 세부 정보를 향상 시키려면 편집하십시오. 예에서 컴퓨터에는 3 개의 구성 결과 집합을 반환 할 유효한 네트워크 어댑터가 세 개 있습니다. 각 결과 집합은 해당 네트워크 어댑터에 고유하게 적용됩니다. 내 코드에서 디버그 로깅을 활성화하면 foreach 및 if 문이 3 가지 고유 한 결과를 원하고 반환 할 때 논리를 수행함을 알 수 있습니다. 내 문제는 출력 캡처가 예상대로 작동하지 않는다는 것입니다. 무슨 일이 일어나고 있는지 나는 모두 동일한 3 가지 결과로 끝을 맺고 있습니다. 이제 무언가가 비어 있고 첫 번째 결과 집합을 덮어 쓸 수 없다는 유혹에 빠질 수 있습니다. 그러나 이는 사실이 아닙니다. 분명히 세 가지 결과 세트를 얻고 있지만 해시 테이블을 만들려고 할 때 첫 번째 결과 집합 만 성공적으로 표기됩니다. 다음 번에 더 많은 결과를 AKA 덮어 쓰기하려고하면 null 배열로 인덱스 할 수 없으므로 실패합니다. 내 코드를 복사하고 활성화 된 하나 이상의 어댑터가있는 컴퓨터에서 실행하면 barf가됩니다. 바지가 아니고 해시 테이블의 첫 번째 결과 세트를 성공적으로 덮어 쓰는 방법을 알고 싶습니다. 그것은 질문입니다.

예 당신은 완전히 정확합니다 - 나와 함께 인내심을 가져 주셔서 감사합니다. 문제가 무엇인지 정확히 알 수 있습니다. 테스트 대상이 잘못 선택되었습니다. 코드가 실제로 괜찮습니다. 정말 고마워!

-ea 자동으로 계속 작동합니다. # 완벽하게 작동합니다.

+0

당신 "는 foreach 루프에서 재사용 해시 테이블"을 뜻하는 것 :

당신은 존재하지 않는 배열의 인덱스를 얻기 위해 시도하여 볼 수 있습니까? 반복 할 때마다 해시 테이블을 설정하는 유일한 장소 인 변수 $ 결과를 덮어 씁니다. –

+0

디버깅을 불가능하게 만들 때 모든 것을 인라인하지 말 것을 강력히 권합니다. foreach 루프 내에서 현재 $ connected_nic 이외의 다른 해시 테이블 멤버에 액세스하려는 경우 루프 내에서 참조 할 수있는 변수에 해시 테이블을 저장해야합니다. this() 배열 변수에 결과를 캐싱하는 FWIW는 powershell 반 패턴입니다. 새 객체를 파이프 라인에 놓고 format-table 또는 format-list 또는 심지어 export-csv가 나머지를 처리하도록해야합니다. –

+0

이것을 보아 주셔서 감사합니다. 결과를 파이프 라인에 배치하는 방법을 자세히 설명하고 format-xxxx가주의를 기울 이도록 할 수 있습니까? – Anthony1256

답변

1

귀하의 정보는 다소 모호합니다. 특정 오류 메시지가 나타나는 이유를 묻는 경우 또는 다른 방법을 묻는 경우 확실하지 않습니다.

'IPv4 Address' = $ips[0] #cope with ipv6 
'Primary DNS Server' = $dns.DNSServerSearchOrder[0] 
'Secondary DNS Server' = $dns.DNSServerSearchOrder[1] 

중 하나를 $ IP를 또는 $ 변수가 비어 또는 속성을 DNS : 오류 가능성이 다음과 같은 세 장소 중 하나에서 발생 - 어쨌든, 오류 메시지를 받고 왜 그냥 요구하는 가정 사용중인 것은 비어 있습니다. 수행중인 것처럼 인덱스를 가져 오려고하지만 배열이 존재하지 않으면보고있는 오류를 반환합니다.

$dontexist[5] 
+1

'DNSServerSearchOrder'는'$ dns' 객체의 유효한 속성이지만, 대부분의 nics에서는 비어 있습니다. 그것은 위의 코드를 사용하여 발생한 오류입니다. – Matt