1

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.

6
  • What do you mean "reuse hash table in the foreach loop"? Everytime you cycle through the loop you overwrite the variable $results which is the only place you are establishing a hash table. Commented Oct 3, 2014 at 13:23
  • I would strongly recommend you don't try to inline everything as it makes debugging nigh on impossible. If within the foreach loop you want to access any member of hash table other than the current $connected_nic then you need to store the hashtable in a variable that you can reference from within the loop. FWIW caching up your results in your this() array variable is a powershell antipattern. You should just put your new object on the pipeline and let format-table or format-list or even export-csv take care of the rest. Commented Oct 3, 2014 at 14:22
  • Thanks for looking at this - Can you elaborate on how I would place my results onto the pipeline and let format-xxxx take care as you say? Commented Oct 3, 2014 at 18:03
  • Your edit suggestion to my post should have been a comment. I already explained why this isn't working and Matt elaborated. It is because $dns.dnsserversearchorder is empty, there is no array to index. Run your script in ise then simply type $dns.dnsserversearchorder[0] in the console portion and you will get back the error that is causing your script to fail and see that we are correct. The problem is that you are returning nics that have this property empty and you need to filter those out before attempting to build your hash table. Commented Oct 3, 2014 at 18:52
  • 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. Commented Oct 4, 2014 at 3:23

1 Answer 1

1

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]
Sign up to request clarification or add additional context in comments.

1 Comment

While DNSServerSearchOrder is a valid property of the $dns object it is empty on most of my nics. That is where the error is coming from from using the above code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.