You need to enable JavaScript to run this app. PowerShell执行字符串脚本时如何让$PSScriptRoot返回正确有效值
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell执行字符串脚本时如何让$PSScriptRoot返回正确有效值

底层运行机制说明

$PSScriptRoot 是 PowerShell 内置的自动变量,仅在和物理脚本文件绑定的作用域下会被自动赋值:

  • 直接写在 .ps1 文件中的代码、以及文件内通过 {...} 字面量定义的脚本块,都会继承所属脚本文件的上下文,所以可以正常读取到 $PSScriptRoot,这就是测试3、测试5能正常返回结果的核心原因。
  • 而 Invoke-Expression 执行字符串、[ScriptBlock]::Create() 从字符串生成脚本块的场景下,PowerShell 会判定这部分代码为无文件绑定的动态代码,不会自动注入路径相关的自动变量,因此返回空值,对应测试2、4、6的表现。

问题解答

  • 不存在用 {...} 字面量语法基于字符串生成脚本块的方法,该语法是编译时静态语法,仅支持写固定代码内容。
  • 不需要调用 Invoke-Expression 也可以实现需求,可使用上下文继承的脚本块创建方案。

核心需求解决方案

方案1:动态注入变量(兼容性最高)

在待执行的脚本字符串开头拼接赋值逻辑,直接继承父脚本的 $PSScriptRoot 值,无需修改原有混淆脚本的逻辑:

# script.ps1
# 从可执行程序拿到的混淆脚本字符串
$obfuscatedScript = 你从stdout读取到的脚本内容

# 拼接变量注入代码,用格式化语法避免特殊字符转义问题
$execString = "`$PSScriptRoot = @'
$PSScriptRoot
'@
$obfuscatedScript"

Invoke-Expression $execString

方案2:上下文绑定脚本块(无需调用Invoke-Expression)

使用 PowerShell 执行上下文提供的 NewScriptBlock 方法创建脚本块,该方法生成的脚本块会继承当前父脚本的完整上下文,包含 $PSScriptRoot 自动变量:

# script.ps1
$obfuscatedScript = 你从stdout读取到的脚本内容
# 生成继承当前上下文的脚本块
$scriptBlock = $executionContext.InvokeCommand.NewScriptBlock($obfuscatedScript)
# 点源执行脚本块
. $scriptBlock
# 脚本内的$PSScriptRoot会正常返回父脚本所在目录路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 18:06:05