为什么这个脚本只在 运行 直接来自 powershell 而不是来自另一个脚本时有效

Why does this script only work when run directly from powershell but not from another script

我正在部署一个在事件网格上触发的逻辑应用程序。部署后,我需要验证 API 连接。我找到了这个脚本 https://github.com/logicappsio/LogicAppConnectionAuth,它工作正常。但前提是我从 Powershell 手动 运行 它。但我想在 New-AzResourceGroupDeployment 命令之后从部署逻辑应用程序的另一个脚本调用该脚本。

这样做是行不通的。我收到错误:

The variable '$Scope' cannot be retrieved because it has not been set.
At C:\location\LogicAppConnectionAuth.ps1:16 char:113
+ ... Browser -Property @{Width=580;Height=780;Url=($url -f ($Scope -join " ...
+                                                            ~~~~~~
    + CategoryInfo          : InvalidOperation: (Scope:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : VariableIsUndefined

$scope 变量是什么?它没有在脚本中定义,当 运行 单独时它仍然存在,但当我 运行 来自另一个脚本的脚本时它不存在。

$scope 变量似乎因某些复制粘贴错误而存在。它不会在任何地方声明、设置或读取。 运行 StrictMode 3 中的调用脚本是导致错误的原因。删除它,删除错误,但这并不是真正的解决方案。

我向 github 存储库发布了一个问题,并通过将 $scope 变量声明为空字符串来修复我自己的解决方案。

一样,在您的特定情况下,问题是由于 caller 启用严格模式而出现的通常是良性的错误。然而,这个问题是一个基本问题,如下所述。


潜在的问题是,从 v6.2 开始,PowerShell 的严格模式是动态 作用域,而不是词法.

这意味着使用 Set-StrictMode 不仅会影响调用它的函数或脚本,还会影响 其他函数和脚本从调用那个生活在相同范围域的函数或脚本,那个是,如果调用者和被调用者都定义在模块的 外部 或定义在 same 模块中。

换句话说:脚本或函数可能无意中继承严格模式设置并可能破坏,如果它不是为该模式设计的。

例如,被调用者可能假设严格模式处于默认状态,-Off,并依赖于(松散地)测试变量 $var 与 [=14] 的不存在性=],例如。如果同一范围域中的调用者设置了 Set-StrictMode -Version 1 或更高,则被调用者将中断。

解决方法

  • 如果控制被调用的脚本或函数:

    • 在您的脚本或函数的开头显式调用 Set-StrictMode 使用您的代码设计的模式。

      • 考虑到所描述的行为,值得在非模块脚本和函数中作为习惯这样做
    • 注意:请记住,此模式对 scripts/functions 在从手头的脚本或函数中调用的相同范围域中也有效,以及 scripts/functions 他们打电话。 (相比之下,调用堆栈中更高层的代码不受影响)。

  • 否则:

    • 暂时禁用严格模式以调用需要关闭严格模式的脚本或函数(或较低版本):

      # Temporarily turn strict mode off.
      Set-StrictMode -Off
      
      # Call the script or function that breaks with (a higher) strict mode in effect
      ...
      
      # Re-enable strict mode for your code.
      # Note that there's no way to *get* (and save for later restoring)
      # the specific mode in effect.
      Set-StrictMode -Version <n> 
      

未来展望:

This RFC 建议引入 词法 作用域严格模式以避免当前行为的问题。