noc06
Goto Top

Backup-Skript für Robocopy mit datumsabhängigen Zielverzeichnissen

Hallo zusammen,

ich hatte diese Frage zwar bereits im Bereich \IT-Sicherheit & Recht\Backups gepostet, allerdings glaube ich, daß er hier doch besser aufgehoben ist.

Zunächst mal mein Ausgangsposting:
Hallo zusammen!

Ich stehe derzeit vor einem kleinen Problem bzgl. eines durch Skripte automatisierten Backups mit Robocopy und habe über die Suche leider nichts gefunden, was mir bei meinem Problem direkt weiterhelfen könnte, zumal meine persönlichen Skripterfahrungen gegen Null tendieren und die Kenntnisse von Robocopy auch eher rudimentärer Natur sind.

Vielleicht könnte mir ja jemand von Euch einen Tipp geben. Ich wäre Euch jedenfalls sehr dankbar.


Die Daten eines W2k3 Systems sollen im Wochenwechsel auf 2 externe Platten gesichert werden (also Platte 1 in KW 1, Platte 2 in KW 2, Platte 1 in KW 3 und so weiter), inkl. der bestehenden NTFS Berechtigungen und Freigaben.

Als Grundüberlegung für die Datensicherung besteht derzeit folgende Planung:

  • Gesichert werden Mo-Do (nachts) in einem separaten Verzeichnis, zunächst erstmalig jeweils als Vollbackup (der Originaldatenbestand würde in diesem Verzeichnis also 4x gespiegelt vorliegen), danach erfolgt nur noch die Sicherung der zu diesem Zeitpunkt geänderten Daten und das auf beiden Platten. Somit wäre eine Rückgriffsmöglichkeit auf den Datenbestand (quasi taggenaue Spiegelung) der letzten 13 Tage jederzeit möglich. Am 14 Tag wird die jeweilige Sicherung wieder überschrieben (Bsp.: am 1. Montag, dem 1.1., findet das erste Montag-Backup auf Platte 1 statt. Am darauffolgenden Montag, dem 8.1., findet das zweite Montag-Backup auf Platte 2 statt. Am dritten Montag, dem 15.1., erfolgt das dritte Montag-Backup wieder auf Platte 1 und überschreibt somit die Sicherung vom 1.1. – die anderen Wochentage erfolgen analog hierzu).
  • Freitags erfolgt die Sicherung als Kalenderwoche (KW), ebenfalls in einem separaten Verzeichnis; auf der 1. Platte befinden sich somit (in diesem Beispiel) die ungeraden KW (1.KW, 3.KW,...), wohingegen sich die geraden (2.KW, 4.KW,...) auf der 2. Platte befinden. Die KW Sicherungen sollen alle als Vollsicherungen erhalten bleiben und jeweils mit Datum (ggfs. auch der KW) im Dateinamen gespeichert werden (für ein Kalenderjahr würde dies bei 2 Platten also 26 KW Vollbackups entsprechen).

  • Eine weitere Überlegung geht momentan dahin, zusätzlich auch noch ein Vollbackup jeweils am Monatsende durchzuführen und dieses entsprechend mit dem Monatsnamen versehen ebenfalls in einem eigenen Verzeichnis abzulegen.

  • Die Verzeichnisstruktur auf den ext. Festplatten würde somit wie folgt aussehen exemplarisch für Platte 1):
** Laufwerk X:
1. Tagessicherung (Mo-Do)
2. Wochensicherung (KW_ung)
3. Monatssicherung

Kann man etwas derartiges überhaupt noch sinnvoll in ein einzelnes Skript packen?

Die ersten Vollbackups für die Wochentage würden noch per Hand ausgeführt werden und müssten somit nicht zwingend mit in ein Skript eingebunden werden.

Zwecks Vereinfachung gehe ich derzeit auch davon aus, dass ausschließlich ganze Laufwerke gesichert werden sollen und keine einzelnen Verzeichnisse – die Sicherung von einzelnen Verzeichnissen würde ein derartiges Skript m.E. erst recht sprengen, sollte dies überhaupt vernünftig darstellbar sein.

Vielen Dank vorab und schönen Gruß
Noc06



Nach ein wenig rumprobieren (bin wie gesagt absoluter Laie, was das Skripte schreiben betrifft) und Bastelei ist m.E. zumindest im Ansatz etwas brauchbares rausgekommen, was ich auch gerne zwecks Kritik und Verbesserungsvorschlägen hier posten möchte, allerdings würde ich gerne zuvor noch selbst einen Punkt einbauen, bei dem ich derzeit allerdings leider nicht weiterkomme.

