Powershell 脚本在可视代码中工作正常,但无法从终端运行

Nil*_*edi 3 powershell automation f5 powershell-3.0 azure-devops

我正在编写一个将从 AzDo Pipeline 运行以禁用 F5 WebServer 的脚本。下面的脚本在可视代码中运行良好,并且确实按预期禁用了服务器。但是当从终端或 PS 窗口运行时失败并出现以下错误。有人可以帮忙吗?

\n
$ServerInput = 'server1.abc.com'\n$BIGIPBaseURL = "https://ser-f5-1.prod.abc.com"\n$usr = "nilesh"\n$SecurePassword='P@assword'\nWrite-Host "Starting the Script..." \n# Initialize variables\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n$BIGIPToken = $null\nWrite-Host -ForegroundColor Green " done!"\n$DisableWebServers = $true\n# Initialize functions\nWrite-Host "Initializing functions..." -NoNewline\n$PSVersionTable\n\nfunction Disable-BIGIPNode([string]$NodeName) {\n    # servers should use the Disable-BIGIPTelcoNode() function\n    Write-Host "In the Disable function"\n    if ($NodeName -match "(?i).*telco.*") {\n        Write-Host -ForegroundColor Yellow "WARNING: `"$($NodeName.ToUpper().Split('.')[0])`" is in the wrong list.  telcoo hosts should be added to the TelcoServers list in your input file."\n        BREAK\n    }\n    else {\n        if ($BIGIPToken -eq $null) {\n            Write-Host "Now will enter the Open-Session"\n            Open-BIGIPSession\n        }\n\n        Write-Host "Disabling node `"$($NodeName.ToUpper().Split('.')[0])`" in BIG-IP..." -NoNewline\n        $WebRequestInput = @{\n            body = @{\n                "session" = "user-disabled"\n            } | ConvertTo-Json\n            uri = $($BIGIPBaseURL) + "/mgmt/tm/ltm/node/~Common~" + $NodeName.ToLower()\n            headers = @{\n                "Content-Type" = "application/json"\n                "X-F5-Auth-Token" = "$BIGIPToken"\n            } \n            method = "PATCH"\n        } \n        Write-Host $WebRequestInput\n        Write-Host $WebRequestInput.body\n\n        try {\n            Write-Host "In the final try block"\n            $Request = Invoke-WebRequest @WebRequestInput -UseBasicParsing -SkipCertificateCheck \n        }\n        catch {\n            Write-Host -ForegroundColor Red " failed!"\n            Write-Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Message\n        }\n        Write-Host -ForegroundColor Green " done!"\n        $global:ZabbixRequestID++\n    }\n}\n\nfunction Open-BIGIPSession() {\n    Write-Host "Authenticating with BIG-IP API..." -NoNewline\n    $WebRequestInput = @{\n        body = @{\n            username = "$usr"\n            password = "$SecurePassword"\n            loginProviderName = "tmos"\n        } | ConvertTo-Json\n        uri = $ScriptInput.BIGIPBaseURL + "/mgmt/shared/authn/login"\n        headers = @{\n            "Content-Type" = "application/json"\n        }\n        method = "POST"\n    }\n    try {\n        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n        $Request = Invoke-WebRequest @WebRequestInput -UseBasicParsing -SkipCertificateCheck\n    }\n    catch {\n        Write-Host -ForegroundColor Red " failed!"\n        Write-Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Message\n        EXIT 1\n    }\n    Write-Host -ForegroundColor Green " done!"\n    $global:BIGIPToken = ($Request.Content | ConvertFrom-Json).token.token \n}\n\nif ($DisableWebServers) {\n    Write-Host "Starting the main Methord "\n    foreach ($Server in $($ServerInput)) {\n        Disable-BIGIPNode -NodeName $Server\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

PowerShell版本是PS版本7.2.2

\n
Disabling node "SAC-DEV-WEB2" in BIG-IP...System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry\n{\n  "session": "user-disabled"\n}\nIn the final try block\n failed!\nConvertFrom-Json: C:\\Temp\\Testing.ps1:49:64\nLine |\n  49 |  \xe2\x80\xa6 Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Messag \xe2\x80\xa6\n     |                                                 ~~~~~~~~~~~~~~~~\n     | Conversion from JSON failed with error: Additional text encountered after finished reading JSON content: U. Path '', line\n     | 3, position 4.\n
Run Code Online (Sandbox Code Playgroud)\n

从 VsCode 运行时工作正常,但如果从同一终端使用文件名调用则失败

\n

像.\\Testing.ps1

\n

请帮忙

\n

mkl*_*nt0 5

  • 您的附带问题是,真正的错误消息被后续错误所掩盖,该错误是由于尝试将错误记录的.ErrorDetails属性解析为 JSON 而导致的,但事实并非如此。(您报告说,检查真实错误会发现401 身份验证错误)。

  • 对于您在 Visual Studio Code 中运行与在常规 PowerShell 控制台中运行之间所看到的行为差异,我没有具体的解释,但我有一个猜测

    • 所谓的 PowerShell 集成控制台中的 Visual Studio Code 会话可能具有早期调试运行的延迟状态,这可能会掩盖脚本中的错误。

    • 重新启动 Visual Studio Code 应该可以澄清是否是这种情况,但还有一种方法可以配置 PowerShell 扩展,以便一开始就不会出现问题 - 请参阅下文。


  • 默认情况下,通过Visual Code PowerShell 扩展运行(调试)的代码会在同一个PowerShell 会话中直接在全局范围内执行

    • 也就是说,foo.ps1在调试器中运行正在编辑的脚本(例如 )实际上与使用 调用它相同. .\foo.ps1,即它实际上是点源的

    • 因此,给定的调试运行可能会受到早期运行的影响,因为早期运行的状态会持续存在

      • 可能会导致错误未被检测到,例如以下示例:

        • 假设您的脚本定义了变量$foo并在整个脚本中使用它。如果您至少调试一个脚本,$foo则现在在 PowerShell 集成控制台的 PowerShell 会话中定义。

        • 假设您随后将名称更改为$bar,但您忘记将(所有)引用$foo替换为$bar

        • 现在,您的脚本实际上已被破坏,但您不会在同一会话中注意到,因为$foo早期的调试运行仍然存在。

          • 但是,从常规 PowerShell 控制台运行脚本导致问题出现。
    • 过时Windows PowerShell ISE总是表现出同样不幸的行为,但幸运的是,PowerShell 扩展有一个解决方案 - 请参阅下一点。

  • 您可以通过激活该设置(通过或)来避免此问题Create Temporary Integrated Console,这确保每次调试运行都会创建一个新的临时会话来运行,该会话从一个干净的状态开始:File > Preferences > SettingsCtrl+,

    • 每当启动新的临时会话时,任何先前的临时会话都会自动丢弃。

    • 临时会话[TEMP] 在集成终端中正在运行的 shell 列表中具有前缀。

    • 您会付出性能损失,因为每次运行都必须创建一个新的 PowerShell 会话,并且您会丢失前一个会话的显示输出 - 但我怀疑避免延迟状态的陷阱是值得的。

    • 请注意,在给定的临时会话中,上面描述的点源调用仍然适用,但是随着延迟状态问题的出现,它现在可以被认为是一个优点:在脚本完成之后,在临时会话启动之前当替换为新的时,脚本顶级作用域中定义的变量和函数就可供检查。