#powershell
#powershell
Вопрос:
Я пытаюсь получить список vm
из nutanix
с name, ipaddress,
Получаемый мной результат включает ip-адрес с фигурными скобками, который выдает вывод в виде System.String[]
Я взял все значения из массива с помощью цикла for, затем экспортировал значения в csv
Сценарий, который я написал, выглядит следующим образом-
foreach ($vmachine in $vm){
$obj = "" | Select "vmName", "ipAddresses", "description", "protectionDomainName", "powerState"
$obj.vmName = $vmachine.vmName
$obj.ipAddresses = $vmachine.ipAddresses
$obj.description = $vmachine.description
$obj.protectionDomainName = $vmachine.protectionDomainName
$obj.powerState = $vmachine.powerState
$outArrayVM = $obj
$obj =$null
}
$outArrayVM | Export-Csv d:z.csv
Ожидаемый результат должен быть таким, как ip-адрес 10.x.x.x
, но я получаю @{ipAddresses=System.String[]}
Ответ №1:
Это происходит потому, что $vmachine.ipAddresses
является объектом string array. Вам нужно строковое представление этого с контролируемым форматированием. Есть много способов добиться этого. Вот один, который будет объединять несколько IP-адресов (если они существуют) с помощью ;
. Если указан только один IP, он будет отображаться без точки с запятой:
$obj.ipAddresses = $vmachine.ipAddresses -join ";"
Вот пример вашего сценария:
$ip = @("10.1.23.45")
$ip.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
$obj.name = "test"
$obj.ip = $ip
$obj
name ip
---- --
test {10.1.23.45}
$obj | convertto-csv
#TYPE Selected.System.String
"name","ip"
"test","System.Object[]"
Преобразование ip
свойства $obj
в строку заставляет PowerShell интерпретировать свойство как строку, а не как коллекцию. Таким образом, обозначение фигурных скобок ( {}
) исчезает.
$obj.ip = $ip -join ";"
$obj | convertto-csv
#TYPE Selected.System.String
"name","ip"
"test","10.1.23.45"
Вот несколько других альтернатив для установки ip
значения свойства в виде строки:
$obj.ip = -join $ip # No join character here. Works best with only one IP.
$obj.ip = $ip[0] # Accesses first element of array $ip, which will be a string. Only works with one IP.
$obj.ip = [string]$ip # Uses string type accelerator to cast $ip as string. This will join multiple IPs with a space between each IP.
Объяснение:
При запуске ConvertTo-Csv
или Export-Csv
свойство объекта ввода преобразуется с помощью ToString()
метода. Если ссылочный тип этого свойства объекта ( System.Array
в данном случае) не имеет переопределения для ToString()
метода, то этот метод вернет полное имя типа свойства. В данном случае этот FQTN равен System.Object[]
. Это предсказуемо, если немного покопаться.
При тестировании с [Int32]
можно было бы ожидать, что преобразование строки обеспечит строковое представление целочисленных данных, поскольку оно имеет переопределение:
$int = 1
$int.gettype().fullname
System.Int32
($int | Get-Member).where{$_.Name -eq "ToString"}
TypeName: System.Int32
Name MemberType Definition
---- ---------- ----------
ToString Method string ToString(), string ToString(string format), string ToString(System.IFormatProvider provid...
$int.ToString()
1
$int.ToString().gettype().fullname
System.String
При тестировании с помощью [Array]
вы бы не ожидали, что преобразование строк обеспечит строковое представление данных массива, поскольку оно не имеет переопределения:
$arr = [array]1
$arr.gettype().fullname
System.Object[]
([System.Object[]] | Get-Member -Static).where{$_.name -eq "ToString"}
$arr.toString()
System.Object[]
Смотрите раздел Экспорт-Csv и объект.Метод toString для дополнительных пояснений и примеров.