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

如何在PowerShell中将脚本块存入变量并用于Invoke-Command

问题解决:Hyper-V中Invoke-Command使用ScriptBlock变量获取VM主机名失败

核心原因

你遇到的问题是变量解析时机错误:

  • 直接写{"$env:COMPUTERNAME"}时,这个脚本块会被完整传到目标VM,在VM的环境中才解析$env:COMPUTERNAME,得到的是VM自身的计算机名。
  • 但你把"$env:COMPUTERNAME"存成字符串变量时,这个赋值操作会立即在Hyper-V主机环境中解析$env:COMPUTERNAME,得到的是主机的计算机名。之后无论你把这个变量放到ScriptBlock里,还是用[ScriptBlock]::Create()转换,最终传到VM执行的都是已经解析好的主机名,而非VM的。

正确写法

写法1:直接定义ScriptBlock类型变量

直接把脚本块定义为[ScriptBlock]类型,避免提前解析:

# 直接创建ScriptBlock变量,不经过字符串中转
$scriptBlock = { $env:COMPUTERNAME }

# 执行命令
Get-VM | Where-Object State -Eq 'Running' | ForEach-Object { 
    Invoke-Command -VMName $_.Name -ScriptBlock $scriptBlock -Credential $cred
    '' # 空行分隔结果
}

写法2:用字符串创建ScriptBlock时,避免提前解析

如果必须通过字符串中转,要使用单引号包裹字符串(单引号内的变量不会被主机解析),再转换为ScriptBlock:

# 用单引号定义字符串,$env:COMPUTERNAME不会被主机提前解析
$scriptStr = '$env:COMPUTERNAME'
$scriptBlock = [ScriptBlock]::Create($scriptStr)

# 执行命令
Get-VM | Where-Object State -Eq 'Running' | ForEach-Object { 
    Invoke-Command -VMName $_.Name -ScriptBlock $scriptBlock -Credential $cred
    ''
}

为什么之前的尝试失败

  • $script="$env:COMPUTERNAME":赋值时主机直接解析$env:COMPUTERNAME为自身主机名,传到VM后输出的是主机名。
  • [ScriptBlock]::create("$env:COMPUTERNAME"):同样,字符串里的$env:COMPUTERNAME已经被主机解析,生成的ScriptBlock实际是{ 主机名 },执行后自然不对。
  • {"$script"}或{"$($script)"}:还是在主机端解析$script的值(主机名),传到VM输出的依然是主机名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:36:00