powershell - All VMs PowerCLI Info output /Console and Custom Object Not Working Properly
问题描述
I want to to get all our VMs with the vSphere PowerCLI and get those outputed with some additional info. But i don't get the output working properly.
I tried it as Console output already but then i dont get the name with the os and 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
}
This is my "best approach" so far.
My result should look like
SomeVMname SomeOS SomeIP
but I only got so far the Length
of the total String or error as I don't handle the custom object properly:
Therefore if someone can help me either way, Console output or into a object which i can also export to csv I would be really happy with it
解决方案
你已经非常接近完成这项工作了。您只需要在循环$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
AVShalom 的有用答案暗示了一些关于处理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"
推荐阅读
- python - 根据文件中的数据计算平均高度
- angular - 如何在角材料表中获得选定区域?
- python - 如何通过请求库将 Curl 命令更改为 Python3?
- c++ - 即使您没有将结构显式定义为指针,为什么还要使用 -> 来访问结构成员变量?
- javascript - 如何在 Rails 5 上的 ruby 中添加人脸识别?
- javascript - 如何防止 JavaScript 动画出现奇怪的震动
- mapbox - MapBox- BasicNetwork.performRequest:意外响应代码 403
- javascript - 我们如何在 Angular 8 中将数据从一个组件发送到另一个同级组件?
- python - Python:如何尽可能快地发送更多请求?
- deployment - 如何在 Uffizzi 上设置我的 API 服务?