pragomer
Goto Top

Hilfe Powershellscript Ordner vergleichen

Hallo,

ich bin maximal ein "Poweruser" wenn man so will. Ich bin kein Coder, deshalb ist das was ich dringend benötige, am besten mittels eines einfachen Scriptes, auch über meinen Fähigkeiten. Und deshalb: Bitte helft mir!

Das Szenario:
Ich habe zwei Synology NAS Geräte bei denen zwei Ordner synchron gehalten werden. Das geschieht mit einem Synology-Tool, funktioniert super und muss auch so bleiben.

Die Struktur ist hierbei wie folgt:

MAINFOLDER
– Project 1-Folder
File1, File2, File3, etc
– Project 2-Folder
File1, File2, File3, etc
– Project 3-Folder
File1, File2, File3, etc

Der Mainfolder wird hierbei von NAS1 zu NAS2 synchronisiert. Was ich dringend bräuchte:

Ein Script, welches im Mainfolder auf NAS1 und NAS2 (beide als Netzlaufwerk eingebunden) sucht, und dabei die Projekt-Ordner vergleicht. Vergleichskriterien sollten sein:

Dateiname und Dateigröße.

Das wäre ausreichend (hash oder so bräuchte es nicht und würde auch wegen der Dateigröße zu lange dauern).

Dieser Vergleich sollte z.B. alle 30 Minuten stattfinden. Das Ziel soll sein:
Solange z.B. Project1-Folder von Quelle und Ziel noch unterschiedlich sind: Nichts tun. Ist der Inhalt aber identisch, und das Projekt somit vollständig sychronisiert, sollte eine Textdatei in diesen Projektordner geschrieben werden, z.B. namens "fertig.txt".

Somit müsste man nicht ständig manuell nachsehen, ob das eine oder andere Projekt am Ziel eingetroffen ist (Sync kann durchaus zwischen 1 Stunde und 2 Tagen dauern).

Ich habe mir schon Befehle wie "compare" in der Powershell angesehen, aber das hier zu realisieren geht über meine Fähigkeiten weit hinaus.

Wenn es unter euch jemand gibt, dem so etwas leicht(er) fallen würde: ich wäre so so dankbar, wenn ihr mir helfen könntet.

Liebe Grüße

Peter

Content-ID: 6751447819

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

Ausgedruckt am: 22.11.2024 um 07:11 Uhr

Doskias
Doskias 13.04.2023 um 08:28:53 Uhr
Goto Top
Moin,

ich verstehe den Sinn deiner ganzen Aktion nicht:

Zitat von @pragomer:
Das Szenario:
Ich habe zwei Synology NAS Geräte bei denen zwei Ordner synchron gehalten werden. Das geschieht mit einem Synology-Tool, funktioniert super und muss auch so bleiben.
Ok, du hast also ein Tool, welche die Ordner synchron hält. Super. DU musst also nichts händisch kopieren.

Ein Script, welches im Mainfolder auf NAS1 und NAS2 (beide als Netzlaufwerk eingebunden) sucht, und dabei die Projekt-Ordner vergleicht.
Wofür? du kannst doch auf der NAS nachschauen ob eine Synchronisierung läuft, bzw. abgeschlossen ist. Die NAs prüft und vergleicht die ordner doch permanent und synchronisiert bei bedarf.

Vergleichskriterien sollten sein:
Dateiname und Dateigröße.
Was sehr gefährlich ist, dann Name und Größe sagt nicht ob die Datei auch inhaltlich identisch ist.

Das wäre ausreichend (hash oder so bräuchte es nicht und würde auch wegen der Dateigröße zu lange dauern).
Nein würde es nicht. Der Hashwert einer Datei hat nichts mit der Größe der Datei zu tun.

Dieser Vergleich sollte z.B. alle 30 Minuten stattfinden. Das Ziel soll sein:
Solange z.B. Project1-Folder von Quelle und Ziel noch unterschiedlich sind: Nichts tun. Ist der Inhalt aber identisch, und das Projekt somit vollständig sychronisiert, sollte eine Textdatei in diesen Projektordner geschrieben werden, z.B. namens "fertig.txt".
Ist das sinnvoll? Wenn die Ordner synchron sind, dann erstellst du eine Datei, wodurch die Ordner nicht mehr Synchron sind?

