简体   繁体   English

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

[英]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. 我想使用vSphere PowerCLI获取所有虚拟机,并输出一些其他信息。 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 我已经尝试将其作为控制台输出,但是随后我没有获得带有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
}

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: 但到目前为止,由于我无法正确处理自定义对象,我只能得到String或错误总数的Length

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 因此,如果有人可以通过控制台输出或我可以导出为csv的对象来帮助我,我将对此感到非常满意

You are very close to making this work already. 您已经非常接近完成这项工作。 You just need to move the $object creation and retrieval inside of your ForEach loop. 您只需要在$object ForEach循环中移动$object创建和检索。

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's helpful answer alludes to some of the ideas regarding handling the IPAddress property and the removal of unnecessary commands, ie Get-VMGuest , to reach the desired goal. AVShalom的有用答案暗示了一些有关处理IPAddress属性和删除不必要的命令(例如Get-VMGuest的想法,以实现所需的目标。 He uses a shortcut method for creating the object $row that will hold the virtual machine properties. 他使用快捷方式创建对象$row ,该对象将保存虚拟机属性。 However, there are inherent inefficiencies with using array replacement plus addition technique $Report += Row because a new array object of larger size is created each time the loop iterates. 但是,使用数组替换和附加技术$Report += Row会固有地效率低下,因为每次循环迭代时都会创建一个较大的新数组对象。 For smaller data sets, this may not matter, but for larger ones, this could prove significant. 对于较小的数据集,这可能并不重要,但是对于较大的数据集,这可能证明很重要。

Once the [PSCustomObject] is created, you can edit the value in the properties as long as that object is not destroyed and/or those property definitions remain on the object. 一旦创建了[PSCustomObject] ,就可以在属性中编辑该值,只要该对象没有被破坏和/或那些属性定义保留在该对象上即可。 This means you can have all new values (if you wish) for the same properties during each iteration of the loop. 这意味着您可以在循环的每次迭代期间为相同的属性拥有所有新值(如果需要)。 I added the [ordered] attribute so that the $object property order would remain consistent in your output. 我添加了[ordered]属性,以便$object属性顺序在您的输出中保持一致。

I added the $Output variable to store the value of $Object during each iteration of the loop. 我添加了$Output变量以在循环的每次迭代期间存储$Object的值。 $Output becomes an array of objects with the three properties you want to track. $Output成为具有您要跟踪的三个属性的对象的数组。 Now your Export-Csv will convert those property values into strings for your CSV file. 现在,您的Export-Csv会将这些属性值转换为CSV文件的字符串。

I removed the Get-VMGuest command because the $name variable is an object that contains all the information you already need. 我删除了Get-VMGuest命令,因为$name变量是一个对象,其中包含您已经需要的所有信息。 The Guest property provides the information that Get-VMGuest provides. Guest属性提供了Get-VMGuest提供的信息。

You could cast the IPAddress value to string because there could be times where there is more than one IP since that property is an array. 您可以将IPAddress值转换为字符串,因为由于该属性是一个数组,因此有时可能会有多个IP。 You can choose to grab just an indexed value ( $Name.Guest.IPAddress[0] ); 您可以选择仅获取索引值( $Name.Guest.IPAddress[0] ); however, you must be careful with this because the IP address(es) you want, may be at another index. 但是,您必须注意这一点,因为所需的IP地址可能在另一个索引中。 The [string] cast will return all values of that property using a space delimiter. [string]强制转换将使用空格分隔符返回该属性的所有值。 I used the -join operator instead and used a space delimiter. 我改用-join运算符,并使用空格定界符。 IPAddress may also contain IPv6 addresses. IPAddress也可能包含IPv6地址。 I only wanted to capture IPv4 addresses, so I used a Regex match, eg $Name.Guest.IPAddress -match "\\." 我只想捕获IPv4地址,因此我使用了Regex匹配项,例如$Name.Guest.IPAddress -match "\\." , which matches the literal . ,它与文字匹配. character. 字符。 You can combine multiple techniques to get the data you want. 您可以结合多种技术来获取所需的数据。

Consider the following object and examples: 请考虑以下对象和示例:

$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

With the way your code was structured, it appeared as though you were trying to create properties whose values are by reference rather than by value. 通过代码的结构方式,似乎就像您试图创建其值是通过引用而不是按值创建的属性一样。 To explain further, it appears that you want the property values for $Object to update as the $info property values change automatically without an explicit assignment. 为了进一步说明,您似乎希望$Object的属性值更新,因为$info属性值会在没有显式分配的情况下自动更改。 I do not know if that was your intention, but I believe that would add complexity to what you want to accomplish. 我不知道这是否是您的意图,但我相信这会增加您要完成的工作的复杂性。 I did not do this for your code. 我没有为您的代码执行此操作。 I am setting the $Object property values explicitly each time the loop iterates. 我每次循环迭代时都会显式设置$Object属性值。

I also did not see your Export-Csv command; 我也没有看到您的Export-Csv命令; however, you described having an output of the Length property. 但是,您描述了具有Length属性的输出。 That can happen when you Export-Csv with a [string] object as the input object. 当使用[string]对象作为输入对象的Export-Csv时,可能会发生这种情况。 Since the purpose of Export-Csv is to convert property values into strings, the only property value of a regular string is Length . 由于Export-Csv的目的是将属性值转换为字符串,因此常规字符串的唯一属性值是Length So that is to be expected. 因此,这是可以预期的。 You can see this behavior below: 您可以在下面看到此行为:

$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"

You don't need to use Get-VMGuest to get OS/IP information, you already have it with Get-VM using the Guest property member: 您不需要使用Get-VMGuest来获取OS / IP信息,而使用Guest属性成员的Get-VM已经具有该信息:

Should be as simple as that: 应该像这样简单:

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
}
  • Note that the IPAddress may include more then one IP, eg IPV4/V6, in the example I collect the first one [0] You can use regex to match specific pattern 请注意,IPAddress可能包含一个以上的IP,例如IPV4 / V6,在该示例中,我收集了第一个[0]您可以使用regex来匹配特定的模式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM