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

Url: https://administrator.de/forum/powershell-dateien-aus-verschiedenen-arrays-attribute-vergleichen-321806.html

Ausgedruckt am: 13.04.2025 um 21:04 Uhr

131381
Lösung 131381 23.11.2016 aktualisiert um 11:18:36 Uhr
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ß
Giffas
Giffas 23.11.2016 um 13:21:57 Uhr
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?
131381
131381 23.11.2016 aktualisiert um 13:32:11 Uhr
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.
Giffas
Giffas 23.11.2016 um 13:44:21 Uhr
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?
131381
131381 23.11.2016 um 14:45:10 Uhr
Goto Top
Korrekt.