Mein Problem liegt momentan darin, daß ich die Abfrage, die zu der separaten Monatssicherung führen soll, nicht zum Laufen bekomme. Biber (thx hierfür nochmal!) war hier so freundlich und hat mir den notwendigen Code gezeigt, nämlich

' ---- vbsSnippet.vbs  
If WScript.arguments.count = 1 Then 
   dDate=WScript.arguments.item(0) 
  Else 
    dDate=Date
End If       
Wscript.echo dateAdd ("d", -1, dateAdd("m", 1, "01." & Month(dDate) & "." &year(ddate)))  

Ruft man das ganze in der cmd-Line über

cscript //nologo vbsSnippet.vbs

auf, erhält man auch gleich das benötigte Datum, welches für einen IF Abgleich nötig wäre (nämlich ist "heutiges datum" = "Monatsletzter"). Leider bekomme ich das aber nicht hin...

Könnte mir bitte jemand von Euch die richtige Schreibweise verraten, in der man einen derartigen Abgleich in ein Skript reinpackt?

Sobald ich den Teil habe, poste ich den Rest von meinem zusammengezimmerten etwas - dann deckt das, wenn auch im Komplettumfang noch nicht getestet, zumindest den Teil meiner ursprünglichen Problemstellung ab.

Vielen Dank vorab und schönen Gruß
Noc06

Content-ID: 118683

Url: https://administrator.de/forum/backup-skript-fuer-robocopy-mit-datumsabhaengigen-zielverzeichnissen-118683.html

Ausgedruckt am: 22.12.2024 um 12:12 Uhr

bastla
bastla 21.06.2009 um 17:43:15 Uhr
Goto Top
Hallo Noc06!

Im Batch wäre der Aufruf dann zB
for /f %%i in ('cscript //nologo vbsSnippet.vbs') do set "Letzter=%%i"  
if "%date%"=="%Letzter%" echo Heute Monatssicherung  
Grüße
bastla
Noc06
Noc06 21.06.2009 um 20:19:50 Uhr
Goto Top
Hallo bastla!

Vielen Dank für Deinen Tipp - so hat es jetzt auch funktioniert.

Wie versprochen, poste ich jetzt auch mal das von mir zusammengezimmerte Programm, daß ich allerdings noch nicht komplett getestet habe (Nutzung erfolg auf eigene Verantwortung).

Hinweisen möchte ich auch darauf, daß es sich bei der von mir angestrebten Datensicherung um jeweils "tägliche" Spiegelungen der Quellen handelt - je nach Datenmenge können so auf dem Sicherungsmedium einige GB bis TB zusammenkommen (für Bänder und CDs/DVDs also u.U. eher ungeeignet).
Die ECHO kann man sich an vielen Stellen auch schenken; ich hatte sie hauptsächlich für mich als Kontrollmechanismen eingebaut.


::---Tagesabhängiges Backup-Skript für unterschiedliche Ziellaufwerke (nicht getestet - Anwendung erfolgt auf eigene Verantwortung!)


@Echo off & setlocal


::----Definition der Konstanten



::--------hier: Dateipfad Robocopy

SET RC_path="C:\WINDOWS\SysWOW64\ROBOCOPY.EXE"  




::--------hier: Quellverzeichnisse (Exemplarisch...)

SET Quelle='C:\Dokumente'  




::--------hier: Zielverzeichnisse (Exemplarisch...)

SET bck_Mo='E:\Montag_Donnerstag\Montag'  
SET bck_Di='E:\Montag_Donnerstag\Dienstag'  
SET bck_Mi='E:\Montag_Donnerstag\Mittwoch'  
SET bck_Do='E:\Montag_Donnerstag\Donnerstag'  
SET bck_Fr='E:\Kalenderwoche'  
SET bck_Monatsende='E:\Monatssicherung'  




::--------hier: Neu anzulegende Verzeichnisse für Kalenderwochen- und Monatssicherung

SET KW_bckdir=%bck_Fr%\%OSKW%.KW_%%JJ%_%MM%_%TT%
SET MM_bckdir=%bck_Monatsende%\%MM%.Monatsende_%%JJ%_%MM%_%TT%




::--------hier: anzuwendende Robocopy-Parameter