Somit müsste man nicht ständig manuell nachsehen, ob das eine oder andere Projekt am Ziel eingetroffen ist (Sync kann durchaus zwischen 1 Stunde und 2 Tagen dauern).
Wenn du nur Größe und Name prüfst, weißt du auch nicht ob die Ordner Synchron sind. Ich kann dir 2 Dateien mit identischem Titel und Größe erstellen, aber völlig unterschiedlichem Inhalt.

Mein Fazit: Das was du vorhast, ergibt für mich auf Grund der Informationslage keinen Sinn.

Gruß
Doskias
SomebodyToLove
SomebodyToLove 13.04.2023 um 08:37:49 Uhr
Goto Top
Hallo Peter,

ich sehe es so wie der Kollege Doskias... Dein vorhaben hat wenig Sinn für mich.
Aber mal zu Übungszwecken, dein Script könnte in etwa so aussehen:

$folder1 = "C:\Ordner1"  
$folder2 = "C:\Ordner2"  

$diff = Compare-Object (Get-ChildItem $folder1 -Recurse) (Get-ChildItem $folder2 -Recurse)

if ($diff -eq $null) {
    New-Item -ItemType file -Path "$folder1\fertig.txt"  
}

Viele Grüße
Somebody
Crusher79
Crusher79 13.04.2023 aktualisiert um 09:22:59 Uhr
Goto Top
Sehe das auch so. Da würde ich denken den Pferden überlassen - NAS. Dafür sind die ausgelegt und haben geeignete
Bordmittel.

Hash wäre mir auch zu aufwendig. Wir setzen Hash für POS ein, um sicher zu gehen das die Dateien vollständig übertragen wurden. Ist was da, wird Event ausgelöst der einen BITS Job auslöst. Am Ende steht und fällt die Bewertung mit der Hashsumme.

Nur bei so abgesetzten Lokationen lohnt sich so ein Aufwand. NAS, gleicher Hersteller, Firmware, App-Stand - da können die "Großen" das so unter sich aus machen.

Geht es um DaSi gibt es noch andere Methoden. Auch Bandlaufwerke nach wie vor. Da würde ich mir komplett nochmal das Konzept anschauen. Gerade wenn man die Speicehr sieht, würde auch ein Trojaner die sehen.

2. NAS ist aber OK - als Redundanz. Keine Frage.
jsysde
jsysde 13.04.2023 um 09:28:24 Uhr
Goto Top
Moin.

Welches "Synology-Tool" setzt du denn ein?
Auf den Synos kannst du imho für alles Benachrichtigungen aktivieren und bei etlichen der Tools kann man auch Skripte vor und/oder nach deren Lauf einfügen - damit könntest du die Syno selbst die "fertig.txt" erzeugen lassen, wenn ein Sync-Job erfolgreich durchgelaufen ist.

Cheers,
jsysde
pragomer
pragomer 13.04.2023 um 10:34:01 Uhr
Goto Top
Hi jsysde,

ich mach das nicht selbst, aber ich schau bzw. frage mal nach was das für ein Tool ist. Zumindest ne Idee. Aber ich denke unser Kollege der es eingerichtet hat, hätte diese Option ggf. schon gefunden. Aber ich hake da nochmal nach. Danke dir.
mayho33
mayho33 13.04.2023 um 11:19:32 Uhr
Goto Top
Zitat von @pragomer:
Ich habe mir schon Befehle wie "compare" in der Powershell angesehen, aber das hier zu realisieren geht über meine Fähigkeiten weit hinaus.

Also meine Google Suche (Compare 2 directories) hat nach 4 Sekunden inclusive eingeben das ausgespuckt:

Scheint ganz simpel zu sein und kann einfach kopiert werden:
https://devblogs.microsoft.com/scripting/easily-compare-two-folders-by-u ...
pragomer
pragomer 13.04.2023 um 11:19:43 Uhr
Goto Top
Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Ich bräuchte jetzt nur noch die Möglichkeit, dass ich den Übergeordneten Ordner als Quelle/Ziel angebe, und dass der Vergleich für alle enthaltenen Unterordner gemacht wird (es ist immer genau eine Hierarchie darunter!).

Hättest du dafür vielleicht auch noch eine Lösung? Dann hätte ich nämlich 100% genau das was ich bräuchte. Das wär super lieb!!!
pragomer
pragomer 13.04.2023 um 11:23:21 Uhr
Goto Top
Also im Prinzip müsste das, was dein Script gemacht, genauso für JEDEN Unterordner gemacht werden, "Projekt1, Projekt2, usw"
mayho33
mayho33 13.04.2023 um 11:25:57 Uhr
Goto Top
Zitat von @pragomer:

Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Hey pragomer,

