【问题标题】:Why does this script only work when run directly from powershell but not from another script为什么此脚本仅在直接从 powershell 运行而不是从另一个脚本运行时才有效
【发布时间】:2019-02-12 12:49:20
【问题描述】:

我正在部署一个在事件网格上触发的逻辑应用程序。部署后,我需要验证 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 变量是什么?它没有在脚本中定义,单独运行时仍然存在,但当我从另一个脚本运行脚本时不存在。

【问题讨论】:

  • 可能是复制粘贴错误,因为one version of OAuth 脚本使用了该特定变量。至于为什么它不能通过另一个脚本工作,也许后者会使用Set-StrictMode(无论如何这应该是默认设置。)
  • 我运行它的脚本确实有 Set-StrictMode -Version 3。看起来删除它使它工作。好的,也许 $scope 是一个错误,因为它没有在任何地方设置,也没有在任何地方读取

标签: powershell scoping strict


【解决方案1】:

作为you've discovered,在您的具体情况下,问题是由于调用者启用严格模式而出现的通常良性错误。然而,这个问题是一个基本问题,如下所述。


根本的问题是,从 v6.2 开始,PowerShell 的严格模式是动态,而不是词法

这意味着使用Set-StrictMode不仅会影响调用它的函数或脚本,还会影响其他调用来自的函数和脚本该函数或脚本存在于同一个作用域中,也就是说,如果调用者和被调用者都定义在外部一个模块的或在相同模块中定义的。

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

例如,被调用者可能假设严格模式是默认的-Off,并依赖(松散地)使用if (-not $var) 测试变量$var 的不存在。如果同一作用域域中的调用者设置了Set-StrictMode -Version 1 或更高级别,则被调用者将中断。

解决方法

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

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

      • 鉴于所描述的行为,在非模块脚本和函数中作为一种习惯值得这样做
    • 注意:请记住,此模式也适用于从手头的脚本或函数中调用的同一作用域域中的脚本/函数,以及脚本/函数它们 em> 打电话。 (相比之下,调用堆栈更高的代码不受影响)。

  • 否则

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

      # 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 建议引入 lexically 范围的严格模式以避免当前行为的问题。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      • 2014-11-28
      相关资源
      最近更新 更多