我希望我的PowerShell脚本在我运行的任何命令失败时停止(例如set -e在bash中).我正在使用Powershell命令(New-Object System.Net.WebClient)和程序(.\setup.exe).
如何在自定义PowerShell函数中模拟-ErrorAction.例如,请考虑以下脚本
function Foo2
{
Write-Host "in Foo2"
#...Error occurs
Foo3
}
function Foo1
{
Write-Host "in Foo1"
Foo2
}
function Foo3
{
Write-Host "in Foo3"
}
Run Code Online (Sandbox Code Playgroud)
PS> Foo1 -ErrorAction停止
当Foo2发生错误时,是否可以停止执行Foo1,而不是继续执行Foo3?
此致,Jeez
在PowerShell中,throw $ErrorMsg和之间有什么区别$PScmdlet.ThrowTerminatingError($ErrorMsg)?
它们是相同还是不同?如果它们不同哪一个更好?
问题:powershell 脚本因使用 $ErrorActionPreference 时应该由 try 块捕获的异常而停止
例子:
$ErrorActionPreference = 'Stop'
try {
ThisCommandWillThrowAnException
} catch {
Write-Error 'Caught an Exception'
}
# this line is not executed.
Write-Output 'Continuing execution'
Run Code Online (Sandbox Code Playgroud) 因此,考虑到有四种*方法来报告错误(不包括$ErrorActionPreference、try/catch和trap块的影响,它们有可能改变另一个源报告错误的方式),PowerShell 错误报告似乎是一个巨大的混乱,分钟和糟糕记录了差异,更糟糕的是,没有关于何时使用不同类型的真正说明。(我意识到这会因情况而异,但“标准”是什么——其他人会期望我做什么?)
但这并不是真正的重点。我决定尽可能使用最简单的选项,因为这是我期望大多数其他人都会使用的选项,所以至少我们会保持一致性 - 但我要么没有正确理解某些内容,要么它已损坏。
根据PowerShell 文档,类Activity的属性ErrorCategoryInfo(在 的CategoryInfo属性中观察到System.Management.Automation.ErrorRecord)应该是“遇到错误的操作的文本描述”。考虑到该值是可设置的,并且(在编译的 cmdlet 的情况下)指示 cmdlet 的名称,除非另有指定,我希望基于脚本的错误报告方法具有相同的功能,但我做错了,或者我我们发现 PowerShell 中存在一个自 PowerShell 1.0 以来就普遍存在的错误。
考虑以下示例:
using namespace System.Management.Automation;
function Invoke-Error1 {
[CmdletBinding()]
param()
process {
$ex = [InvalidOperationException]::new()
$er = [ErrorRecord]::new($ex, 'OperationTest', [ErrorCategory]::InvalidOperation, 'MyErrorTarget')
$er.CategoryInfo.Activity = 'MyActivity'
Write-Error -ErrorRecord $er
}
}
Run Code Online (Sandbox Code Playgroud)
调用此函数将导致以下错误。
invoke-error1 : Operation is not valid due to the current state of the object.
At line:1 char:1
+ …Run Code Online (Sandbox Code Playgroud) 因此,在 Powershell 中,如果您写入输出一些行然后抛出错误,您会期望获得错误发生之前发生的输出。所以如果你执行这个:
Write-Output ("test output 1")
Write-Output ("test output 2")
Write-Output ("test output 3")
Write-Output ("test output 4")
Write-Output ("test output 5")
throw "pretend error"
Run Code Online (Sandbox Code Playgroud)
您将得到预期的结果:
test output 1
test output 2
test output 3
test output 4
test output 5
pretend error
At C:\Powershell\Test.ps1:7 char:1
+ throw "pretend error"
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (pretend error:String) [], RuntimeException
+ FullyQualifiedErrorId : pretend error
Run Code Online (Sandbox Code Playgroud)
但是,如果您在数组中写入输出一堆对象,然后抛出错误,则数组的写入输出(以及之后的任何内容)永远不会出现。所以如果你运行这个:
Write-Output ("test output 1")
Write-Output ("test output 2")
Write-Output ("test output 3")
Write-Output …Run Code Online (Sandbox Code Playgroud) 我已经阅读了很多关于 powershell 错误处理的内容,现在我对在任何给定情况下应该做什么(错误处理)感到非常困惑。我正在使用 powershell 5.1(不是核心)。话虽如此:假设我有一个模块,它的功能看起来像这个模拟:
function Set-ComputerTestConfig {
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string] $Name)
begin { ... }
process {
# task 1
# task 2 => results in a failure that prevents further tasks
# task 3
# task 4
}
end { ... }
Run Code Online (Sandbox Code Playgroud)
假设对于我传递给此函数的每台计算机名称,我有 4 个任务要完成,但如果其中任何一个任务失败,我将无法继续执行剩余的任务。我应该如何产生错误(最佳实践),以便它停止此特定计算机名称的“进程”,但有效地继续处理管道?
我无法在谷歌上搜索一个明确的答案.例如,throw 'temper tantrum'和之间是否存在实际差异Write-Error 'temper tantrum' -ErrorAction Stop?
它们都会产生终止错误并设置$?为假.我可以看到CategoryInfo和FullyQualifiedErrorId存在差异.操作词是实用的.他们有不同的效果吗?在特定情况下,是否有理由偏好另一个?
我正在构建一个脚本,该脚本将包含一个包含块和多个块的Try 语句。此页面提供了一个很好的指南,可帮助识别PowerShell 中的错误类型,以及如何在语句中处理它们。TryCatchcatch
我一直Write-Error用到现在。我认为其中一个可选参数 ( Categoryor CategoryTargetType) 可用于指定错误类型,然后是一个catch专门用于该类型的块。
不走运:该类型始终列为Microsoft.PowerShell.Commands.WriteErrorException.
throw正是我所追求的。
代码
[CmdletBinding()]param()
Function Do-Something {
[CmdletBinding()]param()
Write-Error "something happened" -Category InvalidData
}
try{
Write-host "running Do-Something..."
Do-Something -ErrorAction Stop
}catch [System.IO.InvalidDataException]{ # would like to catch write-error here
Write-Host "1 caught"
}catch [Microsoft.PowerShell.Commands.WriteErrorException]{ # it's caught here
Write-host "1 kind of caught"
}catch{
Write-Host "1 not caught properly: $($Error[0].exception.GetType().fullname)"
}
Function Do-SomethingElse …Run Code Online (Sandbox Code Playgroud)