Bitte nutze doch die "Zitieren"-Funktion
zitieren

Dann wissen alle wen du gerade ansprichst
pragomer
pragomer 13.04.2023 um 11:37:23 Uhr
Goto Top
Zitat von @mayho33:

Zitat von @pragomer:

Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Hey pragomer,

Bitte nutze doch die "Zitieren"-Funktion
zitieren

Dann wissen alle wen du gerade ansprichst

Super. Danke für den Hinweise. Ich teste es gleich mal face-smile
pragomer
pragomer 13.04.2023 um 11:42:06 Uhr
Goto Top
Zitat von @SomebodyToLove:

Hallo Peter,

ich sehe es so wie der Kollege Doskias... Dein vorhaben hat wenig Sinn für mich.
Aber mal zu Übungszwecken, dein Script könnte in etwa so aussehen:

$folder1 = "C:\Ordner1"  
$folder2 = "C:\Ordner2"  

$diff = Compare-Object (Get-ChildItem $folder1 -Recurse) (Get-ChildItem $folder2 -Recurse)

if ($diff -eq $null) {
    New-Item -ItemType file -Path "$folder1\fertig.txt"  
}

Viele Grüße
Somebody

Also im Prinzip müsste das Script im definierten ordner "Folder1" nur:
Schauen, gibt es einen Unterordner und dann von genau diesem (oder mehreren) den Vergleich machen.
pragomer
pragomer 13.04.2023 um 11:45:48 Uhr
Goto Top
Zitat von @pragomer:

Zitat von @mayho33:

Zitat von @pragomer:

Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Hey pragomer,

Bitte nutze doch die "Zitieren"-Funktion
zitieren

Dann wissen alle wen du gerade ansprichst

Super. Danke für den Hinweis. Ich teste es gleich mal face-smile
SomebodyToLove
SomebodyToLove 13.04.2023 um 13:43:04 Uhr
Goto Top
Zitat von @pragomer:

Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Ich bräuchte jetzt nur noch die Möglichkeit, dass ich den Übergeordneten Ordner als Quelle/Ziel angebe, und dass der Vergleich für alle enthaltenen Unterordner gemacht wird (es ist immer genau eine Hierarchie darunter!).

Hättest du dafür vielleicht auch noch eine Lösung? Dann hätte ich nämlich 100% genau das was ich bräuchte. Das wär super lieb!!!

Servus Peter,

da musst dann mit einer foreach Schleife über jeden Ordner gehen.
Das könnte dann in etwa so aussehen:

$folder1 = "C:\tmp\test"  
$folder2 = "C:\tmp\test2"  
$folders = Get-ChildItem $folder1 -Directory -Recurse
foreach ($folder in $folders) {
    $compare = Compare-Object $(Get-ChildItem $folder.FullName -Recurse) $(Get-ChildItem "$folder2\$($folder.Name)" -Recurse) -Property Name, Length, LastWriteTime -PassThru  
    if ($compare -eq $null) {
        New-Item -ItemType File -Path "$($folder.FullName)\fertig.txt"  
    }
}

Grüße
Somebody
6247018886
Lösung 6247018886 14.04.2023, aktualisiert am 15.04.2023 um 07:02:55 Uhr
Goto Top
$sourceroot = 'D:\Mainfolder'  
$targetroot = '\\Server\Share\Mainfolder'  
foreach($projectfolder in (Get-ChildItem $sourceroot -Directory | ?{!(Test-Path "$targetroot\$($_.Name)\fertig.txt")})){  
    $files1 = Get-ChildItem $projectfolder.Fullname -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($sourceroot)}}  
    $files2 = Get-ChildItem "$targetroot\$($projectfolder.Name)" -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($targetroot)}}  
    if(!(compare @($files1) @($files2) -Property RelativePath,LastWriteTime,Length)){
        write-host "Project '$($projectfolder.Name)' finished!" -F Green  
        new-item -Path "$targetroot\$($projectfolder.Name)" -ItemType File -Name fertig.txt -force | out-null  
    }
}
Cheers briggs
pragomer
pragomer 18.04.2023 um 09:21:55 Uhr
Goto Top
Zitat von @SomebodyToLove:

Zitat von @pragomer:

Hi SomebodyToLove,

dein Script funktioniert schon mal fast perfekt für mich. Da ich von Scripting nichts verstehe:

Ich bräuchte jetzt nur noch die Möglichkeit, dass ich den Übergeordneten Ordner als Quelle/Ziel angebe, und dass der Vergleich für alle enthaltenen Unterordner gemacht wird (es ist immer genau eine Hierarchie darunter!).

