Powershell 所有VM PowerCLI信息输出/控制台和自定义对象工作不正常

Powershell 所有VM PowerCLI信息输出/控制台和自定义对象工作不正常,powershell,powercli,Powershell,Powercli,我希望使用vSphere PowerCLI获取所有虚拟机,并将这些虚拟机输出一些附加信息。但是我没有让输出正常工作 我已经尝试过将其作为控制台输出,但是我没有得到带有操作系统和IP地址的名称 $Object = New-Object PSObject -Property @{ Name = $name OS = $info.OSFullName IP = $info.IPAddress } Connect-VIServer -Server VMServer -C

我希望使用vSphere PowerCLI获取所有虚拟机,并将这些虚拟机输出一些附加信息。但是我没有让输出正常工作

我已经尝试过将其作为控制台输出,但是我没有得到带有操作系统和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
但由于没有正确处理自定义对象,我只得到了整个字符串或错误的
长度:


因此,如果有人能以任何一种方式帮助我,将控制台输出或输出到一个我也可以输出到csv的对象中,我将非常高兴

您已经非常接近于实现这一目标了。只需将
$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
。但是,使用数组替换加加法技术存在固有的低效性,因为每次循环迭代时都会创建一个较大的新数组对象。对于较小的数据集,这可能无关紧要,但对于较大的数据集,这可能是非常重要的

创建
[PSCustomObject]
后,只要对象未被销毁和/或那些属性定义保留在对象上,就可以编辑属性中的值。这意味着您可以在循环的每次迭代期间为相同属性设置所有新值(如果愿意)。我添加了
[ordered]
属性,以便
$object
属性顺序在输出中保持一致

我添加了
$Output
变量来存储循环每次迭代期间
$Object
的值
$Output
成为一个对象数组,其中包含要跟踪的三个属性。现在,您的
导出Csv
将把这些属性值转换为Csv文件的字符串

我删除了
Get-VMGuest
命令,因为
$name
变量是一个包含您已经需要的所有信息的对象。
Guest
属性提供了
Get-VMGuest
提供的信息

您可以将
IPAddress
值强制转换为字符串,因为有时可能存在多个IP,因为该属性是数组。您可以选择只获取一个索引值(
$Name.Guest.IPAddress[0]
);但是,您必须小心,因为您想要的IP地址可能位于另一个索引中。
[string]
cast将使用空格分隔符返回该属性的所有值。我使用了
-join
操作符,并使用了空格分隔符<代码>IP地址
也可能包含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
属性值

我也没有看到您的
导出Csv
命令;但是,您描述了具有
Length
属性的输出。当您使用
[string]
对象作为输入对象导出Csv时,可能会发生这种情况。由于导出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"

你已经非常接近完成这项工作了。只需将
$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
。但是,使用数组替换加加法技术存在固有的低效性,因为每次循环迭代时都会创建一个较大的新数组对象。对于较小的数据集,这可能无关紧要,但对于较大的数据集,这可能是非常重要的

创建
[PSCustomObject]
后,只要对象未被销毁和/或那些属性定义保留在对象上,就可以编辑属性中的值。这意味着您可以在循环的每次迭代期间为相同属性设置所有新值(如果愿意)。我添加了
[ordered]
属性,以便
$object
属性顺序在输出中保持一致

我添加了
$Output
变量来存储循环每次迭代期间
$Object
的值
$Output
成为一个对象数组,其中包含要跟踪的三个属性。现在,您的
导出Csv
将把这些属性值转换为Csv文件的字符串

我快速眼动