SET Log_dir="C:\Log-Files\Backups\Robocopy\"  

SET Log_filename=%Log_dir%%cDoW%_%JJ%_%MM%_%TT%.log

SET Copy_MoDo=/MIR /COPYALL /DCOPY:T /A

SET Copy_Fr=/MIR /COPYALL /DCOPY:T

SET Optionen=/R:0 /W:0 /NP / TEE /LOG+:%Log_filename%




::----Programmanfang



::-------Datumsabfrage zwecks späterer Verteilung Kopieraufträge
::-------Aufruf des Programms zur Datumsabfrage aus Bibers Tutorial, zu finden unter www.administrator.de/Workshop_Batch_for_Runaways_Part_III_Datums-_und_Zeitvariablen_im_Batch.html

Call GetAllDateTimeInfos /s /q




::--------hier: Abfrage des jeweils aktuellen Wochentages mit anschlie?ender Ausführung des Backups für die Tage Montag bis Donnerstag (werden im Wochenwechsel immer wieder überschrieben)

if %cDoW%==Mo ECHO Heute ist Montag, der %TT% %MM% %JJ%
%RC_path% %Quelle% %bck_Mo% %Copy_MoDo% %Optionen%

if %cDoW%==Di ECHO Heute ist Dienstag, der %TT% %MM% %JJ%
%RC_path% %Quelle% %bck_Di% % Copy_MoDo % %Optionen%

if %cDoW%==Mi ECHO Heute ist Mittwoch, der %TT% %MM% %JJ%
%RC_path%%Quelle% %bck_Mi% % Copy_MoDo % %Optionen%

if %cDoW%==Do ECHO Heute ist Donnerstag, der %TT% %MM% %JJ%
%RC_path%%Quelle% %bck_Do% % Copy_MoDo % %Optionen%

if %cDoW%==Sa echo Heute ist Samstag
if %cDoW%==So echo Heute ist Sonntag


::--------hier: Abfrage des Wochentages => Freitags erfolgt eine separate Sicherung in einen neuen, noch zu erstellenden Ordner mit der jeweils aktuellen Kalenderwoche

if %cDoW%==Fr ECHO Heute ist Freitag, der %TT% %MM% %JJ% und wir befinden uns in der %OSKW% Kalenderwoche

md %KW_bckdir%

%RC_path%%Quelle% %bck_Fr% % Copy_Fr% %Optionen%




::--------hier: Abfrage, ob das aktuelle Datum dem Monatsletzten entspricht => falls ja, wird ein neues Verzeichnis mit dem Monatsdatum erstellt und es erfolgt eine zusätzliche Sicherung
::--------Anmerkung: bei LastDayOfMonth.vbs wird ermittelt, welches der, vom aktuellen Datum aus gesehen, Monatsletzte ist.

for /f %%i in ('cscript //nologo LastDayOfMonth.vbs') do set "Letzter=%%i"   
if "%date%"=="%Letzter%" echo Heute Monatssicherung  
if not "%date%"=="%Letzter%" echo Heute ist NICHT der Moantsletzte - keine Sicherung erforderlich  

md %MM_bckdir%

%RC_path%%Quelle% %bck_Monatsende% % Copy_Fr% %Optionen%



Call GetAllDateTimeInfos /u


::----Ende des Programms
:END

Hier auch noch der Code für die LastDayOfMonth.vbs (habe es leider nicht hinbekommen, es direkt in das eigentliche Skript einzubauen - beide Dateien müssen also im gleichen Verzeichnis liegen):

'-------LastDayOfMonth.vbs  

If WScript.arguments.count = 1 Then  
   dDate=WScript.arguments.item(0)  
  Else  
    dDate=Date 
End If        
Wscript.echo dateAdd ("d", -1, dateAdd("m", 1, "01." & Month(dDate) & "." &year(ddate)))  


Einen Schönheitspreis wird das Teil sicherlich nicht gewinnen, nach meinem Laienverständnis sollte es aber für meine Zwecke ausreichend sein.

Für Anregungen und Verbesserungsvorschläge bin ich selbstverständlich immer dankbar.

Schönen Gruß
Noc06

(P.S.: Das ganze soll später über den M$-Taskplaner jede Nacht ausgeführt werden.)
36539
36539 22.06.2009 um 06:00:30 Uhr
Goto Top
Hallo,

Dein "LastDayOfMonth.vbs" musst Du auch nicht einbauen, ginge aber.

