Zum Inhalt wechseln


Foto

Fehlerbehandlung bei Powershell-Scripte


  • Bitte melde dich an um zu Antworten
22 Antworten in diesem Thema

#1 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 16. März 2010 - 08:58

Hallo,
bin neu hier und möchte mich gerne in Powershell einarbeiten.
Ich suche eine Lösung um Fehler im Script abzufangen und darauf zu reagieren. Wenn im Script ein Fehler auftritt soll das Script abbrechen und einen Fehlerschalter setzen sodass eine Folgeverarbeitung nicht anläuft.
Ich möchte ein Powershellscript in einer Batchdatei aufrufen.
Z.Zt. wird der Errorlevel gesetzt und abgefragt, so können Folgejobs (Batch)
weiterlaufen oder blockiert werden.

Für eine verständliche (Anfänger) Lösung bin ich sehr dankbar.

Pet7:)

#2 blub

blub

    Moderator

  • 7.605 Beiträge

 

Geschrieben 16. März 2010 - 09:48

Hallo,
In der Powershellhilfe steht sehr viel dazu
get-help about_CommonParameters
z.B. unter -Erroraction

Evtl. findest du hier auch was
PowerShell Preference Variables /CommonParameters - PowerShellPraxis.de

Darüber wie man PS-skripte startet, findest du hier gute Infos
Running Windows PowerShell Scripts

cu
blub

Ein Kluger bemerkt alles, Ein Dummer macht über alles eine Bemerkung. (Heinrich Heine)


#3 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 16. März 2010 - 10:17

Hallo,
In der Powershellhilfe steht sehr viel dazu
get-help about_CommonParameters
z.B. unter -Erroraction

Evtl. findest du hier auch was
PowerShell Preference Variables /CommonParameters - PowerShellPraxis.de

Darüber wie man PS-skripte startet, findest du hier gute Infos
Running Windows PowerShell Scripts

cu
blub


Hallo blub,

erst mal danke für die schnelle Antwort.
Habe die eine oder andere Seite zu diesem Thema im Web schon ausfindig gemacht. Nur ist es nicht so einfach das umzusetzen.
Da ich das PS-Script aus einer Windows-Batchdatei starte muß ich bei einem Fehler der im PS-Script auftaucht die Variable %errorlevel% setzen damit ich richtig auf die Folgeverarbeitung reagieren kann.

Danke schon mal.

Pet7

#4 Cybquest

Cybquest

    Expert Member

  • 1.888 Beiträge

 

Geschrieben 16. März 2010 - 10:25

Schau mal hier:
Microsoft und Umwelt : Windows PowerShell Exit Codes: wie nutzen?


Wäre es nicht eleganter, einfach alles per Powershell zu erledigen, statt mit Batch plus Powershell?
My name is Frank, you can say you to me.

#5 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 16. März 2010 - 10:53

Schau mal hier:
Microsoft und Umwelt : Windows PowerShell Exit Codes: wie nutzen?


Wäre es nicht eleganter, einfach alles per Powershell zu erledigen, statt mit Batch plus Powershell?


Hallo Cybquest,

auch dir erstmal danke.
Es muß über die Batch-Datei laufen!
Ich glaube das funktioniert so nicht.
Habe gelesen dass die Variable $lastexitcode nur für externe Programme gilt.
Wenn ich z.B. ein Copy-Commando verwende und der Pfad ist fehlerhaft wird die Variable nicht gesetzt.
Werde das aber alles nochmal in Ruhe überprüfen.

Gruß Pet7

#6 Bernd W

Bernd W

    Newbie

  • 9 Beiträge

 

Geschrieben 16. März 2010 - 11:57

Hallo Pet7,
mit Powersell geht das auf jeden Fall:
1. Kannst Du alles was du im Batch aufrufst auch direkt in Powershell aufrufen z.B. robocopy.exe und dann mit $Lastexitcode arbeiten
2. Kannst Du die Variable $? aus werten die True zurückgibt wenn der Letzte Befehl erfolgreich war
3. Kannst Du $error auswerten
4. Kannst Du sog. Traps oder Try-Catch Blöcke (ab PS V2.0) verwenden um Fehler abzufangen bzw. darauf zu reagieren

Wenn Du deinen Code mal reinstellst kann ich sicher auch konkreter werden.... .

Bruß
Bernd

PS: Schau mal bei xxxx rein

