使用PowerShell执行Set-DrsRule遇类型转换错误的解决求助
解决PowerShell配置VMware DrsVMHostRule的绑定错误
问题重现
尝试执行以下PowerShell代码为服务器配置DrsRule:
$hostname= $TOD_Data.name try{ $OS = $TOD_Data.os $dc = $TOD_Data.datacenter Connect-VIServer -server 12.16.1.3 $VM = Get-VM | where {$_.Name -match $Hostname} | select -Unique $cluster = Get-Cluster | where {$_.Name -eq "Standard"} | select Name $cluster = $cluster.Name $Win_Rule_2 = get-Cluster -name $cluster | Get-DrsVMHostRule -name "ST5_STRETCH_CLUSTER" if($OS -eq "Windows" -and $dc -eq "ST5") { Set-DrsRule -Rule $Win_Rule_2 -VM $VM -Enabled $true; Write-Host "$hostname added to $Win_Rule_2" -BackgroundColor Green -ForegroundColor Black } else {write-host "Dual Site Hosting is false" -BackgroundColor Red -ForegroundColor White} } catch { write-host "$Error.Exception.Message" -BackgroundColor Red -ForegroundColor White }
执行时触发第一个错误:
Cannot bind parameter 'Rule'. Cannot convert the "ST5_STRETCH_CLUSTER" value of type "VMware.VimAutomation.ViCore.Impl.V1.Cluster.DrsVMHostRuleImpl" to type "VMware.VimAutomation.ViCore.Types.V1.Cluster.DrsRule"..Exception.Message
检查$Win_Rule_2类型:
PS C:\Windows\system32> $Win_Rule_2.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- False False DrsVMHostRuleImpl VMware.VimAutomation.ViCore.Util10.VersionedObjectImpl
改用Set-DrsVMHostRule后触发第二个错误:
PS C:\Windows\system32> Set-DrsVMHostRule -Rule $Win_Rule_2 -VMGroup $Win_Rule_2_VMGroup -Server $VM -Enabled $true
错误信息:
Set-DrsVMHostRule : Cannot bind parameter 'Server'. Cannot convert the "SW560PWMS1DB" value of type "VMware.VimAutomation.ViCore.Impl.V1.VM.UniversalVirtualMachineImpl" to type "VMware.VimAutomation.ViCore.Types.V1.VIServer". At line:1 char:74 + ... le -Rule $Win_Rule_2 -VMGroup $Win_Rule_2_VMGroup -Server $VM -Enable ... + ~~~ + CategoryInfo : InvalidArgument: (:) [Set-DrsVMHostRule], ParameterBindingException + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetDrsVMHostRule
错误原因分析
- 第一个错误:混淆了
Set-DrsRule和Set-DrsVMHostRulecmdlet。Get-DrsVMHostRule返回的是主机亲和/反亲和规则对象(DrsVMHostRuleImpl),必须使用对应的Set-DrsVMHostRule来修改,而非通用的Set-DrsRule。 - 第二个错误:参数使用错误。
-Server参数需要传入VIServer对象(vCenter连接实例),而非虚拟机对象;要将VM添加到规则的VM组,需通过-VM参数直接传入VM对象,或确保-VMGroup绑定正确的VM组对象。
修正后的代码
$hostname= $TOD_Data.name try{ $OS = $TOD_Data.os $dc = $TOD_Data.datacenter # 保存vCenter连接实例,后续复用 $vCenterConn = Connect-VIServer -server 12.16.1.3 -ErrorAction Stop $VM = Get-VM -Name $hostname -Server $vCenterConn | Select-Object -Unique if(-not $VM){ Write-Host "未找到虚拟机 $hostname" -BackgroundColor Red -ForegroundColor White break } $cluster = Get-Cluster -Name "Standard" -Server $vCenterConn if(-not $cluster){ Write-Host "未找到集群 Standard" -BackgroundColor Red -ForegroundColor White break } $Win_Rule_2 = $cluster | Get-DrsVMHostRule -Name "ST5_STRETCH_CLUSTER" -Server $vCenterConn if(-not $Win_Rule_2){ Write-Host "未找到规则 ST5_STRETCH_CLUSTER" -BackgroundColor Red -ForegroundColor White break } if($OS -eq "Windows" -and $dc -eq "ST5") { # 使用正确的Set-DrsVMHostRule,直接传入VM对象到-VM参数 Set-DrsVMHostRule -Rule $Win_Rule_2 -VM $VM -Enabled $true -Server $vCenterConn Write-Host "$hostname 已成功添加到规则 $($Win_Rule_2.Name)" -BackgroundColor Green -ForegroundColor Black } else{ Write-Host "不满足双站点托管条件(OS非Windows或数据中心非ST5)" -BackgroundColor Red -ForegroundColor White } } catch{ Write-Host "执行错误: $($_.Exception.Message)" -BackgroundColor Red -ForegroundColor White } finally{ # 确保断开vCenter连接(可选,按需保留) if($vCenterConn){ Disconnect-VIServer -Server $vCenterConn -Confirm:$false } }
关键修正点
- 替换
Set-DrsRule为Set-DrsVMHostRule,匹配Get-DrsVMHostRule返回的对象类型。 - 修正参数错误:
-Server传入vCenter连接实例,而非虚拟机对象;直接用-VM参数传递要添加的VM对象。 - 添加对象存在性检查(VM、集群、规则),提前捕获异常,避免后续执行报错。
- 保存vCenter连接实例并复用,提升执行效率,确保cmdlet在指定连接上操作。
- 优化错误输出,直接显示异常详情,便于排查。
内容的提问来源于stack exchange,提问作者Empty Coder
相关产品推荐
相关产品推荐

