PowerCLI 变量的奇怪行为

PowerCLI strange behaviour of variable

正在尝试收集 VM 的一些属性,但由于某些原因,输出中的所有条目仅包含有关最后一个 VM 的信息

$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

您可以通过将 $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 时,它实际上会影响 [=15] 中的现有结果=].

通过在循环内移动 $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。