所有 VM PowerCLI 信息输出/控制台和自定义对象均无法正常工作
All VMs PowerCLI Info output /Console and Custom Object Not Working Properly
我想使用 vSphere PowerCLI 获取我们所有的 VM,并在 ose 中输出一些附加信息。但是我没有让输出正常工作。
我已经尝试将它作为控制台输出,但后来我没有得到带有 os 和 IPAddress
的名称
$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
}
到目前为止,这是我的"best approach"。
我的结果应该像
SomeVMname SomeOS SomeIP
但到目前为止我只得到了总字符串的 Length
或错误,因为我没有正确处理自定义对象:
因此,如果有人可以帮助我,控制台输出或我也可以导出到 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
。但是,使用数组替换和添加技术 $Report += Row
存在固有的低效率,因为每次循环迭代时都会创建一个更大的新数组对象。对于较小的数据集,这可能无关紧要,但对于较大的数据集,这可能很重要。
创建 [PSCustomObject]
后,只要该对象未被销毁,您就可以编辑属性中的值 and/or 这些 属性 定义保留在对象上。这意味着您可以在循环的每次迭代期间为 相同的属性 获得所有新值(如果您愿意)。我添加了 [ordered]
属性,以便 $object
属性 顺序在您的输出中保持一致。
我添加了 $Output
变量以在循环的每次迭代期间存储 $Object
的值。 $Output
成为具有您要跟踪的三个属性的对象数组。现在,您的 Export-Csv
会将这些 属性 值转换为 CSV 文件的字符串。
我删除了 Get-VMGuest
命令,因为 $name
变量是一个包含您已经需要的所有信息的对象。 Guest
属性 提供 Get-VMGuest
提供的信息。
您可以将 IPAddress
值转换为字符串,因为有时会有多个 IP,因为 属性 是一个数组。您可以选择只获取一个索引值 ($Name.Guest.IPAddress[0]
);但是,您必须小心,因为您想要的 IP 地址可能在另一个索引中。 [string]
转换将 return 使用 space 分隔符的 属性 的所有值。我改用了 -join
运算符并使用了 space 定界符。 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 Whosebug
$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"
您不需要使用 Get-VMGuest
来获取 OS/IP 信息,您已经使用 Guest
属性 成员通过 Get-VM
获得了它:
应该就这么简单:
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]
你可以使用正则表达式来匹配特定的模式
我想使用 vSphere PowerCLI 获取我们所有的 VM,并在 ose 中输出一些附加信息。但是我没有让输出正常工作。
我已经尝试将它作为控制台输出,但后来我没有得到带有 os 和 IPAddress
的名称$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
}
到目前为止,这是我的"best approach"。
我的结果应该像
SomeVMname SomeOS SomeIP
但到目前为止我只得到了总字符串的 Length
或错误,因为我没有正确处理自定义对象:
因此,如果有人可以帮助我,控制台输出或我也可以导出到 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
。但是,使用数组替换和添加技术 $Report += Row
存在固有的低效率,因为每次循环迭代时都会创建一个更大的新数组对象。对于较小的数据集,这可能无关紧要,但对于较大的数据集,这可能很重要。
创建 [PSCustomObject]
后,只要该对象未被销毁,您就可以编辑属性中的值 and/or 这些 属性 定义保留在对象上。这意味着您可以在循环的每次迭代期间为 相同的属性 获得所有新值(如果您愿意)。我添加了 [ordered]
属性,以便 $object
属性 顺序在您的输出中保持一致。
我添加了 $Output
变量以在循环的每次迭代期间存储 $Object
的值。 $Output
成为具有您要跟踪的三个属性的对象数组。现在,您的 Export-Csv
会将这些 属性 值转换为 CSV 文件的字符串。
我删除了 Get-VMGuest
命令,因为 $name
变量是一个包含您已经需要的所有信息的对象。 Guest
属性 提供 Get-VMGuest
提供的信息。
您可以将 IPAddress
值转换为字符串,因为有时会有多个 IP,因为 属性 是一个数组。您可以选择只获取一个索引值 ($Name.Guest.IPAddress[0]
);但是,您必须小心,因为您想要的 IP 地址可能在另一个索引中。 [string]
转换将 return 使用 space 分隔符的 属性 的所有值。我改用了 -join
运算符并使用了 space 定界符。 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 Whosebug
$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"
您不需要使用 Get-VMGuest
来获取 OS/IP 信息,您已经使用 Guest
属性 成员通过 Get-VM
获得了它:
应该就这么简单:
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]
你可以使用正则表达式来匹配特定的模式