giffas
Goto Top

Powershell - Dateien aus verschiedenen Arrays - Attribute vergleichen

Guten Morgen zusammen,

ich habe erst vor kurzem angefangen mit PowerShell zu skripten und komme zurzeit nicht weiter:

Ich möchte aus aus einem Quell-Ordner, PDF Dateien zum Ziel-Ordner kopieren - vorher aber prüfen ob die LastWriteTime von der Quell-Datei ungleich der LastWriteTime der ZielDatei ist..

Bis jetzt habe ich folgendes:

Zeile 23 funktioniert nicht, da liegt mein Fehler. Ich weiß nicht wie ich die zwei Dateien aus 2 Arrays vergleichen kann um sie dann bei ungleicher LastWriteTime in das include-Array zu schreiben.

Oder wie würdet Ihr das ganze machen?
Habe ich sonst noch irgendetwas im Skript was zwar funktioniert aber nicht schön ist?

$SourcePath = "\\Ordner\"  
$DestinationPath ="\\Ordner2\"  
$LogFileError="\\Ordner3\"  

$ErrorActionPreference="stop"  
$include=@()

$DestinationArray=@()
$SourceArray=get-ChildItem $SourcePath
$DestinationArray=get-ChildItem $DestinationPath

try{
#Prüfung ob Quell und Zielpfad erreichbar sind.
if((Test-Path $DestinationPath)-eq $False){Write-Error "$DestinationPath konnte nicht erreicht werden" -Category "OpenError"}  
if((Test-Path $SourcePath)-eq $False){Write-Error "$SourcePath konnte nicht erreicht werden" -Category "OpenError"}  



#Prüfen ob Datei im Zielverzeichnis noch nicht vorhanden ist, wenn ja -> in include Liste.
foreach($sourceFile in ($SourceArray)){if((Test-Path $DestinationPath\$sourceFile) -eq $False){$include+=$sourceFile}}

#prüfen ob source änderungsdatum ungleich destination änderungsdatum - dann in die include liste
foreach($sourceFile in ($sourceArray)){$DestinationArray -match $sourceFile | Where-Object($_.LastWriteTime -lt $sourceFile.LastWriteTime)}


#Alle Dateien aus dem include-Array werden ins Ziellaufwerk kopiert.
Foreach($file in (get-ChildItem $SourcePath)){
Copy-Item -Path $file.fullname -Destination $DestinationPath -confirm -force -include $include
}
}catch{
"$(Get-Date -f 'dd.MM.yyyy HH:mm:ss') --- $error" | Add-Content $LogFileError  
}


Vielen Dank schon Mal für die Hilfe!

Gruß Giffas

Content-Key: 321806

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

Printed on: April 25, 2024 at 01:04 o'clock

Mitglied: 131381
Solution 131381 Nov 23, 2016 updated at 10:18:36 (UTC)
Goto Top
Das lässt sich alles auf eine Zeile reduzieren face-smile
Oder wie würdet Ihr das ganze machen?
Prädestinierte Aufgabe für Robocopy face-smile

Oder so:
$folder1 = '\\server\ordner1'  
$folder2 = '\\server\ordner2'  
compare (gci $folder1 -File) (gci $folder2 -File) -Property Name -IncludeEqual -PassThru | ?{$_.LastWriteTime -gt (get-item "$folder2\$($_.Name)" -EA SilentlyContinue).LastWriteTime} | copy-item -Destination $folder2 -Force -Verbose  
Zeile 23 funktioniert nicht, da liegt mein Fehler.
Weil du keine Properties angibst sondern ein ganzes FileSystem-Object mit einem "Regex" Operator vergleichst, da jeht so nie und nimmer face-wink. Ein Filesystemobject hat Eigenschaften wie Namen, Größe, etc.pp. Davon suchst du dir das passende raus LastWriteTime oder Name.

Gruß
Member: Giffas
Giffas Nov 23, 2016 at 12:21:57 (UTC)
Goto Top
Danke für die schnelle Antwort!

Ich verstehe die erste "Pipe" nicht so ganz.. Was bedeutet "?{}", wie kann ich mir das vorstellen?

Ich habe deinen Code mal für mich angepasst und es scheint zu funktionieren, habe es auch soweit verstanden. Ich selber wäre darauf nicht gekommen, vielen Dank für die Hilfe..
Warum würdest du dafür Robocopy benutzen? Welchen Vorteil hat man damit?
Mitglied: 131381
131381 Nov 23, 2016 updated at 12:32:11 (UTC)
Goto Top
Zitat von @Giffas:
Ich verstehe die erste "Pipe" nicht so ganz.. Was bedeutet "?{}", wie kann ich mir das vorstellen?
Das compare macht erst mal einen Vergleich der zwei Verzeichnisse, anhand des Dateinamens - inkludiert werden Unterschiedliche Dateinamen und gleiche Dateinamen, dann wird das Ergebnis dieses Vergleichs (Die Dateiobjekte des ersten Ordners) and das CMDLet where-object (Abkürzung ?{}) übergeben, in welchem dann das Datum der Datei des ersten Ordners mit der Datei im zweiten Ordner verglichen wird. Ist es größer wird die Datei in der Pipeline weiter an das CMDLet Copy-Item geleitet.
Ich habe deinen Code mal für mich angepasst und es scheint zu funktionieren, habe es auch soweit verstanden. Ich selber wäre darauf nicht gekommen, vielen Dank für die Hilfe..
Warum würdest du dafür Robocopy benutzen? Welchen Vorteil hat man damit?
Diverse... hat sich bewährt und du musst nicht das Rad neu erfinden.
Schau dir die möglichen Optionen an dann weißt du warum.
Member: Giffas
Giffas Nov 23, 2016 at 12:44:21 (UTC)
Goto Top
Ich verstehe, danke.

compare (gci $folder1 -File) (gci $folder2 -File) -Property Name -IncludeEqual -PassThru | ?{$_.LastWriteTime -gt (get-item "$folder2\$($_.Name)" -EA SilentlyContinue).LastWriteTime} | copy-item -Destination $folder2 -Force -Verbose  

Und dadurch, dass du nach der ersten "Pipe" die ErrorAction auf "nicht abbrechen" gesetzt hast, wird eine Datei auch kopiert wenn sie im Zielverzeichnis nicht vorhanden ist , richtig?
Mitglied: 131381
131381 Nov 23, 2016 at 13:45:10 (UTC)
Goto Top
Korrekt.