Powershell повторно использовать хэш-таблицу для каждого цикла

Я новичок в PowerShell и подозреваю, что, поскольку я не программист, причина моей проблемы, вероятно, в чем-то совершенно очевидном для большинства из вас. В основном мои ошибки сценария с

«Невозможно проиндексировать в нулевой массив».

Это цикл для сбора свойств каждого сетевого адаптера на статически настроенных многосетевых серверах. Мои отладочные операторы показывают, что 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

Отредактируйте, чтобы увеличить детали. В этом примере на компьютере есть три действительных сетевых адаптера, которые будут возвращать три набора результатов конфигурации. Каждый набор результатов будет уникальным для данного сетевого адаптера. Когда я включаю ведение журнала отладки в своем коде, я вижу, что операторы foreach и if выполняют свою логику так, как я хочу, и возвращают три набора уникальных результатов. Моя проблема в том, что захват вывода работает не так, как ожидалось. Что происходит, так это то, что я получаю три набора результатов, которые все идентичны. Теперь у вас может возникнуть соблазн заявить, что что-то пустое и не может перезаписать первый набор результатов, однако - это неверно. Я определенно получаю три разных набора результатов, но когда я пытаюсь создать хеш-таблицу, успешно отображается только первый набор результатов. В следующий раз, когда я попытаюсь добавить больше результатов AKA overwrite - он не может выполнить индексирование в нулевой массив. Просто скопируйте мой код и запустите его на любом компьютере с более чем одним активным адаптером, и он отключится. Я хочу знать, как сделать так, чтобы он не прерывался и успешно перезаписывал первый набор результатов в хеш-таблице. Вот в чем вопрос.

Да, вы совершенно правы - спасибо за ваше терпение. Теперь я точно понимаю, в чем проблема - мой испытуемый оказался плохим выбором. Код действительно был в порядке. Большое спасибо!

-ea silently continue # работает отлично.


person Anthony1256    schedule 03.10.2014    source источник
comment
Что вы имеете в виду повторно использовать хеш-таблицу в цикле foreach? Каждый раз, когда вы проходите цикл, вы перезаписываете переменную $ results, которая является единственным местом, где вы устанавливаете хеш-таблицу.   -  person Noah Sparks    schedule 03.10.2014
comment
Я настоятельно рекомендую вам не пытаться встроить все, так как это делает отладку практически невозможной. Если в цикле foreach вы хотите получить доступ к любому члену хеш-таблицы, кроме текущего $ connected_nic, вам необходимо сохранить хеш-таблицу в переменной, на которую вы можете ссылаться из цикла. FWIW, кэширующий ваши результаты в переменной массива this (), является антипаттерном PowerShell. Вам нужно просто поместить свой новый объект в конвейер, а об остальном позаботиться format-table, format-list или даже export-csv.   -  person Stephen Connolly    schedule 03.10.2014
comment
Спасибо, что посмотрели на это - не могли бы вы подробнее рассказать, как я бы поместил свои результаты в конвейер и позволил бы format-xxxx позаботиться о том, как вы говорите?   -  person Anthony1256    schedule 03.10.2014
comment
Ваше предложение по редактированию моего сообщения должно было быть комментарием. Я уже объяснил, почему это не работает, и Мэтт подробно рассказал. Это потому, что $ dns.dnsserversearchorder пуст, нет массива для индексации. Запустите свой сценарий в ise, затем просто введите $ dns.dnsserversearchorder [0] в консоли, и вы получите сообщение об ошибке, из-за которой ваш сценарий завершился неудачно, и убедитесь, что мы правы. Проблема в том, что вы возвращаете сетевые устройства, у которых это свойство пусто, и вам необходимо отфильтровать их, прежде чем пытаться построить хеш-таблицу.   -  person Noah Sparks    schedule 03.10.2014
comment
Да, вы совершенно правы - спасибо за ваше терпение. Теперь я точно понимаю, в чем проблема - мой испытуемый оказался плохим выбором. Код действительно был в порядке. Большое спасибо! -ea silently continue # работает отлично.   -  person Anthony1256    schedule 04.10.2014
comment
Добро пожаловать, мы рады помочь!   -  person Noah Sparks    schedule 06.10.2014


Ответы (1)


Ваша информация довольно расплывчата. Я не уверен, спрашиваете ли вы, почему вы получаете конкретное сообщение об ошибке, или спрашиваете, как сделать что-то еще. В любом случае, предполагая, что вы просто спрашиваете, почему вы получаете сообщение об ошибке, ошибка, скорее всего, возникает в одном из следующих 3 мест:

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

Либо переменные $ ips или $ dns пусты, либо используемые вами свойства пусты. Когда вы пытаетесь получить индекс, как вы это делаете, но массив не существует, он вернет ошибку, которую вы видите.

В этом можно убедиться, просто попытавшись получить индекс несуществующего массива:

$dontexist[5]
person Noah Sparks    schedule 03.10.2014
comment
Хотя DNSServerSearchOrder является допустимым свойством объекта $dns, на большинстве моих сетевых устройств оно пусто. Вот откуда возникает ошибка из-за использования приведенного выше кода. - person Matt; 03.10.2014