Все виртуальные машины PowerCLI Информация выводится / Консоль и пользовательский объект не работают должным образом - PullRequest
0 голосов
/ 26 марта 2019

Я хочу получить все наши виртуальные машины с vSphere PowerCLI и получить их с некоторой дополнительной информацией. Но я не получаю вывод, работающий должным образом.

Я уже пробовал это как вывод на консоль, но потом не получаю имя с помощью os и IP-адреса

$Object = New-Object PSObject -Property @{
    Name = $name
    OS = $info.OSFullName
    IP = $info.IPAddress
    }

Connect-VIServer -Server VMServer -Credential admin -Password ASecretPWnoOneKnows

$allnames = Get-VM

foreach($name in $allnames)
{
    $info = Get-VMGuest $name | select OSFullName, IPAddress
    Add-Member -InputObject $Object
}

Это мой "лучший подход" на данный момент.

Мой результат должен выглядеть как

SomeVMname SomeOS SomeIP

но я получил только Length от всей строки или ошибки, так как я не обработал пользовательский объект должным образом:

Поэтому, если кто-то может помочь мне в любом случае, вывод на консоль или в объект, который я также могу экспортировать в CSV, я был бы очень рад с этим

Ответы [ 2 ]

2 голосов
/ 26 марта 2019

Вы уже очень близки к выполнению этой работы.Вам просто нужно переместить $object создание и извлечение внутри цикла ForEach.

Connect-VIServer -Server VMServer -Credential admin -Password ASecretPWnoOneKnows
$allnames = Get-VM

$Output = foreach($name in $allnames)
{
  $Object = [PSCustomObject][ordered]@{
    Name=$name.Name
    OS=$name.Guest.OSFullName
    IP=$name.Guest.IPAddress -match "\." -join " "
  }
  $Object
}
$Output # To output to the console
$Output | Export-Csv -path "file.csv" -NoTypeInformaton # Csv output

Полезный ответ А.В.Шалома ссылается на некоторые идеи, касающиеся обработки IPAddressсвойство и удаление ненужных команд, т.е. Get-VMGuest, для достижения желаемой цели.Он использует ярлык для создания объекта $row, который будет содержать свойства виртуальной машины.Тем не менее, при использовании метода замены массива и сложения $Report += Row есть некоторые недостатки, поскольку новый объект массива большего размера создается при каждой итерации цикла.Для небольших наборов данных это может не иметь значения, но для больших наборов это может оказаться значительным.

После создания [PSCustomObject] вы можете редактировать значение в свойствах, пока этот объект не уничтожени / или эти определения свойств остаются на объекте.Это означает, что вы можете иметь все новые значения (если хотите) для одинаковых свойств во время каждой итерации цикла.Я добавил атрибут [ordered], чтобы порядок вывода свойств $object оставался неизменным.

Я добавил переменную $Output для хранения значения $Object во время каждой итерации цикла.$Output становится массивом объектов с тремя свойствами, которые вы хотите отслеживать.Теперь ваш Export-Csv преобразует эти значения свойств в строки для вашего CSV-файла.

Я удалил команду Get-VMGuest, потому что переменная $name - это объект, который содержит всю информацию, которая вам уже нужна.Свойство Guest предоставляет информацию, которую предоставляет Get-VMGuest.

Вы можете преобразовать значение IPAddress в строку, поскольку могут быть случаи, когда существует более одного IP, поскольку это свойство является массивом.Вы можете выбрать только индексированное значение ($Name.Guest.IPAddress[0]);однако вы должны быть осторожны с этим, потому что IP-адрес (а), который вы хотите, может быть в другом индексе.Приведение [string] вернет все значения этого свойства, используя пробел.Вместо этого я использовал оператор -join и разделитель пробелов.IPAddress также может содержать адреса IPv6.Я хотел только захватить адреса IPv4, поэтому я использовал совпадение с регулярным выражением, например, $Name.Guest.IPAddress -match "\.", что соответствует буквальному символу ..Вы можете комбинировать несколько методов, чтобы получить нужные данные.

Рассмотрим следующий объект и примеры:

$name.guest

IPAddress                                     OSFullName
---------                                     ----------
{1.1.1.1, 2.2.2.2, fe80::ffff:ffff:ffff:ffff} Windows StackOverflow

$name.guest.IPAddress # Retrieves all IPs
1.1.1.1
2.2.2.2
fe80::ffff:ffff:ffff:ffff

$name.guest.IPAddress[0] # Retrieves the first IP in the array
1.1.1.1

$name.guest.IPAddress -match "\." # Retrieves all IPv4 IPs
1.1.1.1
2.2.2.2

$name.guest.IPAddress -match "\." -join " " # Retrieves all IPv4 separated by space
1.1.1.1 2.2.2.2

С тем, как ваш код структурирован, он выглядиткак будто вы пытаетесь создать свойства, значения которых являются ссылками, а не значениями.Поясним, что вам нужно обновить значения свойств для $Object, так как значения свойств $info автоматически изменят без явного присвоения.Я не знаю, было ли это вашим намерением, но я верю, что это усложнит то, что вы хотите достичь.Я не делал этого для вашего кода.Я устанавливаю значения свойств $Object явно каждый раз, когда цикл повторяется.

Я также не видел вашу команду Export-Csv;однако вы описали наличие вывода свойства Length.Это может произойти, когда вы Export-Csv с [string] объектом в качестве входного объекта.Поскольку целью Export-Csv является преобразование значений свойств в строки, единственным значением свойства обычной строки является Length.Так что этого следовало ожидать.Вы можете увидеть это поведение ниже:

$str = "this is a string"
($str | Get-Member).where({$_.MemberType -eq "Property"})


   TypeName: System.String

Name   MemberType Definition
----   ---------- ----------
Length Property   int Length {get;}
$str | ConvertTo-Csv
#TYPE System.String
"Length"
"16"
0 голосов
/ 26 марта 2019

Вам не нужно использовать Get-VMGuest для получения информации об ОС / IP, у вас уже есть Get-VM с использованием элемента свойства Guest:

Должно быть так просто:

Connect-VIServer -Server VMServer -Credential admin -Password ASecretPWnoOneKnows

$Report = @()
$VMs = Get-VM
foreach ($vm in $VMs)
{
$row = "" | Select Name,OSFullName,IP
$row.Name = $vm.name
$row.OSFullName = $vm.Guest.OSFullName
$row.IP = $vm.Guest.IPAddress[0]
$Report += $row
}
  • Обратите внимание, что IP-адрес может включать в себя более одного IP, например, IPV4 / V6, в примере я собираю первый [0] Вы можете использовать регулярные выражения для соответствия конкретному шаблону
...