Ich habe ein weiteres Skript geschrieben, um das Speicherplatz-Handling an meinem Server für mich zu vereinfachen.
Das nachfolgende Skript verschiebt meine DVBViewer-Aufnahmen vom Laufwerk D nach E, F und G, und behält auf den Laufwerken mindestens 5 GB frei. Dadurch können neue Videodateien stets auf Laufwerk D hinzukommen und die bereits vorhandenen werden automatisch verteilt. Das ist für mich deswegen sinnvoll, weil ich den freien Speicherplatz immer möglichst zusammenhängend auf Laufwerk D haben möchte.
DOS ist auf 32-Bit-Arithmetik limitiert, daher verwende ich für die Berechnung des zu erwartenden freien Speicherplatzes (nach dem Verschieben der Dateien) einen Trick. Vor der Subtraktion schneide ich bei beiden Operanden die letzten 3 Ziffern weg, für die Vorgabe des freien Speicherplatzes muss man dasselbe machen. Die Berechnung ist dadurch nicht mehr ganz genau, aber das Ziel wird erreicht – ein bestimmter Speicherplatz bleibt in etwa frei (mögliche Abweichung ca 1 MB, da die Angabe im Skript in Byte ist).
Bei mehr als 2 TB freiem Speicher auf einem der Ziellaufwerke wird das Skript aber wieder Probleme machen, anfänglich sollte man die Festplatten daher von Hand befüllen. Die Vorgabe des frei zu haltenden Speicherplatzes erfolgt in Byte; man sollte bei der Umrechnung in größere Maßeinheiten die Unterschiede zwischen Megabyte (Basis 1000) und Mebibyte (Basis 1024) beachten. 5.000.000.000 Bytes sind daher 5 Gigabytes, aber nicht 5 Gibibytes – das Betriebssystem arbeitet mit der Maßeinheit Gibibyte und wird daher ca. 4,6 GB verbleibenden, freien Speicherplatz anzeigen.
Das Skript lasse ich periodisch jeden Tag aufrufen, ich muss dadurch keine Dateien mehr von Hand verschieben, die Laufwerke werden automatisch gleichmäßig aufgefüllt (bis auf D:). Wenn man das für Kodi etc. benutzt, sollte man die Datenbank aber öfter mal aufräumen lassen, weil sich die Dateien halt verschieben können. Das kann Kodi über Addons aber automatisch erledigen.
Ab Windows Server 2012 kann man mittels Storage Spaces auch mehrere Laufwerke zu einem Speicherpool zusammenfassen. Ich nutze das Feature deswegen nicht, weil ich 1. schlechte Erfahrungen mit der Storage Pool-Technik von Windows Home Server v1 gemacht habe (technisch vermutlich nicht mit Storage Spaces vergleichbar), und weil 2. bei Storage Spaces die Festplatten nicht einzeln auslesbar bleiben, dadurch ist man noch mehr auf ein Backup angewiesen. Mittlerweile finde ich UnionFS unter OpenMediaVault die bessere Lösung.
@echo off
setlocal EnableDelayedExpansion
SET "Quelle=D:\_Filme"
SET "Ziel1=E:\_Filme"
SET "Ziel2=F:\_Filme"
SET "Ziel3=G:\_Filme"
REM wieviel Speicher mindestens frei lassen? 5 GB
SET "minFreeSpace=5000000000"
Set "RoboParms=/E /ZB /COPY:DATSOU /SEC /FP /R:0 /W:0 /MOV"
Set "RoboParms=%Roboparms% /NP"
FOR /R %Quelle% %%G in (*.ts *.mkv *.avi) DO (
REM echo %%G mit Pfad
set filedrive=%%~dG
set filepath=%%~pG
set filefullpath=!filedrive!!filepath!
REM abschließenden \ entfernen
set filefullpath=!filefullpath:~,-1!
set filename=%%~nG
set fileextension=%%~xG
set filefullname=%%~nxG
REM echo %%~nxG ohne Pfad
set fileCopyMask=!filename!*.*
echo !fileCopyMask!
REM Dateigröße der zu kopierenden Datei ermitteln, mit Nullen vorne auffüllen
REM Originalzahl fürs Rechnen aber behalten
set filesize=%%~zG
set filesizeTemp=%%~zG
set filesize=00000000000000000000!filesize!
set filesize=!filesize:~-20!
set minFreeSpace=00000000000000000000!minFreeSpace!
set minFreeSpace=!minFreeSpace:~-20!
rem echo !filesize! !minFreeSpace!
REM Freien Speicherplatz auf Ziellaufwerken ermitteln
REM Zahlenvergleiche, zumal so große, funktionieren in DOS nur korrekt wenn die Zahlen zuvor mit führenden Nullen
REM auf die gleiche Länge gebracht werden
REM Von den angegebenen Zielpfaden werden die ersten beiden Zeichen für die Laufwerksbuchstaben und : abgeschnitten
REM WMI-Infos: "https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/aa394515(v=vs.85).aspx
for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel1:~0,2%"') do set drivefreeSpace1=%%S
REM Originalzahl fürs Rechnen behalten, ansonsten aufnullen
set drivefreeSpace1Temp=!drivefreeSpace1!
set drivefreeSpace1=00000000000000000000!drivefreeSpace1!
set drivefreeSpace1=!drivefreeSpace1:~-20!
for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel2:~0,2%"') do set drivefreeSpace2=%%S
REM Originalzahl fürs Rechnen behalten, ansonsten aufnullen
set drivefreeSpace2Temp=!drivefreeSpace2!
set drivefreeSpace2=00000000000000000000!drivefreeSpace2!
set drivefreeSpace2=!drivefreeSpace2:~-20!
for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^%Ziel3:~0,2%"') do set drivefreeSpace3=%%S
REM Originalzahl fürs Rechnen behalten, ansonsten aufnullen
set drivefreeSpace3Temp=!drivefreeSpace3!
set drivefreeSpace3=00000000000000000000!drivefreeSpace3!
set drivefreeSpace3=!drivefreeSpace3:~-20!
rem echo !drivefreeSpace1! !drivefreeSpace2! !drivefreeSpace3!
REM Bestimmung des Ziellaufwerks mit dem größten freien Speicherplatz
set ZielLaufwerk=%Ziel1%
set ZielGroesse=!drivefreeSpace1!
set ZielGroesseTemp=!drivefreeSpace1Temp!
if !drivefreeSpace2! gtr !ZielGroesse! (
set ZielLaufwerk=%Ziel2%
set ZielGroesse=!drivefreeSpace2!
set ZielGroesseTemp=!drivefreeSpace2Temp!
)
if !drivefreeSpace3! gtr !ZielGroesse! (
set ZielLaufwerk=%Ziel3%
set ZielGroesse=!drivefreeSpace3!
set ZielGroesseTemp=!drivefreeSpace3Temp!
)
REM passt die Datei noch drauf? Größenvergleiche gehen mit führenden Nullen besser
if !ZielGroesse! gtr !filesize! (
REM zu erwartenden, freien Speicherplatz nach der Kopieraktion berechnen
REM Subtraktion macht bei führenden Nullen Probleme, deswegen hier die Original-Operanden
REM ohne führenden Nullen nehmen
REM DOS ist aber auf 32-Bit-Arithmetik beschränkt, alles über 2 Milliarden Bytes macht
REM Probleme bei der Berechnung, deswegen nehmen wir die letzten 3 Ziffern weg
set ZielGroesseTemp=!ZielGroesseTemp:~,-3!
set filesizeTemp=!filesizeTemp:~,-3!
set minFreeSpaceTemp=!minFreeSpace!
set minFreeSpaceTemp=!minFreeSpaceTemp:~,-3!
REM Berechnung
rem echo !ZielGroesseTemp!-!filesizeTemp!
set /a verbleibenderFreierSpeicher=!ZielGroesseTemp!-!filesizeTemp!
REM verbleibenden, freien Speicher mit führenden Nullen auffüllen
set verbleibenderFreierSpeicher=00000000000000000000!verbleibenderFreierSpeicher!
set verbleibenderFreierSpeicher=!verbleibenderFreierSpeicher:~-20!
rem echo !ZielGroesse!_!filesize!_!verbleibenderFreierSpeicher!
REM freie Speicherplatzvorgabe auch wieder auf 20 Stellen auffüllen, für den Vergleich
set minFreeSpaceTemp=00000000000000000000!minFreeSpaceTemp!
set minFreeSpaceTemp=!minFreeSpaceTemp:~-20!
rem echo !ZielGroesse!_!filesize!_!verbleibenderFreierSpeicher!_!minFreeSpaceTemp!
if !verbleibenderFreierSpeicher! gtr !minFreeSpaceTemp! (
REM Datei einzeln kopieren
rem echo Robocopy.exe "!filefullpath!" "!Ziellaufwerk!" !RoboParms! /IF "!fileCopyMask!"
Robocopy.exe "!filefullpath!" "!Ziellaufwerk!" !RoboParms! /IF "!fileCopyMask!"
)
)
)