简体   繁体   中英

Powershell Re-Use a hash Table foreach loop

I am very new to PowerShell and I suspect as I am not a programmer the cause of my problem is probably something quite obvious to most of you. Basically my script errors with

"Cannot index into a null array."

It's looping to gather properties of each network adapter in statically configured multihomed servers. My debug statements show that the foreach and if work as expected - but it seems like I can't re-use the hash table in the foreach loop. What is the correct method here? (Note: this is part of a 400 line script that is heavily centred around the hash table so I need to use hash tables if at all possible).

    # 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

Edit to increase details. In the example the computer has three valid network adapters which are going to return three sets of configuration results. Each set of results will be specifically unique to that network adapter. When I enable debug logging in my code I can see that the foreach and if statements are doing their logic as I want and returning three sets of unique results. My problem is that capturing the output is not working as expected. What is happening is that I am ending up with three sets of results that are all identical. Now, you might be tempted to state that something is therefore empty and can't overwrite the first set of results - however - that is not true. I am definitely getting three different sets of results but when I try to hash table these only the first set of results are successfully tabled. The next time I try to add more results AKA overwrite - it fails with cannot index into a null array. Just copy my code and run it against any computer with more than one adapter which is active and it will barf. I want to know how to make it not barf and successfully overwrite the first set of results in the hash table. That is the question.

Yes you are perfectly correct - thank you for your patience with me. I see now precisely what the issue is - my test subject happened to be a poor choice. The code was actually fine. Thanks so much!

-ea silently continue # works perfectly.

Your information is rather vague. I am not sure if you are asking why you are receiving a specific error message or if you are asking how to do something else. Anyways, assuming you are just asking why you are receiving the error message - the error is likely occurring in one of the following 3 places:

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

Either the $ips or $dns variables are empty, or the properties you are using are empty. When you try to get the index like you are doing, but the array doesn't exist it will return the error you are seeing.

You can see this by just attempting to get the index of a non-existent array:

$dontexist[5]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM