gpt4 book ai didi

powershell - 我可以使 PowerShell $error 对象在脚本和交互模式下的行为一致吗?

转载 作者:行者123 更新时间:2023-12-03 09:41:04 24 4
gpt4 key购买 nike

我正在编写一个使用 $error 的 PowerShell 脚本检测和响应错误。我的问题是我对 $error 有不同的行为对象取决于我如何运行脚本。如果我以交互方式运行它(特别是从 PowerShell ISE),则会将错误添加到集合中,但如果我从命令行运行相同的脚本,则会发生相同的错误,但不会添加到集合中。

这是脚本(为了说明问题而进行了缩减):

# export_exception_test.ps1

# show me how many errors before we start
"Count = " + $error.Count

try {
# treat non-terminating errors as terminating errors.
$ErrorActionPreference = "Stop"
# echo the setting to output
$ErrorActionPreference

# use sqlcmd to save the output of stored procedures to text files.
# The first and third call will fail because the output folder does not exist.
# The second call will succeed.
'first call to sqlcmd'
sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_new\FI_Codes.txt"
'second call to sqlcmd'
sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_newt\FI_Codes.txt"
'third call to sqlcmd'
sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_new\FI_Codes.txt"
# and a whole bunch more of these...

# The error count should be two more than when we started.
"Count = " + $error.Count
# And this should be the most recent error message
"Message = " + $error[0].Message

}
catch [Exception]
{
'exception was caught!!!'
"Count in catch clause = " + $error.Count
$_.Exception.Message
# the ultimate goal is to return a non-successful return code when the exports fail
exit 1
}
finally {
# set this back to what it was
$ErrorActionPreference = "Continue"

# primitive trace output
'finally.'
}

当我从 PowerShell ISE 运行它时,它的行为符合预期。 SQLCMD 引发非终止错误,该错误被捕获并处理。这是输出:
PS U:\> C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1
Count = 0
Stop
first call to sqlcmd
exception was caught!!!
Count in catch clause = 1
Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified).
finally.

但是当我从命令行运行它时,就像我要设置计划任务一样,没有任何内容添加到 $error ,并且不会引发异常。这是输出:
C:\Users\etmatt>powershell.exe -file "C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1"
Count = 0
Stop
first call to sqlcmd
Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified).
second call to sqlcmd
third call to sqlcmd
Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified).
Count = 0
Message =
finally.

C:\Users\etmatt>

如果我从 powershell 命令行而不是 cmd.exe(这是有道理的)运行脚本文件,我也会得到相同的结果。例如:
PS C:\> ."C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1"

我怀疑这与执行上下文有关,或者可能与我仍然不太了解的解析器模式有关,甚至可能与我的个人资料有关(尽管到目前为止,我一直在同一台 PC 下使用同一帐户运行所有内容) .我在网上看到很多使用 try/catch 的基本方法的例子。与 $ErrorActionPreference = "Stop" ,所以看起来我应该能够完成这项工作。

所以我的问题本质上是:我可以让这个脚本像我认为的那样工作吗?如果不是,我有什么误解?我如何捕捉这些类型的错误?如果有帮助,我不需要对这个异常进行 super 详细的异常处理,我只需要知道什么时候出现问题,以便我的任务监视器可以提醒我。 powershell.exe 的非零返回码就足够了。

我正在研究使用 $? , 和 $LASTEXITCODE ,但我打赌 $?将有与 $error 相同的问题, 并且两者都只适用于执行的最后一条语句,这不太理想,因为我的真实脚本比这个例子长很多。

编辑:
好的,我后来了解到 Windows 可执行文件(例如 sqlcmd)永远不会向 $error 添加任何内容。集合,即使它们返回非零退出代码。 $error如果我理解正确,则仅由 cmdlet 使用。我通过重复使用 $LASTEXITCODE 使我的脚本工作,虽然我可以使用 $?同样,因为它可以识别 Windows 可执行退出代码并为非零值设置为 false。

总而言之,从命令行运行脚本时的行为是正确的、预期的行为。不过,仍然不知道为什么我从 PowerShell ISE 得到了不同的结果。

最佳答案

对我来说,我正在使用 cmd /C <command> 调用批处理命令我有类似的问题。对于非零返回码 $?设置正确但没有 $error对象(powershell 怎么知道?所以这是可以的)并且代码在 ISE 和命令行执行中的行为类似。

我的问题是在这种情况下 $ErrorActionPreference = "Stop"它没有抛出异常。可能是因为它没有 $error要扔的对象。所以现在我需要检查 $?在每次调用其他不整洁的脚本或程序之后。他们应该为这种情况想出好的解决方案(可能通过抛出内置异常说调用外部脚本/程序失败)

关于powershell - 我可以使 PowerShell $error 对象在脚本和交互模式下的行为一致吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11654435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com