Robocopy ansich kann keine geöffneten Dateien kopieren. Seit Windows Server 2003 schaffen die Schattenkopien (VSS) abhilfe. Mit ein paar zusätzlichen Befehlen bzw. einem Skript kann man Robocopy und VSS zusammenbringen.
Folgendes Skript erstellt eine Schattenkopie, sichert diese mittels Robocopy und entfernt sie wieder. Robocopy arbeitet dabei mit Versionen. Eine Protokollierung und etwas Fehlerbehandlung ist ebenfalls enthalten. Ein Monitoring kann beispielsweise bei vorhandensein einer “error.txt” Alarm schlagen.
@echo off cls rem Evtl. vorhandenes altes Fehlerprotokoll entfernen if exist error.txt del /q error.txt rem Protokoll erstellen echo %date% - %time% - Start > current.log rem Konfiguration set DriveLetter=D: set ShadowCopyVolume=D:\CDP\ShadowCopyVolume set Source=%ShadowCopyVolume%\Share set Destination=D:\CDP\Backup\Share set NumberOfVersionsToKeep=10 rem Version.txt pruefen, falls diese nicht existiert, dann anlegen if not exist Version.txt echo %NumberOfVersionsToKeep% > Version.txt rem Version auslesen und ggf. festlegen set /p Version=< Version.txt set Version=%Version: =% set /A Version=Version %% NumberOfVersionsToKeep + 1 echo %Version% > Version.txt rem Ziel-Ordner pruefen und ggf. anlegen if not exist "%Destination%\%Version%" mkdir "%Destination%\%Version%" rem Schattenkopie erstellen echo %date% - %time% - Schattenkopie erstellen >> current.log vssadmin create shadow /for=%DriveLetter% > ShadowCopy.txt if %errorlevel% neq 0 echo error > error.txt & exit rem Schattenkopie-Volumename auslesen type ShadowCopy.txt | find "Schattenkopie-Volumename:" > ShadowCopyName.txt set /p ShadowCopyName=< ShadowCopyName.txt set ShadowCopyName=%ShadowCopyName:~30% rem Schattenkopiekennung auslesen type ShadowCopy.txt | find "Schattenkopiekennung:" > ShadowCopyID.txt set /p ShadowCopyID=< ShadowCopyID.txt set ShadowCopyID=%ShadowCopyID:~26% rem Schattenkopie bereitstellen mklink /d "%ShadowCopyVolume%\" "%ShadowCopyName%\" > NUL rem Robocopy ausfuehren echo %date% - %time% - Robocopy ausfuehren >> current.log robocopy "%Source%" "%Destination%\%Version%" /mir /r:0 /w:0 /xj /np /log:Logs\robocopy-%Version%.log if %errorlevel% gtr 1 echo Fehler bei der Ausfuehrung von Robocopy >> error.txt type Logs\robocopy-%Version%.log >> current.log rem Schattenkopie-Bereitstellung aufheben echo %date% - %time% - Schattenkopie Bereitstellung aufheben und die Schattenkopie entfernen >> current.log rmdir "%ShadowCopyVolume%" rem Schattenkopie loeschen vssadmin delete shadows /shadow=%ShadowCopyID% /quiet > NUL if %errorlevel% neq 0 echo Fehler beim Loeschen der Schattenkopie >> error.txt & exit rem Aufraeumen del ShadowCopy.txt /q del ShadowCopyName.txt /q del ShadowCopyID.txt /q echo %date% - %time% - Ende >> current.log
Den Schattenkopie-Teil des Skripts habe ich irgendwann 2016/2017 mal im Rahmen eines Feldversuchs geschrieben. Der Robocopy-Versionen-Teil stammt aus diesem Beitrag:
Windows: Robocopy-Backup mit Versionen
In dieser Fassung läuft das Skript bei einem Kunden auf einem Windows Server 2016 stündlich Montags bis Freitags von 08:00 bis 17:00 Uhr und stellt sozusagen ein Marke-Eigenbau-CDP für eine Freigabe dar.
Diese Maßnahme wurde notwendig, da immer wieder aus einer Branchen-Anwendung heraus aus versehen Dateien und Ordner gelöscht wurden.
Man kann zwar auch die regulären Schattenkopien häufiger laufen lassen, allerdings wird dann der Schattenkopie-Speicher entsprechend belastet. Da es allerdings nur darum geht einen Ordner öfter zu sichern erschien diese Lösung attraktiver. Mit dem Skript hat man außerdem die Option als Ziel ein anderes Laufwerk, ein NAS oder Server anzugeben.
Update 06.12.2021
Anbei eine Variante mit ShadowRun, mit dessen Hilfe das eigentliche Robocopy-Skript einfacher und (imho) die Ausführung zuverlässiger wird:
@echo off rem Evtl. vorhandenes altes Fehlerprotokoll entfernen if exist error.txt del /q error.txt rem Protokoll erstellen echo %date% - %time% - Start > current.log rem Konfiguration set Source=V:\Share set Destination=D:\CDP\Backup\Share set NumberOfVersionsToKeep=10 rem Version.txt pruefen, falls diese nicht existiert, dann anlegen if not exist Version.txt echo %NumberOfVersionsToKeep% > Version.txt rem Version auslesen und ggf. festlegen set /p Version=< Version.txt set Version=%Version: =% set /A Version=Version %% NumberOfVersionsToKeep + 1 echo %Version% > Version.txt rem Ziel-Ordner pruefen und ggf. anlegen if not exist "%Destination%\%Version%" mkdir "%Destination%\%Version%" rem Robocopy ausfuehren echo %date% - %time% - Robocopy ausfuehren >> current.log robocopy "%Source%" "%Destination%\%Version%" /mir /r:0 /w:0 /xj /np /log:Logs\robocopy-%Version%.log if %errorlevel% gtr 3 echo Fehler bei der Ausfuehrung von Robocopy - %errorlevel% >> error.txt type Logs\robocopy-%Version%.log >> current.log rem Protkoll abschliessen echo %date% - %time% - Ende >> current.log
Dieses Skript wird dann mit
shadowrun.exe -env -mount -drive=V: -exec=CDP.cmd D:
aufgerufen. ShadowRun kümmert sich komplett um die Schattenkopie, das Robocopy-Skript muss nur noch vom bereitgestellten Laufwerk V: die Daten kopieren.
Verheiratet, Vater von zwei Kindern, eines an der Hand, eines im Herzen. Schon immer Technik-Freund, seit 2001 in der IT tätig und seit über 10 Jahren begeisterter Blogger. Mit meiner Firma IT-Service Weber kümmern wir uns um alle IT-Belange von gewerblichen Kunden und unterstützen zusätzlich sowohl Partner als auch Kollegen.
Hallo Andy,
genau das, was ich schon lange gesucht habe.
Kannst du das Skript noch mit der “Automatik” von Tom Stein (https://www.andysblog.de/windows-robocopy-backup-mit-versionen#comments) aktualisieren oder eine 2’te Version (am besten auch für “ROBOCOPY-BACKUP MIT VERSIONEN”) davon bereitstellen?
Wäre echt super!
Danke
Jens