PowerCLI变量的奇怪行为

时间:2017-07-28 07:07:26

标签: powershell powercli

尝试收集虚拟机的一些属性,但由于某些原因,输出中的所有条目都包含有关最后一个虚拟机的信息

$CSV基本上包含几个VM名称:

VMName
Centos1
Centos2

以下是我正在使用的代码:

$VMdata = @()
$line = '' | Select VMName, VMToolStatus, VMToolVersion, UUID, Tag, Notes

foreach($entry in $csv){
    $line.VMName = $entry.VMname
    $line.VMToolStatus = (get-vm $entry.VMname).ExtensionData.Guest.ToolsRunningStatus
    $line.VMToolVersion = (get-vm $entry.VMname).ExtensionData.Guest.ToolsVersion
    $line.UUID = (get-vm $entry.VMname).ExtensionData.Config.UUID
    $line.Notes = (get-vm $entry.VMname).Notes
    $line.Tag = get-vm $entry.VMname | Get-TagAssignment | Select -ExpandProperty Tag  | select Name
    $VMdata += $line
}

$VMdata | Export-Csv -Path c:\report.csv -NoTypeInformation -Force

这是CSV输出 - 您可以看到两行包含有关VM Centos2的信息。

"VMName","VMToolStatus","VMToolVersion","UUID","Tag","Notes","StartupOrder"

"CentOS2","guestToolsRunning","2147483647","564d7fd7-e58f-e546-ecdf-c347e35cd453",,"Test Note",

"CentOS2","guestToolsRunning","2147483647","564d7fd7-e58f-e546-ecdf-c347e35cd453",,"Test Note",

当我调试它时,我可以看到第一个周期后$line更新了VM Centos1的正确信息,然后将其添加到$VMData

然而,当第二个周期开始时,例如执行line.VMName = $entry.VMname后,我可以看到变量$line$VMdata都使用CentOS2名称进行更新。

所以,我的问题是$VMdata$line一起更新的原因?

之前我使用过这段代码并且工作得很好。

我正在运行以下版本的PS

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      14393  1480 

VMware PowerCLI 6.5版本1版本4624819

1 个答案:

答案 0 :(得分:4)

您可以通过移动$line = ''循环中的ForEach部分来解决此问题:

$VMdata = @()

foreach($entry in $csv){
    $line = '' | Select VMName, VMToolStatus, VMToolVersion, UUID, Tag, Notes
    $line.VMName = $entry.VMname
    $line.VMToolStatus = (get-vm $entry.VMname).ExtensionData.Guest.ToolsRunningStatus
    $line.VMToolVersion = (get-vm $entry.VMname).ExtensionData.Guest.ToolsVersion
    $line.UUID = (get-vm $entry.VMname).ExtensionData.Config.UUID
    $line.Notes = (get-vm $entry.VMname).Notes
    $line.Tag = get-vm $entry.VMname | Get-TagAssignment | Select -ExpandProperty Tag  | select Name
    $VMdata += $line
}

$VMdata | Export-Csv -Path c:\report.csv -NoTypeInformation -Force

我认为问题出现是因为在这个实例中PowerShell变量就像一个指针(一个引用类型),所以当你第二次更新$line它实际影响$vmdata中的现有结果时

通过在循环中移动$line = '',您可以在每次迭代时重置变量,因此它不会以这种方式运行。

但实际上我建议你这样做:

$CSV | ForEach-Object {
    $Props = @{
        VMName = $_.VMname
        VMToolStatus = (get-vm $_.VMname).ExtensionData.Guest.ToolsRunningStatus
        VMToolVersion = (get-vm $_.VMname).ExtensionData.Guest.ToolsVersion
        UUID = (get-vm $_.VMname).ExtensionData.Config.UUID
        Notes = (get-vm $_.VMname).Notes
        Tag = (get-vm $_.VMname | Get-TagAssignment | Select -ExpandProperty Tag  | select Name)
    }
    New-Object -TypeName PSObject -Property $Props
} | Export-Csv -Path c:\report.csv -NoTypeInformation -Force

这使用哈希表在ForEach-Object循环中创建PowerShell对象,然后您可以将输出直接传递给Export-CSV。

相关问题