thomaskunze
Goto Top

return codes werden in batch-datei fehlerhatft ausgewertet

Hallo,

ich veruche mich an meinem ersten (kleinen) script, um remote-clients herunterzufahren. Dazu nutze ich psshutdown und eine Textdatei mit den Namen der PCs. Allerdings möchte ich evt. auftretende Fehler in einer weiteren Textdatei dokumentieren, weshalb ich nicht einfach die Rechnerliste an psshutdown übergeben kann.
Meine batch-Datei auzurufen unter XP/Vista(als Administrator) - getestet unter Vista:

@echo off

if exist fehler.txt (del fehler.txt)

For /F "tokens=1" %%a IN (rechner.txt) DO (  
 	echo. & echo Shutting down %%a:
 	psshutdown -k -c -m BLAH -t 600 \\%%a
	echo %errorlevel%
 	if errorlevel 0 (echo %%a - OK & echo %%a - OK >> fehler.txt) else (echo %%a - Fehler: %errorlevel% & echo %%a - Fehler: %errorlevel% >> fehler.txt)
)
pause
exit

Mein Problem: Obwohl psshutdown "sinnvolle" return codes ausgibt (0 bzw. 1), liefert obiges script immer ein OK zurück auch wenn ich nicht existierende Rechner in der Liste stehen habe.

IMO müsste das script doch so stimmen oder nicht?

Vielen Dank für jede Erklärung/Tip!


Ausgabe der Batchdatei (der Rechner "zwerg" existiert, "26" nicht):

D:\!Tools\PsTools>test.bat

Shutting down zwerg:

PsShutdown v2.52 - Shutdown, logoff and power manage local and remote systems
Copyright (C) 1999-2006 Mark Russinovich
Sysinternals - www.sysinternals.com

Local system is scheduled to power off in 00:10:00.

0
zwerg - OK

Shutting down 26:

PsShutdown v2.52 - Shutdown, logoff and power manage local and remote systems
Copyright (C) 1999-2006 Mark Russinovich
Sysinternals - www.sysinternals.com

Couldn't access 26:  
Der Netzwerkpfad wurde nicht gefunden.

Make sure that the default admin$ share is enabled on 26.

If 26 is already performing a shutdown operation you must
abort it before issuing a different command.

0
26 - OK
Drücken Sie eine beliebige Taste . . .

An der Konsole hingegen:

D:\!Tools\PsTools>psshutdown -k -c -m BLAH -t 600 \\zwerg

PsShutdown v2.52 - Shutdown, logoff and power manage local and remote systems
Copyright (C) 1999-2006 Mark Russinovich
Sysinternals - www.sysinternals.com

Local system is scheduled to power off in 00:10:00.



D:\!Tools\PsTools>echo %errorlevel%
0

und

D:\!Tools\PsTools>psshutdown -k -c -m BLAH -t 600 \\26

PsShutdown v2.52 - Shutdown, logoff and power manage local and remote systems
Copyright (C) 1999-2006 Mark Russinovich
Sysinternals - www.sysinternals.com

Couldn't access 26:  
Der Netzwerkpfad wurde nicht gefunden.

Make sure that the default admin$ share is enabled on 26.

If 26 is already performing a shutdown operation you must
abort it before issuing a different command.


D:\!Tools\PsTools>echo %errorlevel%
1

Edit: Formatierung angepasst

Content-Key: 104126

Url: https://administrator.de/contentid/104126

Printed on: April 20, 2024 at 00:04 o'clock

Member: Biber
Biber Dec 15, 2008 at 14:13:39 (UTC)
Goto Top
Moin thomaskunze,

willkommen im Forum.
3 Tipps zu Deinem Schnipsel:
1) am besten < code >-Formatierung benutzen - siehe "Formatierungshilfe" beim Editieren oder in den FAQ

Problem ist, dass alles innerhalb einer FOR-Anweisung bis zur letzten schließenden KlammerZu vom CMD als EINE Codezeile aufgefasst wird und darin auch alle Variablen nur einmalig "errechnet"/aufgelöst werden. Nämlich am Beginn der Verarbeitung. Wenn die CMD.exe das Wort FOR liest sozusagen. Und deshalb hat auch %errorlevel% den Wert, den es schon beim ersten Lesen dieses Wortes hatte.

2) Workaround I
@echo off & setlocal enableDelayedExpansion

if exist fehler.txt (del fehler.txt)

For /F "tokens=1" %%a IN (rechner.txt) DO (  
    echo. & echo Shutting down %%a:
    psshutdown -k -c -m BLAH -t 600 \\%%a
    if not errorlevel 1 (
         echo %%a - OK 
         echo %%a - OK >> fehler.txt
    ) else ( 
        echo %%a - Fehler: !errorlevel! 
        echo %%a - Fehler: !errorlevel! >> fehler.txt)
 )
 pause
exit

3) Workaround II - mit Call:Block
@echo off

if exist fehler.txt (del fehler.txt)

For /F "tokens=1" %%a IN (rechner.txt) DO call :brezeldown %%a  
 pause
exit
goto :eof

:brezeldown Parameter %1 ist der Rechnername/IP (vorher %%a)
echo.
echo Shutting down %1:
psshutdown -k -c -m BLAH -t 600 \\%1
if errorlevel 1 (
        echo %1 - Fehler: %errorlevel% 
        echo %1 - Fehler: %errorlevel% >> fehler.txt)
        goto :eof
)
:: else-Fall: Errorlevel war NICHT 1 oder höher
   echo %1 - OK 
   echo %1 - OK >> fehler.txt
goto :eof

Grüße
Biber
[Edit] Tippfehlerkorrektur, [/Edit]
Member: thomaskunze
thomaskunze Dec 15, 2008 at 14:26:36 (UTC)
Goto Top
Vielen Dank für die prompte Antwort! Ich werde Deine Vorschläge gerne ausprobieren!

Viele Grüße,

Tom

Edit: Es hat (natürlich) geklappt. Nochmals vielen Dank!