Вывод массива массивов в Powershell / Powercli усекается с эллипсами
Цель моего сценария - получить весь список виртуальных машин от нашего vcenter, проверить, есть ли у них записи DNS - если запись dns равна нулю, то вывести имя виртуальной машины и соответствующий IP-адрес. Довольно просто, но меня смущает объединение массива имен виртуальных машин с массивом IP-адресов. Вот что я имею в виду:
$mainArray = @()
$vmArray = @()
$ipArray = @()
$vms = Get-VM | select Name, @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, @{N="IPAddress"; E={$_.Guest.IPAddress[0]}}
foreach ($vm in $vms)
{
$dnsname = $vm.DnsName
$ipaddr = $vm.IPAddress
$vmname = $vm.Name
if (!$vm.DNSName) #if DNS name is null
{
$vmArray += $vmname
$ipArray += $ipaddr
}
}
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'VM Name' -Value $vmArray
$item | Add-Member -type NoteProperty -Name 'IP Address' -Value $ipArray
$mainArray += $item
$mainArray | ft -wrap -autosize
Это выводит два столбца рядом друг с другом, но вывод разделяется запятыми и усекается эллипсом. Я знаю, что есть лучший способ сделать это, поэтому я открыт для предложений. Также было бы интересно узнать, как сделать эту работу только для моего собственного понимания. Ценю помощь всех.
2 ответа
Ваша основная проблема заключается в том, что вы заполняете массив вне цикла. У меня сейчас нет доступа к PowerCLI, но мы должны быть в состоянии удалить большую часть этого кода, так как он кажется избыточным и ненужным. Продолжая после $vms
быть объявленным
$vms | Where-Object{!$_.DNSName} | ForEach-Object{
New-Object PSObject -Property @{
'VM Name' = $_.Name
'IP Address' = $_.IPAddress
}
} | ft -wrap -autosize
Прежде чем вы сделали два массива. Один для имен, а другой для ips. Затем вы взяли эти 2 массива и сделали один объект с этими двумя свойствами. Я убрал необходимость в операторе if с Where-Object{!$_.DNSName}
, Теперь все обрабатываемые объекты - это те, которые вам нужны.
Вы действительно можете сделать это в одну / две строки, используя ту же логику.
Get-VM | Select @{N='VM Name';E={$_.Name}}, @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, @{N="IP Address"; E={$_.Guest.IPAddress[0]}} |
Where-Object{!$_.DNSName} | Select "VM Name","IP Address" | Format-Table -wrap -autosize
Опять же, я не могу проверить, но это должно работать. Если есть какие-либо ошибки, они должны быть легко исправимы. Предполагая, что я разобрался с вашей проблемой в первую очередь.
Об эллипсах
PowerShell имеет переменную $FormatEnumerationLimit
это определяет, сколько элементов массива отображается в выводе консоли. Есть хорошая статья, которая обсуждает это на TechNet
По умолчанию $FormatEnumerationLimit
установлено на 4
Мэтт, я нашел эту ссылку ранее, но не нашел ее очень полезной, поскольку она искажает вывод и не разбивает значения по строкам. Вот как я смог заставить оригинальный скрипт работать:
$i=0
write-output $vmArray |
foreach {
new-object psobject -property @{
VMName = $_
IPAddress = $ipArray[$i++]
}
} | ft -auto -wrap
Скорее нетрадиционно, но, тем не менее, работает. Там действительно должен быть более простой способ объединить массив бок о бок, но я отвлекся. Большое спасибо, Мэтт.
Обновление: это, вероятно, более условно:
For($i=0;$i -lt $vmArray.Count;$i++)
{
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'VM Name' -Value $vmArray[$i]
$item | Add-Member -type NoteProperty -Name 'IP Address' -Value $ipArray[$i]
$mainArray += $item
}
$mainArray | ft -wrap -autosize