windows - Sådan stopper du et PowerShell-script på den første fejl?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil have mit PowerShell-script til at stoppe, når nogen af ​​de kommandoer, jeg kører, fejler (som set -e i bash). Jeg bruger begge Powershell-kommandoer (New-Object System.Net.WebClient) og programmer (.setup.exe).

Bedste reference


$ErrorActionPreference = "Stop" får dig en del af vejen der (dvs. det virker godt for cmdlets).


Men for EXE'er skal du selv undersøge $LastExitCode efter hver eksekvering og afgøre, om det mislykkedes eller ej. Desværre tror jeg ikke, at PowerShell kan hjælpe her, fordi Windows, EXEs ikke er forfærdeligt konsekvente på hvad der udgør en 'succes' eller 'fejl' exitkode. De fleste følger UNIX-standarden på 0, der tyder på succes, men ikke alle gør. Se CheckLastExitCode-funktionen i dette blogindlæg. Du kan finde det nyttigt. [15]

Andre referencer 1


Du skal kunne opnå dette ved at bruge sætningen $ErrorActionPreference = "Stop" i begyndelsen af ​​dine scripts.


Standardindstillingen for $ErrorActionPreference er Continue, og derfor ser du, at dine scripts fortsætter, når der opstår fejl.

Andre referencer 2


Desværre er der ikke nok af disse svar på grund af buggy cmdlets som New-RegKey og Clear-Disk. Jeg har i øjeblikket afgjort på følgende linjer øverst på ethvert powerhell-script til at opretholde min skønhed.


Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'


og så får ethvert indgående opkald denne behandling:


native\_call.exe
$native\_call\_success = $?
if (-not $native\_call\_success)
{
    throw 'error making native call'
}


Det indfødte opkaldsmønster bliver langsomt blevet almindeligt nok for mig, at jeg sandsynligvis skal se på muligheder for at gøre det mere koncist. Jeg er stadig en powerhell nybegynder, så forslag er velkomne.

Andre referencer 3


Du har brug for lidt anden fejlhåndtering til powershellfunktioner og til at ringe til exe s, og du skal være sikker på at fortælle opkalderen af ​​dit script, at den har svigtet. Opbygning oven på Exec fra biblioteket Psake, et script som har nedenstående struktur, stopper alle fejl og kan bruges som en basisskabelon til de fleste scripts.


Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"


# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
  This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
  to see if an error occcured. If an error is detected then an exception is thrown.
  This function allows you to run command-line programs without having to
  explicitly check the $lastexitcode variable.
.EXAMPLE
  exec { svn info $repository\_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
    )
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)
    }
}

Try {

    # Put all your stuff inside here!

    # powershell functions called as normal and try..catch reports errors 
    New-Object System.Net.WebClient

    # call exe's and check their exit code using Exec
    Exec { setup.exe }

} Catch {
    # tell the caller it has all gone wrong
    $host.SetShouldExit(-1)
    throw
}

Andre referencer 4


Jeg kom her på udkig efter det samme. $ ErrorActionPreference='Stop' dræber min shell øjeblikkeligt, når jeg vil se fejlmeddelelsen (pause), før den ophører. Tilbagefaldende til min batchfølsomhed:


IF \%ERRORLEVEL\% NEQ 0 pause & GOTO EOF


Jeg fandt ud af, at dette virker stort set det samme for mit særlige ps1 script:


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