PowerShell Invoke-Command调用VM时using作用域传值失效问题咨询
核心错误点
$Using:DNSClientServerAddr语法本身无错,但用法不符合规则:
$using:作用域修饰符的作用是从本地调用上下文读取变量值,作为表达式结果返回到远程会话执行上下文中,不会自动在远程会话创建同名变量。- 原脚本块中单独写的
$Using:DNSClientServerAddr仅会将读取到的DNS地址输出到远程会话管道,并未赋值给远程会话内的$DNSClientServerAddr变量,后续Write-Host $DNSClientServerAddr调用的是远程会话中从未赋值的空变量,输出为空是必然结果。
疑问解答
1. -VMName参数下using作用域是否可正常传值?
可以正常生效。Invoke-Command -VMName走的是Hyper-V PowerShell Direct通道,不需要虚拟机配置网络、开启WinRM监听,在PowerShell 5.1环境下完整支持$using:作用域传值,不存在兼容性问题。
修正后的最简脚本块写法:
Invoke-Command -VMName $VMNameFull -ScriptBlock { # 先将using取到的值赋值给远程会话内的变量 $remoteDnsAddr = $Using:DNSClientServerAddr Write-Host $remoteDnsAddr }
2. 是否必须用New-PSSession配合-ArgumentList传值?
不是必须。
两种传值方式都可用,没有强制绑定要求:
- 临时单次调用场景下,直接用
$using:是最简便的写法,不需要提前创建持久会话。 -ArgumentList传值不依赖New-PSSession,直接在单次Invoke-Command调用中也能使用,示例写法:
Invoke-Command -VMName $VMNameFull -ScriptBlock { param($dnsAddr) Write-Host $dnsAddr } -ArgumentList $DNSClientServerAddr
New-PSSession仅在需要对同一台虚拟机执行多次远程操作、复用连接时才需要使用,和传值方式没有关联。
3. 目标虚拟机是否需要安装启用Hyper-V?
不需要。
Hyper-V角色仅需部署在执行命令的宿主机上,目标虚拟机无需安装该角色,只要满足PowerShell Direct的运行前提即可正常连接:
- 虚拟机处于开机运行状态
- 虚拟机已启用Hyper-V集成服务中的PowerShell Direct功能(对应系统服务名为
vmicvmsession,Windows 10、Windows Server 2016及以上版本默认开启) - 执行命令的账号拥有目标虚拟机的本地管理员权限,也可通过
-Credential参数显式传入管理员凭证。
修正后的完整测试代码
[int]$NumberOfVMs = Read-Host "NUMBER OF VMs TO BE CONFIGURED" $VMName = Read-Host "VM NAME PREFIX " [int]$VMNameSuffix = Read-Host "STARTING NUMBER " $DNSClientServerAddr = Read-Host "DNS CLIENT SERVER IP ADDRESS " For ($Count = 1; $Count -le $NumberOfVMs; $Count++, $VMNameSuffix++) { $VMNameFull = "$VMName" + "$VMNameSuffix" Invoke-Command -VMName $VMNameFull -ScriptBlock { $dnsAddr = $Using:DNSClientServerAddr Write-Host "当前虚拟机 $($env:COMPUTERNAME) 配置的DNS地址为: $dnsAddr" } }
内容的提问来源于stack exchange,提问作者Lee Roy Anthony Sarmiento
相关产品推荐
相关产品推荐

