CMD robocopy in for Schleife. Errorlevel ist leider immer 0 bei Fehler und bei Erfolg von robocopy
Robocopy liefert in aller Regel einen Errorlevel Wert zurück. Durch die FOR Schleife erhalte ich aber immer "errorlevel = 0"
Hallo zusammen,
Robocopy ist für mich ein bekanntes Tool welches ich auch häufig einsetze.
Aktuell versuche ich einen Ordner (...Skripte) von mehreren Servern zu kopieren.
Damit ich jetzt nicht x-mal robocopy server1(2,3,4,...) Quelle Ziel Parameter eingeben muss habe ich eine *.txt Datei in der ich alle Server aufliste.
Das funktioniert alles fehlerfrei!
Einzigstens Problem:
Wenn Robocopy bei einem der Server ein Problem hat (z.B. Zugriff verweigert....Datei nicht gefunden....blaaa) wird der Wert "Errorlevel" in meine CMD Box NICHT mit dem Robocopy errorlog überschrieben sondern bleibt immer ´0´
Sicher hängt das mit meiner FOR xxxxxyyyyyzzzzz Schleife zusammen die ja immer ´0´ zurück liefert. (Die For schleife funktioniert ja auch ... )
Nur wie bekomme ich das gelöst? Wie komm ich an den errorlog Wert von robocopy ran?
Wie kann ich prüfen lassen ob einer der Server, aus der *.txt, mit robocopy einen Fehler meldete?
Wenn ich den realen robocopy Befehl ausführen erhalte ich meinen korrekten robocopy errorlog. Aber ich brauch das ganze ja in der Schleife ... ok los gehts:
Ich hoffe ihr könnt hier helfen.
Vorweg - Ergebnis von der BAT:
BAT ANFANG
C:\>C:\skripte\cmd\Skripte_Backup\Skripte_Backup.cmd
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
C:\>
BAT ENDE
/
Skript Anfang
@echo off
echo.
:: Skript für die Sicherung der Skripte auf den Batchservern
:: von C:\skripte nach \\server1\Batchserver_skripte$
:: Variablen setzen
set "MailEXE=C:\skripte\bin\Maildienst\bmail.exe"
set "ABS=Batchserver@domain.dom"
set "Mailtxt=C:\skripte\cmd\server1_software_backup\EMail.txt"
set "temptxt=C:\skripte\temp\tempskripte.txt"
set "Quelle=\\%%i\skripte$\"
set "Ziel=\\server1\Batchserver_skripte$\%%i\"
set "Mailsrv=exchange.domain.dom"
set "RCPT=pruef1@domain.dom"
set "Subj=Backup von Skripte$ auf %%i hat einen Fehler gemeldet!"
set "Liste=C:\skripte\bin\Batchserverliste\alle_Batchserver.txt"
set "LOG=C:\skripte\logs\Skripte_Backup.log"
:: Löschen der alten LOGs
del /q "%LOG%"
del /q "%temptxt%"
:: Sicherung von Software$
for /f "usebackq delims=" %%i in ("%Liste%") do robocopy %Quelle% %Ziel% *.* /COPY:D /MIR /W:0 /R:0 /LOG+:%LOG% & echo %errorlevel%
:: Auswertung der Rückmeldung von Robocopy
if not errorlevel 0 echo FEHLER aufgetreten >> %LOG% & goto MAILVERSAND
:: for /f "usebackq delims=" %%i in ("%Liste%") do if not %Fehler%=0
:: echo Der Wert des Errorlevels ist %errorlevel% >> %LOG%
:: if errorlevel 16 echo *FATAL ERROR* >> %LOG% & goto MAILVERSAND
:: if errorlevel 15 echo FAIL MISM XTRA COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 14 echo FAIL MISM XTRA >> %LOG% & goto MAILVERSAND
:: if errorlevel 13 echo FAIL MISM COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 12 echo FAIL MISM >> %LOG% & goto MAILVERSAND
:: if errorlevel 11 echo FAIL XTRA COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 10 echo FAIL XTRA >> %LOG% & goto MAILVERSAND
:: if errorlevel 9 echo FAIL COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 8 echo FAIL >> %LOG% & goto MAILVERSAND
goto END
:: Bei einem Fehler wird die E-Mail versendet!
:MAILVERSAND
type %Mailtxt% >> %temptxt%
type %LOG% >> %temptxt%
%MailEXE% -s %Mailsrv% -t %RCPT% -f %ABS% -h -a "%Subj%" -m %temptxt% -c
del %temptxt%
:END
Skript Ende
Hallo zusammen,
Robocopy ist für mich ein bekanntes Tool welches ich auch häufig einsetze.
Aktuell versuche ich einen Ordner (...Skripte) von mehreren Servern zu kopieren.
Damit ich jetzt nicht x-mal robocopy server1(2,3,4,...) Quelle Ziel Parameter eingeben muss habe ich eine *.txt Datei in der ich alle Server aufliste.
Das funktioniert alles fehlerfrei!
Einzigstens Problem:
Wenn Robocopy bei einem der Server ein Problem hat (z.B. Zugriff verweigert....Datei nicht gefunden....blaaa) wird der Wert "Errorlevel" in meine CMD Box NICHT mit dem Robocopy errorlog überschrieben sondern bleibt immer ´0´
Sicher hängt das mit meiner FOR xxxxxyyyyyzzzzz Schleife zusammen die ja immer ´0´ zurück liefert. (Die For schleife funktioniert ja auch ... )
Nur wie bekomme ich das gelöst? Wie komm ich an den errorlog Wert von robocopy ran?
Wie kann ich prüfen lassen ob einer der Server, aus der *.txt, mit robocopy einen Fehler meldete?
Wenn ich den realen robocopy Befehl ausführen erhalte ich meinen korrekten robocopy errorlog. Aber ich brauch das ganze ja in der Schleife ... ok los gehts:
Ich hoffe ihr könnt hier helfen.
Vorweg - Ergebnis von der BAT:
BAT ANFANG
C:\>C:\skripte\cmd\Skripte_Backup\Skripte_Backup.cmd
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
Log File : C:\skripte\logs\Skripte_Backup.log
C:\>
BAT ENDE
/
Skript Anfang
@echo off
echo.
:: Skript für die Sicherung der Skripte auf den Batchservern
:: von C:\skripte nach \\server1\Batchserver_skripte$
:: Variablen setzen
set "MailEXE=C:\skripte\bin\Maildienst\bmail.exe"
set "ABS=Batchserver@domain.dom"
set "Mailtxt=C:\skripte\cmd\server1_software_backup\EMail.txt"
set "temptxt=C:\skripte\temp\tempskripte.txt"
set "Quelle=\\%%i\skripte$\"
set "Ziel=\\server1\Batchserver_skripte$\%%i\"
set "Mailsrv=exchange.domain.dom"
set "RCPT=pruef1@domain.dom"
set "Subj=Backup von Skripte$ auf %%i hat einen Fehler gemeldet!"
set "Liste=C:\skripte\bin\Batchserverliste\alle_Batchserver.txt"
set "LOG=C:\skripte\logs\Skripte_Backup.log"
:: Löschen der alten LOGs
del /q "%LOG%"
del /q "%temptxt%"
:: Sicherung von Software$
for /f "usebackq delims=" %%i in ("%Liste%") do robocopy %Quelle% %Ziel% *.* /COPY:D /MIR /W:0 /R:0 /LOG+:%LOG% & echo %errorlevel%
:: Auswertung der Rückmeldung von Robocopy
if not errorlevel 0 echo FEHLER aufgetreten >> %LOG% & goto MAILVERSAND
:: for /f "usebackq delims=" %%i in ("%Liste%") do if not %Fehler%=0
:: echo Der Wert des Errorlevels ist %errorlevel% >> %LOG%
:: if errorlevel 16 echo *FATAL ERROR* >> %LOG% & goto MAILVERSAND
:: if errorlevel 15 echo FAIL MISM XTRA COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 14 echo FAIL MISM XTRA >> %LOG% & goto MAILVERSAND
:: if errorlevel 13 echo FAIL MISM COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 12 echo FAIL MISM >> %LOG% & goto MAILVERSAND
:: if errorlevel 11 echo FAIL XTRA COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 10 echo FAIL XTRA >> %LOG% & goto MAILVERSAND
:: if errorlevel 9 echo FAIL COPY >> %LOG% & goto MAILVERSAND
:: if errorlevel 8 echo FAIL >> %LOG% & goto MAILVERSAND
goto END
:: Bei einem Fehler wird die E-Mail versendet!
:MAILVERSAND
type %Mailtxt% >> %temptxt%
type %LOG% >> %temptxt%
%MailEXE% -s %Mailsrv% -t %RCPT% -f %ABS% -h -a "%Subj%" -m %temptxt% -c
del %temptxt%
:END
Skript Ende
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 149721
Url: https://administrator.de/contentid/149721
Ausgedruckt am: 05.11.2024 um 07:11 Uhr
10 Kommentare
Neuester Kommentar
nun, es gibt da sicher verschiedene Ansätze.
Ersteinmal fährst Du in Deinem Beispiel eine Schleife und gibst jedesmal in der Console den Errorlevel aus. Das bis zum Ende der Textdatei. Erst nach dem letzten wertest Du Errorlevel aus! Und das wiederum vom letzten Befehl und der ist Echo %Errorlevel%. Der ist natürlich erfolgreich, sodass Du 0 bekommst.
Was Du aber machen willst ist, für jeden Robocopy Job ein Errorlevel auszugeben und wenn einer davon falsch ist, dann Meldung.
Ich würde es vielleicht so machen, das das ... & echo %Errolevel% geändert wird in z.B. Echo <SERVERNAME AUS LISTE> %ERRORLEVEL% >>ERRORSVC.LOG zu ändern.
Wenn alle Jobs durch sind das ERRORSVC.LOG auswerten und für jeden <SERVERNAME AUS LISTE> größer als 0 eine Mail zu schicken. So hätte man gleich einen Ansatz wo was geklemmt hat.
Karo
Ersteinmal fährst Du in Deinem Beispiel eine Schleife und gibst jedesmal in der Console den Errorlevel aus. Das bis zum Ende der Textdatei. Erst nach dem letzten wertest Du Errorlevel aus! Und das wiederum vom letzten Befehl und der ist Echo %Errorlevel%. Der ist natürlich erfolgreich, sodass Du 0 bekommst.
Was Du aber machen willst ist, für jeden Robocopy Job ein Errorlevel auszugeben und wenn einer davon falsch ist, dann Meldung.
Ich würde es vielleicht so machen, das das ... & echo %Errolevel% geändert wird in z.B. Echo <SERVERNAME AUS LISTE> %ERRORLEVEL% >>ERRORSVC.LOG zu ändern.
Wenn alle Jobs durch sind das ERRORSVC.LOG auswerten und für jeden <SERVERNAME AUS LISTE> größer als 0 eine Mail zu schicken. So hätte man gleich einen Ansatz wo was geklemmt hat.
Karo
Moin jonny83,
für den CMD-Interpreter, also die CMD.exe, die deinen Batch durchnudelt, ist doch aber dieses hier:
...genau eine Befehlszeile.
Und in einer Befehlszeile werde alle Variablen genau einmal aufgelöst, ungefähr dann, wenn der Buchstabe "f" der "for /f"-Anweisung gelesen wird.
Zu diesem Zeitpunkt wird %LOG% zu "C:\skripte\logs\Skripte_Backup.log" aufgelöst und eben auch %errorlevel% zu dem, was es vor dem ersten "f" der Zeile hat... zu 0, falls vorher kein Fehler war.
Wenn du eine Variable quasi erst dann auflösen willst, wenn die Ausführung unmittelbar beim ersten "%"-Zeichen von %errorlevel% angelangt ist, dann musst du die "verzögerte Variablenaulösung", neudeutsch "delayed expansion" verwenden und das deiner CMD-Interprerin sagen.
Dazu 2 Schritte:
a) am Anfang des Batches statt "Setlocal" ein "Setlocal EnableDelayedExpansion" (denn die CMD.exe spricht neudeutsch)
b) diejenigen Variablen, die du "unmittelbar vorm Verwenden" versätet auflösen willst, e.g. %errorlevel%,, statt mit Prozentzeichen mit Ausrufungszeichen einrahmen.
Sinngemäß:
Beispiele soltest du auch ohne Mühe einige hier im Forum mit die Suchfunktion finden.
Grüße
Biber
für den CMD-Interpreter, also die CMD.exe, die deinen Batch durchnudelt, ist doch aber dieses hier:
....
for /f "usebackq delims=" %%i in ("%Liste%") do robocopy [...blah ..]..& Echo %%i %ERRORLEVEL% >> %LOG2%
...
Und in einer Befehlszeile werde alle Variablen genau einmal aufgelöst, ungefähr dann, wenn der Buchstabe "f" der "for /f"-Anweisung gelesen wird.
Zu diesem Zeitpunkt wird %LOG% zu "C:\skripte\logs\Skripte_Backup.log" aufgelöst und eben auch %errorlevel% zu dem, was es vor dem ersten "f" der Zeile hat... zu 0, falls vorher kein Fehler war.
Wenn du eine Variable quasi erst dann auflösen willst, wenn die Ausführung unmittelbar beim ersten "%"-Zeichen von %errorlevel% angelangt ist, dann musst du die "verzögerte Variablenaulösung", neudeutsch "delayed expansion" verwenden und das deiner CMD-Interprerin sagen.
Dazu 2 Schritte:
a) am Anfang des Batches statt "Setlocal" ein "Setlocal EnableDelayedExpansion" (denn die CMD.exe spricht neudeutsch)
b) diejenigen Variablen, die du "unmittelbar vorm Verwenden" versätet auflösen willst, e.g. %errorlevel%,, statt mit Prozentzeichen mit Ausrufungszeichen einrahmen.
Sinngemäß:
....
Setlocal EnableDelayedExpansion
..
....
for /f "usebackq delims=" %%i in ("%Liste%") do robocopy [...blah ..]..& Echo %%i !ERRORLEVEL! >> %LOG2%
...
Beispiele soltest du auch ohne Mühe einige hier im Forum mit die Suchfunktion finden.
Grüße
Biber