我的脚本的目的是从我们的vcenter获取整个VM列表,检查它们是否有DNS条目 - 如果dns条目为null,则输出VM名称和相应的IP地址。非常简单,但是我将VM名称数组与IP地址数组相结合。这就是我的意思:
$mainArray = @()
$vmArray = @()
$ipArray = @()
$vms = Get-VM | select Name, @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, @{N="IPAddress"; E={$_.Guest.IPAddress[0]}}
foreach ($vm in $vms)
{
$dnsname = $vm.DnsName
$ipaddr = $vm.IPAddress
$vmname = $vm.Name
if (!$vm.DNSName) #if DNS name is null
{
$vmArray += $vmname
$ipArray += $ipaddr
}
}
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'VM Name' -Value $vmArray
$item | Add-Member -type NoteProperty -Name 'IP Address' -Value $ipArray
$mainArray += $item
$mainArray | ft -wrap -autosize
这会输出彼此相邻的两列,但输出用逗号分隔,并用椭圆截断。我知道有更好的方法可以做到这一点,所以我愿意接受建议。也很想知道如何让这项工作仅仅是为了我自己的理解。感谢每个人的帮助。
答案 0 :(得分:0)
您的主要问题是您在循环外填充数组。我现在无法在我面前访问PowerCLI,但我们应该能够删除大部分代码,因为它看起来是冗余和不必要的。在$vms
被宣布后继续
$vms | Where-Object{!$_.DNSName} | ForEach-Object{
New-Object PSObject -Property @{
'VM Name' = $_.Name
'IP Address' = $_.IPAddress
}
} | ft -wrap -autosize
在制作两个数组之前。一个用于名字,另一个用于ips。然后你拿了那两个数组并用这两个属性做了一个对象。我删除了对Where-Object{!$_.DNSName}
的if语句的需求。现在,所有正在处理的对象都是您想要的对象。
你真的可以用一两行使用相同的逻辑。
Get-VM | Select @{N='VM Name';E={$_.Name}}, @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, @{N="IP Address"; E={$_.Guest.IPAddress[0]}} |
Where-Object{!$_.DNSName} | Select "VM Name","IP Address" | Format-Table -wrap -autosize
同样,我无法测试,但它应该工作。如果有任何错误,应该很容易纠正。假设我首先想出了你的问题。
PowerShell有一个变量$FormatEnumerationLimit
,用于控制在控制台输出中显示的数组元素数量。有一篇很好的文章在TechNet
默认情况下,$FormatEnumerationLimit
设置为4
答案 1 :(得分:0)
马特,我之前发现了这个链接,但没有发现它非常有用,因为它会使输出出现乱码并且不会按行突破这些值。这就是我能够使原始脚本工作的方式:
$i=0
write-output $vmArray |
foreach {
new-object psobject -property @{
VMName = $_
IPAddress = $ipArray[$i++]
}
} | ft -auto -wrap
相当不同寻常,但确实有效。确实应该有一种更简单的方法将数组并排组合,但我离题了。非常感谢Matt。
更新:这可能更为传统:
For($i=0;$i -lt $vmArray.Count;$i++)
{
$item = New-Object PSObject
$item | Add-Member -type NoteProperty -Name 'VM Name' -Value $vmArray[$i]
$item | Add-Member -type NoteProperty -Name 'IP Address' -Value $ipArray[$i]
$mainArray += $item
}
$mainArray | ft -wrap -autosize