You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerCLI测试全主机VM的vMotion兼容性脚本报错求助

问题排查与脚本优化方案

1. 只读错误原因与修复

$host是PowerShell的内置自动变量,用于表示当前会话的主机信息,属于只读变量,不能用作自定义循环变量名。这就是你遇到"只读错误"的根源。

修复方法:将循环变量名从$host改为非内置变量名,比如$vmHost。

2. 脚本优化与CSV导出实现

下面是修改后的完整脚本,同时实现了vMotion兼容性检查结果的CSV导出功能:

#Start Script
$logPath = "\\Server.Name\Department\InformationTechnology\VMware\PowerShell\Logs\vMotion-Data_$(Get-Date -Format `"yyyymmdd_hhmmtt").txt"
Start-Transcript -Path $logPath -IncludeInvocationHeader

#Connection Data
$vCenterServerName = Read-Host "What is the vCenter Server IP?"
$Username = Read-Host "What username?"
$Password = Read-Host "What password?" -AsSecureString 

Connect-VIServer -Server $vCenterServerName -User $Username -Password $Password

# 初始化结果数组,用于收集CSV数据
$vmotionResults = @()

# 获取所有ESXi主机
$allHosts = Get-VMHost

# 循环遍历每台主机
foreach ($vmHost in $allHosts) {
    $hostVmotionEnabled = $vmHost.ExtensionData.Config.Network.VmotionEnabled
    $hostName = $vmHost.Name

    if ($hostVmotionEnabled) {
        Write-Host "vMotion is enabled on Host $hostName"
        # 获取当前主机上的所有VM
        $hostVms = Get-VM -VMHost $vmHost

        foreach ($vm in $hostVms) {
            $vmotionCheck = $vm | Test-VMHost -VMotion
            # 构造结果对象
            $resultObj = [PSCustomObject]@{
                HostName = $hostName
                HostVmotionEnabled = $hostVmotionEnabled
                VMName = $vm.Name
                VmotionCompatible = $vmotionCheck.Compatible
                Reason = if ($vmotionCheck.Compatible) { $null } else { $vmotionCheck.Reason }
            }
            # 添加到结果数组
            $vmotionResults += $resultObj

            # 控制台输出
            if ($vmotionCheck.Compatible) {
                Write-Host "vMotion is compatible for VM $($vm.Name) on Host $hostName"
            } else {
                Write-Host "vMotion is not compatible for VM $($vm.Name) on Host $hostName): $($vmotionCheck.Reason)"
            }
        }
    } else {
        Write-Host "vMotion is not enabled on Host $hostName"
        # 记录主机未启用vMotion的结果
        $resultObj = [PSCustomObject]@{
            HostName = $hostName
            HostVmotionEnabled = $hostVmotionEnabled
            VMName = $null
            VmotionCompatible = $null
            Reason = "Host vMotion is not enabled"
        }
        $vmotionResults += $resultObj
    }
}

# 导出结果到CSV
$csvPath = "\\Server.Name\Department\InformationTechnology\VMware\PowerShell\Results\vMotion-Compatibility_$(Get-Date -Format `"yyyymmdd_hhmmtt").csv"
$vmotionResults | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
Write-Host "Compatibility results exported to: $csvPath"

# Disconnect from vCenter Server
Disconnect-VIServer -Server $vCenterServerName -Confirm:$false

Stop-Transcript

3. 关键修改说明

  • 替换了循环变量名:将$host改为$vmHost,避免与PowerShell内置只读变量冲突
  • 优化VM获取:直接在主机循环内用Get-VM -VMHost $vmHost获取当前主机的VM,逻辑更清晰
  • 结果收集与CSV导出:创建$vmotionResults数组,用PSCustomObject构造结构化数据,最后通过Export-Csv导出为CSV文件
  • 完善结果记录:即使主机未启用vMotion,也会将该信息写入CSV,确保结果完整性

内容的提问来源于stack exchange,提问作者Stephen Skaines

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:35:11