[edit]
Links bitte nur, wenn Sie konkret der Problemlösung des To's dienen, nicht um deine Seite zu promoten
Danke für dein Verständnis
blub

Bearbeitet von blub, 16. März 2010 - 14:27.


#7 Cybquest

Cybquest

    Expert Member

  • 1.888 Beiträge

 

Geschrieben 16. März 2010 - 11:59

Du musst in deinem Powershell-Script den Errorcode selbst als Exitcode ausgeben.
Bei einem Copykommando also z.B. ein -ErrorVariable $err anhängen
und dann das Script mit Exit $err beenden.
In der Batch steht das dann als Errorcode zur Verfügung (wie im Link beschrieben)
My name is Frank, you can say you to me.

#8 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 16. März 2010 - 13:01

Hallo Pet7,
mit Powersell geht das auf jeden Fall:
1. Kannst Du alles was du im Batch aufrufst auch direkt in Powershell aufrufen z.B. robocopy.exe und dann mit $Lastexitcode arbeiten
2. Kannst Du die Variable $? aus werten die True zurückgibt wenn der Letzte Befehl erfolgreich war
3. Kannst Du $error auswerten
4. Kannst Du sog. Traps oder Try-Catch Blöcke (ab PS V2.0) verwenden um Fehler abzufangen bzw. darauf zu reagieren

Wenn Du deinen Code mal reinstellst kann ich sicher auch konkreter werden.... .

Bruß
Bernd

PS: Schau mal bei xxxxxxx rein



Hallo Bernd,

danke für die Antwort.

zur Zeit läuft der Job wie folgt:

Inhalt der Batchdatei:

copy Quelldatei Zieldatei
if %errorlevel% ne 0 set retcode=%errorlevel%

#bei %retcode% ungleich 0 wird dann zum Fehlerausgang gesprungen und keine Folgeverarbeitung angestoßen


Künftig möchte ich den Code in eine Datei copy.ps1 schreiben.
Diese wird dann wie folgt aus einer Batchdatei gestartet:

cmd.exe:

powershell -name C:\copy.ps1

Anschließend muß die Variable %retcode% entsprechend versorgt werden.

set retcode= wie auch immer.

Gruß

Pet7

Bearbeitet von blub, 16. März 2010 - 14:26.


#9 Bernd W

Bernd W

    Newbie

  • 9 Beiträge

 

Geschrieben 17. März 2010 - 11:54

Hallo Pet7,
ich fasse mal zusammen:
Du startest aus einem Batchfile heraus ein Powershell Skript. In dem PS Skript führst Du Befehle aus, z.B. kopieren, die evtl. schief gehen können. In Abhängigkeit dessen willst Du in Deinem Batchfile mit Hilfe von %errorlevel% darauf reagieren.


CMD Test-Batch "test.bat" (wie in dem Link von cybquest beschrieben):

@echo off
powershell -noprofile -command "& {"d:\Test\test.ps1"; exit $Lastexitcode}"
echo Rueckgabewert: %errorlevel%




Powershell Test-Skript "test.ps1":

$ErrorActionPreference = 'Stop'
trap {
"Ein Fehler ist passiert"
exit 5
}

Copy-Item 'C:\Temp\gibtsnicht.txt' 'c:\Temp\a'




Die Variable $ErrorActionPreference muss auf Stop gestellt werden damit der Fehler nicht von cmdlet selbst sondern von der Trap behandelt wird. Das gilt dann für alle cmdlets. Alternativ kannst du beim jeweiligen cmdlet auch den Parameter -Erroraction 'stop' anhängen.
In der Trap wird das Skript mit dem Exitcode, im Beispiel 5, verlassen.


Hoffe das hilft Dir
Gruß
Bernd

Bearbeitet von Bernd W, 17. März 2010 - 11:58.
Formatierung


#10 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 17. März 2010 - 12:02

Schau mal hier:
Microsoft und Umwelt : Windows PowerShell Exit Codes: wie nutzen?


Wäre es nicht eleganter, einfach alles per Powershell zu erledigen, statt mit Batch plus Powershell?


Hallo Cybquest,

habe mir die Seite mal angeschaut.
Bei mir funktioniert das nicht!

Hier der Inhalt meiner Script-Datei H:\e1.ps1 :

Copy-Item c:\ps\e12.txt c:\ps\a2.txt

(die Datei e12.txt gibt es nicht!)