Hättest du dafür vielleicht auch noch eine Lösung? Dann hätte ich nämlich 100% genau das was ich bräuchte. Das wär super lieb!!!

Servus Peter,

da musst dann mit einer foreach Schleife über jeden Ordner gehen.
Das könnte dann in etwa so aussehen:

$folder1 = "C:\tmp\test"  
$folder2 = "C:\tmp\test2"  
$folders = Get-ChildItem $folder1 -Directory -Recurse
foreach ($folder in $folders) {
    $compare = Compare-Object $(Get-ChildItem $folder.FullName -Recurse) $(Get-ChildItem "$folder2\$($folder.Name)" -Recurse) -Property Name, Length, LastWriteTime -PassThru  
    if ($compare -eq $null) {
        New-Item -ItemType File -Path "$($folder.FullName)\fertig.txt"  
    }
}

Grüße
Somebody

Guten Morgen Somebody,

ich habe dein Script mal ausprobiert. Ich ersetze einfach mal die Pfade und führe das Ganze aus. Irgendwie passiert aber nichts. Als Ausgangspunkt hab ich mal gewählt, dass beide Ordner identisch sind, sodass dort in allen Unterordnern ein "fertig.txt" erscheinen müsste. Aktuell passiert aber nichts.
pragomer
pragomer 18.04.2023 um 09:23:09 Uhr
Goto Top
Zitat von @6247018886:

$sourceroot = 'D:\Mainfolder'  
$targetroot = '\\Server\Share\Mainfolder'  
foreach($projectfolder in Get-ChildItem $sourceroot -Directory | ?{!(Test-Path $_.Fullname\fertig.txt)}){
    $files1 = Get-ChildItem $projectfolder.Fullname -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($sourceroot)}}  
    $files2 = Get-ChildItem "$targetroot\$($projectfolder.Name)" -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($targetroot)}}  
    if(!(compare @($files1) @($files2) -Property RelativePath,LastWriteTime,Length)){
        write-host "Project '$($projectfolder.Name)' finished!" -F Green  
        new-item -Path $projectfolder.Fullname -ItemType File -Name fertig.txt -force | out-null
    }
}
Cheers briggs

Hi Briggs,

wenn ich dein Script teste, bekomme ich diese Fehlermeldung:
screenshot 2023-04-18 092235
pragomer
pragomer 18.04.2023 um 09:26:22 Uhr
Goto Top
Zitat von @pragomer:

Zitat von @6247018886:

$sourceroot = 'D:\Mainfolder'  
$targetroot = '\\Server\Share\Mainfolder'  
foreach($projectfolder in Get-ChildItem $sourceroot -Directory | ?{!(Test-Path $_.Fullname\fertig.txt)}){
    $files1 = Get-ChildItem $projectfolder.Fullname -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($sourceroot)}}  
    $files2 = Get-ChildItem "$targetroot\$($projectfolder.Name)" -Recurse -File | select *,@{n='RelativePath';e={$_.Fullname -replace [regex]::Escape($targetroot)}}  
    if(!(compare @($files1) @($files2) -Property RelativePath,LastWriteTime,Length)){
        write-host "Project '$($projectfolder.Name)' finished!" -F Green  
        new-item -Path $projectfolder.Fullname -ItemType File -Name fertig.txt -force | out-null
    }
}
Cheers briggs

Hi Briggs,

wenn ich dein Script teste, bekomme ich diese Fehlermeldung:

Mittlerweile hab ich natürlich gesehen, dass am Ende eine geschweifte Klammer fehlte, aber auch mit der, bekomme ich eine (andere) Fehlermeldung:
screenshot 2023-04-18 092235
pragomer
pragomer 18.04.2023 um 09:31:33 Uhr
Goto Top
Es wäre MEGA toll, wenn ihr mir nochmal weiter helfen könnten. Ich bin mir sehr sicher, dass das iwie hinhaut face-smile
6247018886
6247018886 18.04.2023 aktualisiert um 09:39:42 Uhr
Goto Top
Sorry Tippfehler, o. geändert ...

p.s. man kann Posts auch zusammenfassend schreiben ohne immer gleich nen neuen Kommentar zu erstellen! Wir antworten dadurch nicht schneller wenn man damit versucht die Leute zu nerven ... 😐
Diskussionsrichtlinien - die Regeln zu unseren Inhalten
Nicht zwei Kommentare nacheinander posten, sondern die BEARBEITEN-Funktion nutzen oder den Moderator bitten, den Kommentar zu löschen.
pragomer
pragomer 18.04.2023 um 09:47:33 Uhr
Goto Top
Zitat von @6247018886:

