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。
正在尝试收集 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。