Hier der Aufruf an der Console:

H:\>powershell -command "& { H:\e1.ps1;exit $Lastexitcode}"

und hier die Ausgabe des Kommandos:

H:\>echo %errorlevel%
0

H:\>powershell -command "& { H:\e1.ps1;exit $Lastexitcode}"
Copy-Item : Cannot find path 'C:\ps\e12.txt' because it does not exist.
At H:\e1.ps1:1 char:10
+ Copy-Item <<<< c:\ps\e12.txt c:\ps\a2.txt
+ CategoryInfo : ObjectNotFound: (C:\ps\e12.txt:String) [Copy-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand


H:\>echo %errorlevel%
0


Ich verstehe es nicht.

Gruß Pet7

#11 Cybquest

Cybquest

    Expert Member

  • 1.888 Beiträge

 

Geschrieben 17. März 2010 - 12:07

Bernd W hats fein beschrieben. Vermutlich hast Du's inzwischen gelesen... ;)
My name is Frank, you can say you to me.

#12 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 17. März 2010 - 12:15

Hallo Pet7,
ich fasse mal zusammen:
Du startest aus einem Batchfile heraus ein Powershell Skript. In dem PS Skript führst Du Befehle aus, z.B. kopieren, die evtl. schief gehen können. In Abhängigkeit dessen willst Du in Deinem Batchfile mit Hilfe von %errorlevel% darauf reagieren.


CMD Test-Batch "test.bat" (wie in dem Link von cybquest beschrieben):


@echo off
powershell -noprofile -command "& {"d:\Test\test.ps1"; exit $Lastexitcode}"
echo Rueckgabewert: %errorlevel%




Powershell Test-Skript "test.ps1":

$ErrorActionPreference = 'Stop'
trap {
"Ein Fehler ist passiert"
exit 5
}

Copy-Item 'C:\Temp\gibtsnicht.txt' 'c:\Temp\a'




Die Variable $ErrorActionPreference muss auf Stop gestellt werden damit der Fehler nicht von cmdlet selbst sondern von der Trap behandelt wird. Das gilt dann für alle cmdlets. Alternativ kannst du beim jeweiligen cmdlet auch den Parameter -Erroraction 'stop' anhängen.
In der Trap wird das Skript mit dem Exitcode, im Beispiel 5, verlassen.


Hoffe das hilft Dir
Gruß
Bernd



Hallo Bernd,

erst mal vielen Dank für die Antwort.
Werde das jetzt mal ausprobieren.
Verstehe ich das richtig, dass in jeder Batchdatei dann die Variable
$ErrorActionPreference entsprechend gesetzt werden muß?

Was ist mit den Variablen $Error + $?, kann ich die dafür nicht verwenden?
Vorab schon Danke.

Gruß
Pet7

#13 Cybquest

Cybquest

    Expert Member

  • 1.888 Beiträge

 

Geschrieben 17. März 2010 - 12:33

Noch ne Möglichkeit für die ps1-Datei:
Copy-Item 'C:\Temp\gibtsnicht.txt' 'c:\Temp\a' -ErrorAction "Stop" -ErrorVariable $err
exit $err

Batch, wie Bernd beschrieben hat.

Die ganzen $-Variablen braucht Du in der Batch überhaupt nicht!
My name is Frank, you can say you to me.

#14 Pet7

Pet7

    Newbie

  • 17 Beiträge

 

Geschrieben 17. März 2010 - 12:52

Noch ne Möglichkeit für die ps1-Datei:

Copy-Item 'C:\Temp\gibtsnicht.txt' 'c:\Temp\a' -ErrorAction "Stop" -ErrorVariable $err
exit $err

Batch, wie Bernd beschrieben hat.

Die ganzen $-Variablen braucht Du in der Batch überhaupt nicht!


Hallo,

habe es ausprobiert, hat funktioniert.
Ich möchte es auch verstehen, deshalb noch die Frage:
In der $err steht der Returncode der per exit $err an die Variable %errorlevel% übergeben wird - ist das korrekt?

Danke.

Gruß Pet7

#15 Cybquest

Cybquest

    Expert Member

  • 1.888 Beiträge

 

Geschrieben 17. März 2010 - 13:26

In der $err steht der Returncode der per exit $err an die Variable %errorlevel% übergeben wird - ist das korrekt?


Genau so kann man's ausdrücken :)
My name is Frank, you can say you to me.