Sorry Tippfehler, o. geändert ...

p.s. man kann Posts auch zusammenfassend schreiben ohne immer gleich nen neuen Kommentar zu erstellen! Wir antworten dadurch nicht schneller wenn man damit versucht die Leute zu nerven ... 😐
Diskussionsrichtlinien - die Regeln zu unseren Inhalten
Nicht zwei Kommentare nacheinander posten, sondern die BEARBEITEN-Funktion nutzen oder den Moderator bitten, den Kommentar zu löschen.

Hi, sorry, wollte wirklich nicht nerven. Mm, ich hab ja auf beide Scripte geantwortet, also das waren ja veschiedene Rückmeldungen... Aber ich werd da besser aufpassen. Ok, und jetzt schau ich mir mal deine Änderungen an. Danke schonmal sehr. Ich geb dir gleich eine Rückmeldung.
pragomer
pragomer 18.04.2023 um 09:51:47 Uhr
Goto Top
Zitat von @6247018886:

Sorry Tippfehler, o. geändert ...

p.s. man kann Posts auch zusammenfassend schreiben ohne immer gleich nen neuen Kommentar zu erstellen! Wir antworten dadurch nicht schneller wenn man damit versucht die Leute zu nerven ... 😐
Diskussionsrichtlinien - die Regeln zu unseren Inhalten
Nicht zwei Kommentare nacheinander posten, sondern die BEARBEITEN-Funktion nutzen oder den Moderator bitten, den Kommentar zu löschen.

Tut mir leid, hast du dein ursprüngliches Script geändert? Ich bekommen irgendwie dieselbe Fehler meldung noch. Aber danke danke danke dass du mir hilfst.
6247018886
6247018886 18.04.2023 aktualisiert um 10:13:46 Uhr
Goto Top
Dann hast du's falsch kopiert oder verwendest eine zu alte PowerShell.
Läuft hier im Test einwandfrei!
pragomer
pragomer 18.04.2023 um 10:35:13 Uhr
Goto Top
Zitat von @6247018886:

Dann hast du's falsch kopiert oder verwendest eine zu alte PowerShell.
Läuft hier im Test einwandfrei!

Briggs, vielen vielen lieben Dank. Es läuft. Ich bin dir so dankbar. Weißt du, was mein Fehler war: Ich hatte im Zielverzeichnis nachgesehen, ob dort die "fertig.txt" liegen. Aber die landeten im Quellverzeichnis.

Ich sehe mir gerade den Code an, um als Nicht-Programmierer herauszufinden, an welcher Stelle ich das ändern müsste, damit die Text-Datei im Target landet, traue mir das aber nicht zu.

Ich muss dir echt wie ein totaler Noob vorkommen, ich hab aber nichts mit Scripting zu tun normalerweise.
Wenn du mir diese Alternative vielleicht noch aufzeigen könntest, wäre es einfach perfekt.

Schon jetzt möchte ich mich wirklich 1000fach bedanken. Für deine Zeit und Mühe. Das ist nicht selbstverständlich. Du, und der Dank auch an die anderen, hast mir wirklich so sehr geholfen.

Danke!
6247018886
6247018886 18.04.2023 um 10:46:25 Uhr
Goto Top
Zitat von @pragomer:

Ich hatte im Zielverzeichnis nachgesehen, ob dort die "fertig.txt" liegen. Aber die landeten im Quellverzeichnis.

Ich sehe mir gerade den Code an, um als Nicht-Programmierer herauszufinden, an welcher Stelle ich das ändern müsste, damit die Text-Datei im Target landet, traue mir das aber nicht zu.
Hab's oben angepasst.

Cheers
pragomer
pragomer 18.04.2023 um 10:57:05 Uhr
Goto Top
Zitat von @6247018886:

Zitat von @pragomer:

Ich hatte im Zielverzeichnis nachgesehen, ob dort die "fertig.txt" liegen. Aber die landeten im Quellverzeichnis.

Ich sehe mir gerade den Code an, um als Nicht-Programmierer herauszufinden, an welcher Stelle ich das ändern müsste, damit die Text-Datei im Target landet, traue mir das aber nicht zu.
Hab's oben angepasst.

Cheers

Wahnsinn. Nochmals 1000 Dank!
Ich markieren mal dein Script als Lösung