rem Name der *.vbs erstellen
set "bckTemp=%temp%\LastDayOfMonth.vbs"  
rem Befehle die in der *.vbs stehen sollen erstellen 
echo If WScript.arguments.count = 1 Then > "%bckTemp%"  
echo   dDate=WScript.arguments.item(0) >> "%bckTemp%"  
echo  Else >> "%bckTemp%"  
echo    dDate=Date >> "%bckTemp%"  
echo End If >> "%bckTemp%"  
echo Wscript.echo dateAdd ("d", -1, dateAdd("m", 1, "01." & Month(dDate) & "." &year(ddate))) >> "%bckTemp%"  
rem wenn Du "%bckTemp%" danach nicht mehr benötigtst, dann letzte Zeile  
del /f /s /q "%bckTemp%" > nul  
mfg
onegasee59
Biber
Biber 22.06.2009 um 07:05:27 Uhr
Goto Top
Moin Noc06,

oder aber - um onegasse59s Ansatz konsequent zu (einem vorläufigen) Ende zu führen:
Du bastelst diese zusätzliche Variable "LastdayOfMonth" beispielsweise als %LDoM% mit in die GetAllDateTimeInfos.cmd

Dazu wäre wohl nur die kleine Anpassung nötig:
....
.....
:: ## In folgender Zeile die Variable %LDoM% zusätzlich:
SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms LDoM"  
...
[...]
....
:: Und der VBS-Schnipsel LIEFERT ein Wert  mehr
SET "vbsSnippet=%temp%\%random%.vbs"  
 >%vbssnippet% echo If wscript.arguments.count = 1 Then dDate=wscript.arguments.item(0) Else dDate=Date
>>%vbsSnippet% echo Wscript.Echo "x," ^& DatePart("ww",dDate,vbSunday,vbFirstFourDays) ^& "," ^&_   
>>%vbsSnippet% echo DatePart("ww",dDate) ^& "," ^& DatePart("w",dDate) ^& "," ^& DatePart("y",dDate) ^& "," ^&_   
>>%vbssnippet% echo dateAdd ("d", -1, dateAdd("m", 1, "01." ^& Month(dDate) ^& "." ^&year(ddate)))  

::## und die FOR-Anweisung HOLT ein Token mehr...
for /F "delims=, tokens=2-6" %%a in ('cscript //nologo %vbsSnippet% %INDate%') do (  
(Set "KW=%%a" ) && Rem Kalenderwoche nach verbreiteter Berechnung  
(Set "OSKW=%%b" ) && Rem Kalenderwoche nach Betriebssystemvorgaben nicht über GUI änderbar! *lacht  
(Set "DoW=%%c" ) && Rem Day of Week 1=Sonntag, 2= Montag... bei meinen REG-Settings  
(Set "DoY=%%d" ) && Rem Day of Year, Kalendertag  
(Set "LDoM=%%e") && Rem LastDayOfMonth Letzter Tag des Monats  
)
::  ##Hier kommt der %LDoM% dazu

del %vbssnippet%
....
.....

Die Test-Ausgabe dieser nur oberflächlich getesteten Variante wäre
>e:\daily\GetAllDateTimeInfos.cmd
INDate=22.06.09
INTime= 7:10:41,67
DateOrder=TT-MM-JJ
KW=25
OSKW=26
DoW=2
DoY=173
cDoW=Mo
DD=22
TT=22
MM=06
JJ=2009
YY=2009
hh=07
min=10
ss=41
ms=67
LDoM=30.06.09    -------> hier isser, der LastDayOfMonth

Grüße
Biber
Noc06
Noc06 23.06.2009 um 11:07:24 Uhr
Goto Top
Moin, moin,

Euch beiden erstmal herzlichen Dank für die weiteren Tipps - werde heute direkt mal versuchen, das entsprechend umzusetzten.

Schönen Gruß
Noc06
Noc06
Noc06 23.06.2009 um 12:42:48 Uhr
Goto Top
Hallo Biber,

ich habe den LDoM entsprechend in Dein urspr. Programm eingebaut und die Ausgabe paßt auch. Allerdings funktioniert in meinem Batch der Abgleich zwischen aktuellem Datum und LDoM nicht richtig.

Folgende Änderungen habe ich vorgenommen (Auszug der Zeilen 104-106 meines Programms, s.o.):

