2015-11-19 4 views
1

Итак, у меня возникла проблема, перечислимая через цикл forEach в PowerShell (v3) и добавление оцениваемой переменной, а также результат тестового соединения в массив. Я пытаюсь сделать $ arrPing многомерным массивом, так как это облегчит мне фильтрацию и обработку объектов там позже в скрипте, но я сталкиваюсь с проблемами с кодом.PowerShell - Не создает Jagged Array в цикле forEach

Мой код выглядит следующим образом:

$arrPing= @(); 
$strKioskIpAddress= (Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPAddress -ne $null }).ipaddress 

...FURTHER DOWN THE CODE... 

$tmpIpAddress= Select-Xml -Path $dirKioskIpAddresses -XPath '//kiosks/kiosk' | Select-Object -ExpandProperty Node 

forEach ($entry in $tmpIpAddress) 
    { 
    if ($entry -ne $strKioskIpAddress) 
     { 
     $result= Test-Connection -ComputerName $entry -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue 
     $arrPing+= @($entry,$result); 
     } 
    } 

Но я получаю следующий результат, когда я отобразить содержимое переменной $ arrPing:

PS H:\Documents\PowerShell Scripts> $arrPing 
10.216.1.134 
True 
10.216.1.139 
True 
10.216.23.230 
True 
10.216.23.196 
False 
10.216.23.23 
False 

Может кто-нибудь сказать мне, где я «Не так? У меня есть ощущение, что это происходит потому, что я нахожусь в цикле ForEach, но я просто не могу сказать наверняка ...

+0

Ну, массивы в пределах $ arrPing будет иметь два значения данных в них, но это динамический массив так что технически это будет классифицироваться как зазубренный я полагаю. В идеале я просто хочу, чтобы данные были сопряжены вместе - этот скрипт предназначен для загрузки на тысячи компьютеров, и он будет использовать эти данные и попытаться выполнить некоторые команды FTP для извлечения файла. Эти данные будут использоваться для фильтрации компьютеров, которые не находятся в сети (по разным причинам), или отключены, поэтому отображение вывода в формате таблицы не имеет значения. – Fredulom

ответ

2

Вы видите, как PowerShell разворачивает массивы. Переменная сконструирована так: большой массив. Однако PowerShell при их отображении помещает каждый элемент в свою собственную строку. Если вы этого не хотите, и особенно если вы собираетесь использовать Эти данные будут использоваться для фильтрации компьютеров, которых нет в сети, тогда вы должны использовать объекты PowerShell.

if ($entry -ne $strKioskIpAddress){ 
    $objPing += New-Object -TypeName psobject -Property @{ 
     Entry = $entry 
     Result = Test-Connection -ComputerName $entry -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue 
    } 
} 

Вместо того, что те, я буду продолжать и использовать различные foreach contruct, который является более дружественным трубопровода. Таким образом, вы можете использовать другие командлеты, например Export-CSV, если вам нужен этот вывод в других местах. Также ложь PetSerAl говорит

[Y] ou не должен использовать оператор добавления массива и добавлять элементы один за другим. Он [будет] создавать [новый] массив (поскольку массивы не изменяются по размеру) и копировать элементы из [старого] на каждую операцию.

$tmpIpAddress | Where-Object{$_ -ne $strKioskIpAddress} | ForEach-Object{ 
    New-Object -TypeName psobject -Property @{ 
     Entry = $_ 
     Result = Test-Connection -ComputerName $_ -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue 
    } 
} | Export-CSV -NoTypeInformation $path 

The if избыточна теперь, когда мы переехали в эту логику Where-Object, так как вы использовали это делать отфильтровывать определенные записи в любом случае. Это то, что подходит для Where-Object.

Приведенный выше код подходит для PowerShell 2.0. Если у вас есть 3.0 или более поздней версии, то используйте [pscutomobject] и [ordered]

$tmpIpAddress | Where-Object{$_ -ne $strKioskIpAddress} | ForEach-Object{ 
    [psobject][ordered] @{ 
     Entry = $_ 
     Result = Test-Connection -ComputerName $_ -Count 1 -BufferSize 16 -Quiet -ErrorAction SilentlyContinue 
    } 
} | Export-CSV -NoTypeInformation $path 
+0

И если я хочу добавить это в переменную ко второму или третьему разделам кода вашего ответа (вместо экспортируя результаты в файл .csv), тогда я просто добавлю «$ [VARIABLE_NAME] =» к началу этого и удалю команду «Export-Csv», правильно? – Fredulom

+0

@Fredulom Oh. Я вижу сейчас. Да. Это все, что вам нужно. Это просто хэш-таблица @ {} пар ключевых значений. Поэтому, если вы хотите, вы можете посмотреть их. Вам не нужно использовать '$' для объявления ключа. Просто убедитесь, что все объекты имеют одинаковые наборы свойств или они не будут сгруппированы должным образом. – Matt

+0

Удивительный, это здорово :) Спасибо за вашу помощь @Matt! – Fredulom

3

Я бы упростить его немного с помощью PSCustomObject:

$Ping = foreach ($Entry in $tmpIpAddress) { 
    if ($Entry -ne $strKioskIpAddress) { 
     $TestParams = @{ 
      ComputerName = $Entry 
      Count  = '1' 
      BufferSize = '16' 
      Quiet  = $true 
      ErrorAction = 'SilentlyContinue' 
     } 
     $Result = Test-Connection @TestParams 
     [PSCustomObject]@{ 
      Entry = $Entry 
      Result = $Result 
     } 
    } 
} 

$Ping 

Чтобы избежать длинного ряда параметров, я использовал метод, называемый splatting.

+0

Возможно, добавьте ссылку на about_splatting – Matt

+0

Привет @ DarkLite1, я взгляну на splatting, поскольку я не видел или не слышал, как этот метод используется раньше.Спасибо :) – Fredulom

+0

@Fredulom Это отлично подходит для повторных вызовов одного и того же командлета! Или если вам нужно сделать динамические вызовы с одним командлетом. '$ TestParams.Count = 3', например. – Matt

 Смежные вопросы

  • Нет связанных вопросов^_^