首页 > 解决方案 > ScriptProperty 在作为命令调用时无法访问脚本的 cmdlet

问题描述

给定诸如此 MRE 之类的代码:

function Get-One {1}
Update-TypeData -TypeName 'Demo' -MemberType 'ScriptProperty' -MemberName 'Test1' -Value {Get-Date}
Update-TypeData -TypeName 'Demo' -MemberType 'ScriptProperty' -MemberName 'Test2' -Value {Get-One}
$example = [PSCustomObject]@{PSTypeName = 'Demo'}
$example

如果我调用它,pwsh -File '.\Demo.ps1'那么一切都会按您的预期工作/我得到这个输出:

Test1               Test2
-----               -----
2021-04-17 21:35:55     1

但是,如果我调用与我得到的相同的命令pwsh -Command '.\Demo.ps1'(即 Test2 为空白);虽然我希望得到与上述相同的结果:

Test1               Test2
-----               -----
2021-04-17 21:35:55     

即当我通过-Command参数调用时,ScriptProperty 无法访问脚本本身中定义的 cmdlet/函数;虽然可以访问标准的(例如Get-Date)。

我认为这是一个错误;PWSH 和 PowerShell 中只有相同的行为;这使得这种可能性降低了一点。

这是一个错误吗?或者我在我的理解中遗漏了什么。

标签: powershellpowershell-corepowershell-5.1

解决方案


-File行为上的差异可以通过隐式点源目标脚本文件这一事实来解释,这意味着它在全局范围内运行。

通常,此详细信息无关紧要(除非您-NoExit在脚本终止后还传递请求留在会话中)。

在这里,它产生了关键的区别:

  • -File,Get-One最终定义在全局范围ScriptProperty内,这是-defining{ Get-One }脚本块能够看到它的先决条件

  • 相比之下,运行脚本文件-Command不会对其进行点源,从而使Get-One命令实际上对{ Get-One }脚本块不可见-并且在此类ScriptProperty定义的脚本块中发生的错误被悄悄地忽略了。

有两种解决方案

  • Get-One要么:将您的函数明确定义为global

    function global:Get-One { 1 }
    
  • 或者:使用 时-Command明确点源脚本:

     pwsh -Command '. .\Demo.ps1'
    

推荐阅读