[英]Powershell Script working fine in Visual Code but fails running from Terminal
I'm working on writing a script which will run from AzDo Pipeline to disable F5 WebServers.我正在编写一个脚本,该脚本将从 AzDo 管道运行以禁用 F5 WebServers。 Below script works fine in Visual Code and does disable the server as expected.下面的脚本在 Visual Code 中运行良好,并且确实按预期禁用了服务器。 But when running from the terminal or PS window fails with the below error.但是当从终端或 PS window 运行时失败并出现以下错误。 Can someone please help.有人可以帮忙吗?
$ServerInput = 'server1.abc.com'
$BIGIPBaseURL = "https://ser-f5-1.prod.abc.com"
$usr = "nilesh"
$SecurePassword='P@assword'
Write-Host "Starting the Script..."
# Initialize variables
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$BIGIPToken = $null
Write-Host -ForegroundColor Green " done!"
$DisableWebServers = $true
# Initialize functions
Write-Host "Initializing functions..." -NoNewline
$PSVersionTable
function Disable-BIGIPNode([string]$NodeName) {
# servers should use the Disable-BIGIPTelcoNode() function
Write-Host "In the Disable function"
if ($NodeName -match "(?i).*telco.*") {
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."
BREAK
}
else {
if ($BIGIPToken -eq $null) {
Write-Host "Now will enter the Open-Session"
Open-BIGIPSession
}
Write-Host "Disabling node `"$($NodeName.ToUpper().Split('.')[0])`" in BIG-IP..." -NoNewline
$WebRequestInput = @{
body = @{
"session" = "user-disabled"
} | ConvertTo-Json
uri = $($BIGIPBaseURL) + "/mgmt/tm/ltm/node/~Common~" + $NodeName.ToLower()
headers = @{
"Content-Type" = "application/json"
"X-F5-Auth-Token" = "$BIGIPToken"
}
method = "PATCH"
}
Write-Host $WebRequestInput
Write-Host $WebRequestInput.body
try {
Write-Host "In the final try block"
$Request = Invoke-WebRequest @WebRequestInput -UseBasicParsing -SkipCertificateCheck
}
catch {
Write-Host -ForegroundColor Red " failed!"
Write-Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Message
}
Write-Host -ForegroundColor Green " done!"
$global:ZabbixRequestID++
}
}
function Open-BIGIPSession() {
Write-Host "Authenticating with BIG-IP API..." -NoNewline
$WebRequestInput = @{
body = @{
username = "$usr"
password = "$SecurePassword"
loginProviderName = "tmos"
} | ConvertTo-Json
uri = $ScriptInput.BIGIPBaseURL + "/mgmt/shared/authn/login"
headers = @{
"Content-Type" = "application/json"
}
method = "POST"
}
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$Request = Invoke-WebRequest @WebRequestInput -UseBasicParsing -SkipCertificateCheck
}
catch {
Write-Host -ForegroundColor Red " failed!"
Write-Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Message
EXIT 1
}
Write-Host -ForegroundColor Green " done!"
$global:BIGIPToken = ($Request.Content | ConvertFrom-Json).token.token
}
if ($DisableWebServers) {
Write-Host "Starting the main Methord "
foreach ($Server in $($ServerInput)) {
Disable-BIGIPNode -NodeName $Server
}
}
The PowerShell version is PSVersion 7.2.2 PowerShell版本为PSVersion 7.2.2
Disabling node "SAC-DEV-WEB2" in BIG-IP...System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry
{
"session": "user-disabled"
}
In the final try block
failed!
ConvertFrom-Json: C:\Temp\Testing.ps1:49:64
Line |
49 | … Host -ForegroundColor Red ($_.ErrorDetails | ConvertFrom-Json).Messag …
| ~~~~~~~~~~~~~~~~
| Conversion from JSON failed with error: Additional text encountered after finished reading JSON content: U. Path '', line
| 3, position 4.
Its working fine when running from VsCode but fails if called with the file name from the same terminal从 VsCode 运行时它工作正常,但如果从同一终端使用文件名调用则失败
like.\Testing.ps1喜欢.\Testing.ps1
Please help请帮忙
Your incidental problem is that the true error message is being obscured by a follow-up error that results from attempting to parse the error record's .ErrorDetails
property as JSON, which it isn't.您的附带问题是真正的错误消息被试图将错误记录的.ErrorDetails
属性解析为 JSON 的后续错误所掩盖,但事实并非如此。 (You report that examining the true error reveals a 401 authentication error ). (您报告检查真实错误会发现401 身份验证错误)。
I have no specific explanation for the difference in behavior you're seeing between running in Visual Studio Code vs. in a regular PowerShell console, but I have a guess :对于您在 Visual Studio Code 中运行与在常规 PowerShell 控制台中运行时所看到的行为差异,我没有具体的解释,但我有一个猜测:
Your Visual Studio Code session in the so-called PowerShell Integrated Console may have lingering state from earlier debugging runs, which may mask a bug in your script.在所谓的 PowerShell 集成控制台中,您的 Visual Studio Code session 可能有来自早期调试运行的挥之不去的 state ,这可能会掩盖脚本中的错误。
Restarting Visual Studio Code should clarify whether that is the case, but there's also a way to configure the PowerShell extension so that the problem doesn't arise to begin with - see below.重新启动 Visual Studio Code 应该可以弄清楚是否是这种情况,但也有一种方法可以配置 PowerShell 扩展,这样一开始就不会出现问题 - 见下文。
By default, code you run (debug) via the Visual Code PowerShell extension executes in the same PowerShell session, directly in the global scope .默认情况下,您通过Visual Code PowerShell 扩展运行(调试)的代码在相同的PowerShell session 中执行,直接在全局 scope 中执行。
That is, running a script being edited, say, foo.ps1
, in the debugger is effectively the same as invoking it with . .\foo.ps1
也就是说,在调试器中运行正在编辑的脚本(例如foo.ps1
)与使用 调用它实际上是一样的. .\foo.ps1
. .\foo.ps1
, ie it is in effect dot-sourced . . .\foo.ps1
,即它实际上是dot-sourced 。
Therefore, a given debugging run can be affected by earlier runs , because the state of earlier runs lingers .因此,给定的调试运行可能会受到早期运行的影响,因为早期运行的 state仍然存在。
This can result in bugs going undetected , such as in the following example:这可能导致错误未被发现,例如以下示例:
Say your script defines variable $foo
and uses it throughout the script.假设您的脚本定义了变量$foo
并在整个脚本中使用它。 If you debug your script at least one, $foo
is now defined in the PowerShell session in the PowerShell Integrated Console.如果你调试你的脚本至少一个, $foo
现在定义在 PowerShell Integrated Console 的 PowerShell session 中。
Say you then change the name to $bar
, but you forget to also replace (all) references to $foo
with $bar
.假设您随后将名称更改为$bar
,但您忘记还用$bar
替换(所有)对$foo
的引用。
Your script is now effectively broken, but you won't notice in the same session, because $foo
is still around from earlier debugging runs.您的脚本现在实际上已损坏,但您不会在同一个 session 中注意到,因为$foo
仍然存在于早期的调试运行中。
The obsolescent Windows PowerShell ISE exhibits the same unfortunate behavior, invariably so, but fortunately there is a solution for the PowerShell extension - see next point. 过时的Windows PowerShell ISE表现出同样不幸的行为,总是如此,但幸运的是有一个针对 PowerShell 扩展的解决方案 - 请参阅下一点。
You can avoid this problem by activating the Create Temporary Integrated Console
setting (via File > Preferences > Settings
or Ctrl+, ), which ensures that every debugging run creates a new, temporary session to run in , which starts with a clean slate:您可以通过激活Create Temporary Integrated Console
设置(通过File > Preferences > Settings
或Ctrl+, )来避免此问题,这可确保每次调试运行都会创建一个新的临时 session来运行,它以干净的状态开始:
Whenever a new temporary session is started, any previous one is automatically discarded.每当启动一个新的临时 session 时,任何先前的都会自动丢弃。
A temporary session has prefix [TEMP]
in the list of running shells in the integrated terminal.临时 session 在集成终端的运行 shell 列表中具有前缀[TEMP]
。
You pay a performance penalty, because a new PowerShell session must be created for every run, and you lose the previous session's display output - but I suspect avoiding the pitfalls of lingering state is worth the price.你付出了性能损失,因为每次运行都必须创建一个新的 PowerShell session,并且你失去了前一个会话的显示 output - 但我怀疑避免挥之不去的 state 的陷阱是值得的。
Note that, in a given temporary session, the dot-sourced invocation described above still applies, but with the lingering-state problem out of the picture, it can now be considered an advantage: After the script finishes, and before the temporary session is replaced with a new one, the variables and functions defined in the script's top-level scope are then available for inspection.请注意,在给定的临时 session 中,上述点源调用仍然适用,但由于挥之不去的状态问题已不存在,现在可以将其视为一个优势:脚本完成后,临时 session 之前替换为一个新的,然后可以检查脚本顶层 scope 中定义的变量和函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.