Reports - Überwachtes Kopieren
Hallo Zusammen,
ich habe momentan die Aufgabe, Dateiübertragungen zu automatisieren. Hierbei sind die Daten wie folgt aufgebaut:
\\QuellFreigabe\Name\Fortlaufende Nummer\Sammelordner
Diese Sammelordner sind zwischen 100 - 700 MB groß und bestehen aus ca. 2000-3000 Elementen
Falls sich innehalb dieses Sammelordners eine Signaldatei befindet (z.B. Signal.txt) soll diese nach
\\ZielFreigabe\Name\Fortlaufende Nummer\Sammelordner
kopiert werden. Hierbei muss allerdings sichgestellt werden, dass keine Dateiveränderung o.Ä. stattgefunden haben. Ich habe dafür ein Skript geschrieben, dass die Dateien einzeln kopiert und die Hashwerte vergleicht, allerdings bräuchte ich noch etwaige Verbesserungsvorschläge von euch.
Falls ihr Ergänzungen/Verbesserungen habt, immer her damit.
Grüße,
Tiberius
ich habe momentan die Aufgabe, Dateiübertragungen zu automatisieren. Hierbei sind die Daten wie folgt aufgebaut:
\\QuellFreigabe\Name\Fortlaufende Nummer\Sammelordner
Diese Sammelordner sind zwischen 100 - 700 MB groß und bestehen aus ca. 2000-3000 Elementen
Falls sich innehalb dieses Sammelordners eine Signaldatei befindet (z.B. Signal.txt) soll diese nach
\\ZielFreigabe\Name\Fortlaufende Nummer\Sammelordner
kopiert werden. Hierbei muss allerdings sichgestellt werden, dass keine Dateiveränderung o.Ä. stattgefunden haben. Ich habe dafür ein Skript geschrieben, dass die Dateien einzeln kopiert und die Hashwerte vergleicht, allerdings bräuchte ich noch etwaige Verbesserungsvorschläge von euch.
Clear-Host
$sourcepath = "C:\quelle"
$patharray = gci $sourcepath -Recurse | ?{$_.Name -eq "Signaldatei.txt"} | Select-Object -ExpandProperty FullName |Split-Path
function übergabemithash{
foreach ($a in $patharray){
$copy = gci -Recurse $a
foreach($c in $copy){
$filepath = $c | Select-Object -ExpandProperty FullName |Split-Path
$sourcelength = Get-FileHash "$filepath\$c" | select -ExpandProperty Hash
$destfilepath = $filepath.Replace("quelle","test")
Copy-Item $filepath\$c -Recurse -Destination "$destfilepath"
$destlength = Get-FileHash "$destpath\$newpath\$c" | select -ExpandProperty Hash
if($sourcelength -ne $destlength){
Remove-Item $destpath\$newpath\$c
Copy-Item $a\$c -Destination $destpath\$newpath\
write-host test}
}
}
}
übergabemithash
Falls ihr Ergänzungen/Verbesserungen habt, immer her damit.
Grüße,
Tiberius
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 280611
Url: https://administrator.de/contentid/280611
Ausgedruckt am: 22.11.2024 um 00:11 Uhr
2 Kommentare
Neuester Kommentar
Hallo Tiberius,
also wenn du das Plain mit Powershell ohne Zusatztools wie Robocopy machen willst würde ich das persönlich so machen:
(Kommentare zu den einzelnen Vorgehensweisen siehe Code)
Das mal so als Anregung, für eine von vielen anderen möglichen Varianten. Der Vorteil zu deiner Variante ist das die Berechnung der Hashes die Übertragungen nicht immer wieder unterbricht, denn das Berechnen der Hashes kann übers Netzwerk bei großen Dateien einige Zeit dauern. Deswegen habe ich die Berechnungen von den Übertragungen getrennt, und die Infos gleichzeitig in einem Objekt gespeichert das sich zum Schluss perfekt als Report benutzen lässt.
Grüße Uwe
p.s. gewöhne dir an deinen Code "einzurücken", das ist einerseits übersichtlicher und vermeidet Fehler und Unklarheiten bei nachträglichen Änderungen.
also wenn du das Plain mit Powershell ohne Zusatztools wie Robocopy machen willst würde ich das persönlich so machen:
(Kommentare zu den einzelnen Vorgehensweisen siehe Code)
# Quell-Root
$source_root = 'C:\temp\quelle'
# Ziel-Root
$target_root = 'C:\temp\ziel'
# Name der Signal-Datei
$signal_file = 'signal.txt'
# Alle für die in Frage kommenden Dateien mit deren Quell-Hashes listen
$files = gci $source_root -Filter $signal_file -Recurse | %{gci $_.DirectoryName -Recurse -File | %{get-filehash $_.Fullname -Algo MD5}} | select Path,Hash
# dem Objekt zwei weitere Eigenschaften hinzufügen (Ziel-Pfad / Ziel-Hash)
$files | ?{$_.Name -ne $signal_file} |%{
Add-Member -Input $_ -MemberType NoteProperty -Name "Destination" -Value $_.Path.Replace($source_root,$target_root)
Add-Member -Input $_ -MemberType NoteProperty -Name "Destination_Hash" -Value ''
}
$files | %{
$dest = [IO.Path]::GetDirectoryName($_.Destination)
# Zielverzeichnis erstellen sofern es nicht existiert
if (!(Test-Path $dest)){ md $dest}
# Datei kopieren
copy-item $_.Path $_.Destination -Force
}
# Nach den Dateiübertragungen die Hashes der Zieldateien berechnen
$files | %{$_.Destination_Hash = (get-filehash $_.Destination -Algo MD5).Hash}
# Auf Fehler bei den Übertragungen überprüfen und fehlgeschlagene Übertragungen solange wiederholen bis alle Dateien fehlerfrei übertragen wurden
$files | ?{$_.Hash -ne $_.Destination_Hash} | %{
$new_hash = ""
while($_.Hash -ne $new_hash){
write-host "Hash der Zieldatei: $($_.Destination) stimmt nicht überein, wiederhole Übertragung ..." -ForegroundColor Yellow
copy-item $_.Path $_.Destination -Force
$new_hash = (get-filehash $_.Destination).Hash
}
$_.Destination_Hash = $new_hash
}
# Signaldateien zum Abschluss löschen (wusste nicht wie das bei euch geregelt ist)
gci $source_root -Filter $signal_file -Recurse | remove-item -Force
# Übertragene Dateien anzeigen
$files | ogv
Grüße Uwe
p.s. gewöhne dir an deinen Code "einzurücken", das ist einerseits übersichtlicher und vermeidet Fehler und Unklarheiten bei nachträglichen Änderungen.