immofreund
Goto Top

Powershell Prüfung ob Datei kopiert wurde

Hallo,

ich habe in Powershell ein Script erstellt was auch funktioniert.
Jedoch habe ich noch ein Problem dabei.

Das Script kopiert mir alle Dateien aus der Quelle ins Ziel. (Falls im Ziel schon vorhanden, wird die Datei trotzdem kopiert mit Versionsnummer 1 usw....
Weiterhin kopiert das Script mir alle Dateien aus der Quelle ins Temp. (Falls im Temp schon vorhanden, wird die Datei trotzdem kopiert mit Versionsnummer 1 usw....

Alles was älter als 30 Tage ist, wird im Temp gelöscht.
Alles aus der Quelle wird gelöscht.

Am nächsten Tag sind in der Quelle wieder 2 Dateien und das Script läuft deshalb 1x am Tag.

Kann Mann irgendwie prüfen, ob auch wirklich kopiert wurde?
Der Hintergrund ist, wenn das kopieren nicht funktioniert, wird ja trotzdem gelöscht und die Dateien sind weg.
Ich habe den Temp kopieren als """Sicherheit""" gedacht, aber es ist ja keine.

$source = "E:\Quelle1"    
$target = "E:\Ziel"   
$temp = "E:\Temp"   

#von Quelle ins Temp kopieren
foreach($file in Get-ChildItem $source -file -filter *.txt -recurse){
     $dst = "$temp\$($file.Name)"    
     $cnt = 1
     while(Test-Path $dst){
         $dst = "$temp\$($file.Basename)_$cnt$($file.Extension)"    
         $cnt++
     }
     $file | Copy-Item -Destination $dst -force -verbose
     }

#von Quelle ins Ziel kopieren
     foreach($file in Get-ChildItem $source -file -filter *.txt -recurse){
     $dst = "$target\$($file.Name)"    
     $cnt = 1
     while(Test-Path $dst){
         $dst = "$target\$($file.Basename)_$cnt$($file.Extension)"    
         $cnt++
     }
     $file | Copy-Item -Destination $dst -force -verbose
     }

#Temp löschen wenn älter 30 Tage
Get-childitem $temp\*.txt -recurse | where-object { $_.LastWriteTime -lt (get-date).adddays(-30)} | foreach-object { rm -recurse $_.fullname }

#Quelle löschen
Remove-Item "$source\*.txt"  


Wenn jemand helfen kann, wäre ich sehr dankbar.

Grüße

Content-Key: 81785610218

Url: https://administrator.de/contentid/81785610218

Printed on: May 1, 2024 at 23:05 o'clock

Member: NordicMike
NordicMike Apr 19, 2024 at 06:04:29 (UTC)
Goto Top
Mach beim löschen eine Abfrage ob nur eine Datei vorhanden ist oder mehrere. Bei der Abfrage ignorierst du z.B. die Versionsnummern, sodass er immer alle Dateien zählt, die vor dem "_" gleich heissen. Die einzige bzw letzte Datei wird dann nie gelöscht.
Member: Kraemer
Kraemer Apr 19, 2024 at 06:33:59 (UTC)
Goto Top
Moin,

Test-Path kennst du ja schon.

Wenn du dann auch noch eine Checksumme berechnest, solltest du auf der sicheren Seite sein.

Gruß
Member: Immofreund
Immofreund Apr 19, 2024 updated at 06:39:53 (UTC)
Goto Top
Hallo NordicMike,

danke für Deine Antwort.

Der Ablauf ist das Tagsüber immer so 2 oder 3 Dateien in die Quelle reinkommen. Da der Dateiname im Ziel schon vorhanden sein kann (selten), wird dann die Versionsnummer 1 ran gehangen. Gibt es die Datei noch nicht, wird normal kopiert.

Nach dem kopieren muss die Quelle gelöscht (leer) sein.

Ich brauche eine Lösung die mir das kopieren kontrolliert. Wenn nichts ins Ziel kopiert wurde, darf auch nicht gelöscht werden.

Ich weiß leider nicht, wie ich das machen könnte ????

Grüße
Member: NordicMike
NordicMike Apr 19, 2024 at 06:46:54 (UTC)
Goto Top
OK, das war nur mein Vorschlag alles älter als 30 Tage zu löschen.

Um die Quelle zu löschen hängt du hinter Zeile 24 eine Abfrage ob sich die Datei im Zielverzeichnis befindet. Wenn ja, dann quelle löschen.

Du kannst auch den Status der Kopie abfragen:
https://stackoverflow.com/questions/32727252/how-to-handle-copy-item-exc ...
Member: Jugg3r
Jugg3r Apr 19, 2024 at 06:52:20 (UTC)
Goto Top
Evtl als kleine "Über Den Tellerrand hinaus" - Lösung:
Das kopieren / verschieben könnte man mit Robocopy durchführen.
Das prüft, ob die Dateien kopiert wurden und löscht erst dann
Member: Kraemer
Kraemer Apr 19, 2024 updated at 07:39:53 (UTC)
Goto Top
Jetzt einfach mal aus dem Kopf dahingeschrieben (ohne Temp)

$TempErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = 'SilentlyContinue'  
try {
    $SourceFiles = Get-ChildItem -Path "C:\temp" -File -Filter "*.txt" -Recurse -Force  
    $DestPath = "C:\temp"  
    [Void](Get-ChildItem $DestPath -Force)
    foreach ($File in $SourceFiles) {
        $Count = 0
        $DestFile = Join-Path -Path $DestPath -ChildPath "$($File.BaseName)_$($Count)$($File.Extension)"  
        while (Test-Path -Path $DestFile) {
            $Count++
            $DestFile = Join-Path -Path $DestPath -ChildPath "$($File.BaseName)_$($Count)$($File.Extension)"  
        }
        Copy-Item -LiteralPath $File.Fullname -Destination $DestFile
        [Void](Get-ChildItem $DestPath -Force)
        if ((Get-FileHash -LiteralPath $File).Hash -ne (Get-FileHash -LiteralPath $DestFile).Hash) {
            Throw "Checksummen stimmen nicht überein"  
        }
        Remove-Item $File
    }
}
catch {
    Write-Host $PsItem
}
finally {
    $ErrorActionPreference = $TempErrorActionPreference
}
Member: Immofreund
Immofreund Apr 22, 2024 at 05:12:03 (UTC)
Goto Top
Guten Morgen Kraemer,

danke Dein Script läuft, jedoch wird bei Dir immer versioniert. Also es wird immer _0 rangehangen im Ziel Ordner.
Das soll aber nur bei schon vorhandenen Dateien im Zielordner passieren.

Also wenn Die Datei 13041974.txt in der Quelle nach Ziel kopiert werden soll, im Ziel aber schon vorhanden ist.
Dann soll trotzdem kopiert werden, aber die Datei dann 13041974_0.txt sein.
Ist die Datei nicht im Ziel, dann soll 13041974.txt bleiben.

Die Quelle wird täglich mit 3 bis 5 Dateien gefüllt. Manchmal gibt es hier Dateien, die es schon im Ziel gibt. Da brauche ich beide Dateien.

Jedoch bringt er bei deinem Script am Ende immer "Checksummen stimmen nicht überein"
Deshalb wird auch nichts gelöscht.
Die Dateien sind jedoch identisch ????

Oder liegt das an der Versionierung?????

Danke schon mal im voraus.

Grüße
quelle
auswertung
ziel
Member: Kraemer
Kraemer Apr 22, 2024 at 06:55:48 (UTC)
Goto Top
Jedoch bringt er bei deinem Script am Ende immer "Checksummen stimmen nicht überein"

Wie gesagt aus dem Kopf gescrhieben. In der Zeile fehlen zwei mal .FullName

if ((Get-FileHash -LiteralPath $File).Hash -ne (Get-FileHash -LiteralPath $DestFile).Hash) {

if ((Get-FileHash -LiteralPath $File.FullName).Hash -ne (Get-FileHash -LiteralPath $DestFile.FullName).Hash) {

jedoch wird bei Dir immer versioniert.
Kleinigkeit. Solltest du ohne weiteres anpassen können
Member: Immofreund
Immofreund Apr 24, 2024 at 06:47:37 (UTC)
Goto Top
Danke, bin noch am testen. Das löschen funktioniert noch nicht. Liegt evt. an den Checksummen. Da muss ich mich noch einlesen.
Programmieren kann ich nicht wirklich gut, leider!!!!

Grüße
Member: Jugg3r
Jugg3r Apr 24, 2024 at 07:14:13 (UTC)
Goto Top
robocopy ;)
Member: Immofreund
Immofreund Apr 24, 2024 at 13:18:29 (UTC)
Goto Top
Hallo Kraemer,

ich habe jetzt das gebaut.
Versionierung klappt jetzt. Es wird nur dann versioniert, wenn im Ziel schon die gleiche Datei da ist.

Aber die Kontrolle über den Hashwert stimmt nie überein, wehalb natürlich in der Quelle auch nichts gelöscht wird.
Warum????

Besten Dank!

$source = "E:\Quelle1"    
$target = "E:\Ziel1"   
$temp = "E:\Temp"   
#von Quelle ins Temp kopieren

foreach($file in Get-ChildItem $source -file -filter *.txt -recurse){
     $dst = "$target\$($file.Name)"    
     $cnt = 1
     while(Test-Path $dst){
         $dst = "$target\$($file.Basename)_$cnt$($file.Extension)"    
         $cnt++
     }
     $file | Copy-Item -Destination $dst -force -verbose
}
if ((Get-FileHash -LiteralPath $source.FullName).Hash -ne (Get-FileHash -LiteralPath $target.FullName).Hash) {
     Throw "Checksummen stimmen nicht überein"   
         Remove-Item $source\*.txt -force }
Member: schrick
schrick Apr 24, 2024 updated at 13:52:58 (UTC)
Goto Top
Wenn du nur löschst wenn der Hash nicht übereinstimmt, kein Wunder 😀.
Außerdem steht der Code außerhalb der For-Each Schleife, da hast du ganz schön verunstaltet ....

Schau dir den Code von Krämer nochmal ganz genau an ...

$source = "E:\Quelle1"      
$target = "E:\Ziel1"  

$ErrorActionPreference = "Stop"  
#von Quelle ins Temp kopieren
foreach($file in Get-ChildItem $source -file -filter *.txt -recurse){
   Try{
     $dst = "$target\$($file.Name)"      
     $cnt = 1
     while(Test-Path $dst){
         $dst = "$target\$($file.Basename)_$cnt$($file.Extension)"      
         $cnt++
     }
     $file | Copy-Item -Destination $dst -force -verbose
      if ((Get-FileHash -LiteralPath $file.Fullname).Hash -ne (Get-FileHash -LiteralPath $dst).Hash) {
           Throw "Checksummen stimmen nicht überein '$($file.Fullname)' <=> '$dst'"     
       }else{
           Remove-Item $file.Fullname -force
       }
   }catch{
       write-host $_.Exception.Message -F Red
   }
}

Gruß schrick