rem for /f %%i in ('cscript //nologo LastDayOfMonth.vbs') do set "Letzter=%%i"   
if "%INDate%"=="%LDoM%" echo Heute Monatssicherung  
if not "%INDate%"=="%LDoM%" echo Heute ist NICHT der Moantsletzte - keine Sicherung erforderlich  

Ich habe bei der GetAllDateTimeInfos sowohl das Datum 30.06.2009 (Dienstag, letzter Tag des Monats Juni) als auch den 31.07.2009 (Freitag, hier treffen gleich mehrere Bedingungen zu, nämlich KW-Sicherung und Monatsletzter) fest eingetragen und das Programm aufgerufen. Die Ausgaben stimmen alle. Wenn ich jetzt mein Programm laufen lasse, zeigt er mir zwar auch alle Werte richtig an, allerdings bekomme ich immer das ECHO, daß an dem entsprechenden Datum nicht der Monatsletzte ist. Auch eine Deaktivierung der IF NOT Zeile über ein REM bring kein anderes Ergebnis - es wird halt lediglich gar nichts mehr angezeigt (ist auch logisch, wenn die eigentliche Abfrage negativ ausfällt).

Irgendeine Idee, woran die Übergabe scheitern könnte?

Danke und Gruß
Noc06


EDIT 1:
Ich habe mal versuchsweise "%INDate%" bei den beiden Zeilen durch "%TT%.%MM%.%JJ%" ersetzt und jetzt scheint es zu funktionieren... Kann das daran liegen, das INDate das Ergebnis zwar in dd.mm.yyyy visuell darstellt, aber intern anders verarbeitet, also bspw. mit dd.mm.yy? Anders kann ich es mir gerade leider nicht erklären...

EDIT 2:
Leider bekomme ich es auch nicht hin, mir den Monat als Klarwert anzeigen zu lassen. Nach meinem Verständnis müßte ich in Deiner GetAllDateTimeInfos eine zusätzliche Variable definieren (also bspw. cMM)

[...]
SET "AllDateTimeVars=DateOrder KW OSKW DoW DoY cDoW DD TT MM JJ YY hh min ss ms LDoM cMM"  
[...]

und diese an späterer Stelle entsprechend "umwandeln", was ich über folgende Anpassung versucht habe:

[...]
IF defined MM (
set "MM=%MM:~-2,2%"  
IF %MM%==01 Set "cMM=Januar"  
IF %MM%==02 Set "cMM=Februar"  
IF %MM%==03 Set "cMM=März"  
IF %MM%==04 Set "cMM=April"  
IF %MM%==05 Set "cMM=Mai"  
IF %MM%==06 Set "cMM=Juni"  
IF %MM%==07 Set "cMM=Juli"  
IF %MM%==08 Set "cMM=August"  
IF %MM%==09 Set "cMM=September"  
IF %MM%==10 Set "cMM=Oktober"  
IF %MM%==11 Set "cMM=November"  
IF %MM%==12 Set "cMM=Dezember"  
)
[...]

Da ich beim Aufrufen des Programms jedoch keine Rückmeldung der cMM bekomme, vermute ich mal, daß ich vergesen habe, einen entsprechenden Verweis zu setzten. Welche stelle hätte ich noch anpassen müssen?

Edit 3: Problem aus 2 anderweitig gelöst...


Danke und schönen Gruß
Noc06
Biber
Biber 23.06.2009 um 17:07:57 Uhr
Goto Top
Moin Noc06,

ich hatte gerade mit den Antworten vor Deinem zweiten Edit angefangen und beziehe mich alo nur auf alles vor "edit2".

Mein Vorschlag wäre dann auch, erstmal zu visualisieren, was schiefgeht beim Vergleich.

Also z.B. die Zeile "if not "%INDate%"=="%LDoM%" echo " so weitergehen zu lassen:
if not "%INDate%"=="%LDoM%" echo Vergleich if not "%INDate%"=="%LDoM%" ergibt NICHT GLEICH.

Dann siehst Du doch, was nicht passt.

Grüße
Biber
Noc06
Noc06 23.06.2009 um 17:22:43 Uhr
Goto Top
Sorry, wollte den Thread nicht ausufern lassen.

Werde ich auch nochmal ausprobieren - zur Zeit funtkioniert es allerdings so wie es soll, wenn auch mit der etwas umständlicheren Schreibweise...

Danke Dir für Deine Mühen!

Gruß
Noc06