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

通过PowerCLI调用PowerShell获取VM网卡信息时出现异常

批量更换虚拟机网卡类型时PowerCLI调用脚本的问题

问题场景

我正在批量将虚拟机网卡从e1000类型更换为vmxnet3类型,尝试用以下PowerShell命令筛选vmxnet网卡:

get-wmiobject win32_networkadapter | Where-Object {$_.ServiceName -match "Vmxnet"}

该命令在虚拟机内部直接执行可正常返回结果:

PS C:\Users-adm-mxj45375> get-wmiobject win32_networkadapter | Where-Object {$_.ServiceName -match "Vmxnet*"}

ServiceName : vmxnet3ndis6 MACAddress : 00:50:56:88:7E:07 AdapterType
: Ethernet 802.3 DeviceID : 1 Name : vmxnet3 Ethernet Adapter
NetworkAddresses : Speed : 10000000000

但通过PowerCLI的Invoke-VMScript调用该命令时:

$Network = Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText "(get-wmiobject win32_networkadapter | Where-Object {$_.ServiceName -match 'Vmxnet'})"

出现错误:

.ServiceName : The term '.ServiceName' is not recognized as the name
of a cmdlet, function, script file, or operable

我预期能将结果存入$Network变量,以下是完整的批量配置脚本:

Import-Module NetAdapter
Connect-VIServer in1graapp022
$vms = Import-CSV "C:\Scripts\servers.csv"
$GC = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for VM", "", "")

foreach ($vm in $vms){
$VMName = $vm.Name
  $IP = $vm.IP
$SNM = $vm.SubnetMask
$GW = $vm.Gateway
$DNS1 = $vm.DNS1
$DNS2 = $vm.DNS2 
$Network = Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText "(get-wmiobject win32_networkadapter | Where-Object {$_.ServiceName -match 'Vmxnet*'}).netconnectionid" 
$NetworkName = get-networkadapter $VMName | Where-Object {$_.type -eq "vmxnet3"} | Select-Object MacAddress
#Write-Host "Setting IP address for $VMname..." -ForegroundColor Yellow
#Sleep -Seconds 60
$netadapter = Get-NetAdapter | where MacAddress -ne "$NetworkName"}
$netadapter1 | New-NetIPAddress -AddressFamily IPv4 -IPAddress $IP -PrefixLength 24 -Type Unicast -DefaultGateway $GW
$netadapter2 | Set-DnsClientServerAddress  -ServerAddresses $DNS1
#$netsh = "c:\windows\system32\netsh.exe interface ip set address ""$NetworkName"" static $IP $SNM $GW"
#$netsh2 = "c:\windows\system32\netsh.exe interface ip set dnsservers ""$NetworkName"" static $DNS1"
#$netsh3 = "c:\windows\system32\netsh.exe interface ip add dnsservers ""$NetworkName"" $DNS2"
Invoke-VMScript -VM $VMname -GuestCredential $GC -ScriptType bat -ScriptText $netadapter1
Invoke-VMScript -VM $VMname -GuestCredential $GC -ScriptType bat -ScriptText $netadapter2
#Invoke-VMScript -VM $VMname -GuestCredential $GC -ScriptType bat -ScriptText $netsh3
Write-Host "Setting IP address completed." -ForegroundColor Green
Sleep -Seconds 20
([WMIClass]"\\$vmname\ROOT\CImv2:Win32_Process").Create("cmd.exe /c ipconfig /registerdns")
}

错误原因及解决方法

核心错误原因

脚本字符串中的变量解析冲突:本地PowerShell会优先解析Invoke-VMScript传递的脚本字符串里的$_.ServiceName,把$_当成当前本地管道对象,而非虚拟机内脚本的管道对象,导致语法错误。

两种解决方式

  1. 转义美元符号
    将脚本字符串中的$转义为$$,让虚拟机内的PowerShell正确解析变量:
$Network = Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText "(get-wmiobject win32_networkadapter | Where-Object {$$_.ServiceName -match 'Vmxnet'}).netconnectionid" -GuestCredential $GC
  1. 使用Here-String
    用PowerShell的Here-String格式定义脚本内容,避免本地变量解析(注意用反引号转义$`):
$scriptText = @"
(get-wmiobject win32_networkadapter | Where-Object `$_.ServiceName -match 'Vmxnet').netconnectionid
"@
$Network = Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText $scriptText -GuestCredential $GC

脚本其他问题修正

除了核心错误,原脚本还有几处逻辑问题:

  • $netadapter = Get-NetAdapter | where MacAddress -ne "$NetworkName"}多了一个闭合大括号},需删除;
  • $netadapter1和$netadapter2未定义,应直接使用$netadapter;
  • 用Invoke-VMScript传递PowerShell对象(如$netadapter1)无效,因为该命令需要脚本文本字符串,需将IP/DNS配置逻辑整合到虚拟机内执行的脚本中。

修正后的关键部分示例:

# 获取虚拟机内vmxnet网卡的NetConnectionID
$getAdapterScript = @"
(get-wmiobject win32_networkadapter | Where-Object `$_.ServiceName -match 'Vmxnet').netconnectionid
"@
$Network = Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText $getAdapterScript -GuestCredential $GC

# 构造IP与DNS配置脚本
$configScript = @"
`$adapter = Get-NetAdapter -Name '$Network'
`$adapter | New-NetIPAddress -AddressFamily IPv4 -IPAddress '$IP' -PrefixLength 24 -DefaultGateway '$GW'
`$adapter | Set-DnsClientServerAddress -ServerAddresses '$DNS1', '$DNS2'
ipconfig /registerdns
"@

# 在虚拟机内执行配置
Invoke-VMScript -VM $VMName -ScriptType Powershell -ScriptText $configScript -GuestCredential $GC

内容的提问来源于stack exchange,提问作者Martyn Jeffrey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:43:19