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-ID: 81785610218

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

Ausgedruckt am: 22.11.2024 um 05:11 Uhr

NordicMike
NordicMike 19.04.2024 um 08:04:29 Uhr
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.
Kraemer
Kraemer 19.04.2024 um 08:33:59 Uhr
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ß
Immofreund
Immofreund 19.04.2024 aktualisiert um 08:39:53 Uhr
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
NordicMike
NordicMike 19.04.2024 um 08:46:54 Uhr
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 ...
Jugg3r
Jugg3r 19.04.2024 um 08:52:20 Uhr
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
Kraemer
Kraemer 19.04.2024 aktualisiert um 09:39:53 Uhr
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
}
Immofreund
Immofreund 22.04.2024 um 07:12:03 Uhr
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
Kraemer
Kraemer 22.04.2024 um 08:55:48 Uhr
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
Immofreund
Immofreund 24.04.2024 um 08:47:37 Uhr
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
Jugg3r
Jugg3r 24.04.2024 um 09:14:13 Uhr
Goto Top
robocopy ;)
Immofreund
Immofreund 24.04.2024 um 15:18:29 Uhr
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 }
12764050420
12764050420 24.04.2024 aktualisiert um 15:52:58 Uhr
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