我希望我的PowerShell脚本在我运行的任何命令失败时停止(如bash中的set -e)。我正在使用Powershell命令(New-Object System.Net.WebClient)和程序(.\setup.exe)。


当前回答

我来这里也是为了寻找同样的东西。$ErrorActionPreference="Stop"立即杀死我的shell时,我宁愿看到错误消息(暂停)之前,它终止。回到我的批处理敏感性:

IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF

我发现这对我的特定ps1脚本几乎是一样的:

Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}

其他回答

据我所知,Powershell对它调用的子程序返回的非零退出码没有任何自动处理。

到目前为止,我所知道的模仿bash -e行为的唯一解决方案是在每次调用外部命令后添加这个检查:

if(!$?) { Exit $LASTEXITCODE }

对于2021年来到这里的人,这是我的解决方案,涵盖了cmdlet和程序

function CheckLastExitCode {
    param ([int[]]$SuccessCodes = @(0))

    if (!$?) {
        Write-Host "Last CMD failed" -ForegroundColor Red
        #GoToWrapperDirectory in my code I go back to the original directory that launched the script
        exit
    }

    if ($SuccessCodes -notcontains $LastExitCode) {
        Write-Host "EXE RETURNED EXIT CODE $LastExitCode" -ForegroundColor Red
        #GoToWrapperDirectory in my code I go back to the original directory that launched the script
        exit
    } 
    
}

你可以这样用

cd NonExistingpath
CheckLastExitCode

看来简单的重掷就行了。

param ([string] $Path, [string] $Find, [string] $Replace)
try {
  ((Get-Content -path $Path -Raw) -replace $Find, $Replace) | Set-Content -Path $Path
  Write-Output Completed.
} catch {
  # Without try/catch block errors don't interrupt program flow.
  throw
}

现在只有在成功执行之后才会出现输出Completed。

重定向stderr到stdout似乎也没有任何其他命令/scriptblock包装的技巧,尽管我找不到一个解释为什么它是这样工作的。

# test.ps1

$ErrorActionPreference = "Stop"

aws s3 ls s3://xxx
echo "==> pass"

aws s3 ls s3://xxx 2>&1
echo "shouldn't be here"

这将如预期的那样输出以下内容(命令aws s3…返回$LASTEXITCODE = 255)

PS> .\test.ps1

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
==> pass

我刚接触powershell,但这似乎是最有效的:

doSomething -arg myArg
if (-not $?) {throw "Failed to doSomething"}