PowerShell中如何选择$MyInvocation.ScriptName与$MyInvocation.PSCommandPath?
$MyInvocation.ScriptName vs $MyInvocation.PSCommandPath:该选哪一个?
在PowerShell 5.1及以上版本中,有两个变量似乎都能获取调用当前脚本的脚本(比如来自模块、函数或外部脚本)的完整路径:
$MyInvocation.ScriptName$MyInvocation.PSCommandPath
官方定义
[$MyInvocation.]ScriptName指的是调用你的脚本的名称(官方也承认这个命名不够直观)
[$MyInvocation.]PSCommandPath包含调用或触发当前脚本的脚本的完整路径和名称。
已知差异
$MyInvocation.ScriptName从PowerShell 1.0起就已存在,而$MyInvocation.PSCommandPath是PowerShell 3.0新增的,目的是和自动变量$PSCommandPath保持行为一致性。- 无调用脚本时:
$MyInvocation.ScriptName返回空字符串'',$MyInvocation.PSCommandPath返回$null。
边缘情况与隐藏陷阱
1. 路径完整性差异
$MyInvocation.ScriptName在部分场景下仅返回文件名,而非完整绝对路径:比如当调用脚本是通过PATH环境变量找到并执行时,它只会返回脚本名称;而$MyInvocation.PSCommandPath始终返回完整的绝对路径。
举个例子:若C:\Scripts在系统PATH中,执行caller.ps1调用当前脚本,$MyInvocation.ScriptName可能仅返回caller.ps1,而$MyInvocation.PSCommandPath会返回C:\Scripts\caller.ps1。
2. 函数与模块中的行为差异
- 在脚本定义的函数内部:两者都会返回调用该函数的脚本的路径,而非定义函数的脚本路径。
- 在模块函数内部:当模块函数被外部脚本调用时,两者都返回调用脚本的路径;但如果直接在控制台调用模块函数,
$MyInvocation.ScriptName返回空字符串,$MyInvocation.PSCommandPath返回$null。
3. 版本兼容性限制
$MyInvocation.PSCommandPath仅在PowerShell 3.0及以上版本可用;如果你的脚本需要兼容PowerShell 2.0或更早版本,只能使用$MyInvocation.ScriptName。
场景选择建议
优先使用$MyInvocation.PSCommandPath
- 需要确保获取完整绝对路径,避免仅得到文件名的问题;
- 脚本目标环境是PowerShell 3.0及以上(包括5.1及所有PowerShell Core/7.x版本);
- 希望和自动变量
$PSCommandPath的行为保持一致,降低代码维护的认知成本。
必须使用$MyInvocation.ScriptName
- 脚本需要兼容PowerShell 2.0及更早版本;
- 你的代码逻辑更适配空字符串(
'')而非$null的返回值(比如某些字符串校验或拼接逻辑)。
内容的提问来源于stack exchange,提问作者Minkus
相关产品推荐
相关产品推荐

