Powershell mehrere Dateien vergleichen
Hallo
Ich möchte von unterschiedlichen PC's gewisse Dateien in einem Verzeichniss vergleichen.
Dies soll dann ermitteln ob die Dateien ein unterschiedliches Datum haben.
In den Verzeichnissen, werden Programmteile abgespeichert, die manchmal zuerst auf einen PC getestet werden und erst danach verteilt werden.
Aktuell ermittle ich mit einer Batch den Inhalt der Verzeichnisse und gebe diese dann in einem File aus.
Jetzt wollte ich mittels einer Powershell den Inhalt der Dateien vergleichen und bei einem Unterschied soll er eine Email senden.
Das klappt auch mit 2 Dateien.
Das klappt auch soweit.
Aber wie kann ich hier 3 oder mehrere Files auf einmal überprüfen und dann eine einzige Email senden, in der dann nur der PC entahlten ist wo sich der Unterschied befindet?
Mir ist klar das man dies eleganter lösen könnte, aber ich bin schon mal froh, daß ich das soweit hinbekommen habe.
Bin für jede Hilfe Dankbar.
Ich möchte von unterschiedlichen PC's gewisse Dateien in einem Verzeichniss vergleichen.
Dies soll dann ermitteln ob die Dateien ein unterschiedliches Datum haben.
In den Verzeichnissen, werden Programmteile abgespeichert, die manchmal zuerst auf einen PC getestet werden und erst danach verteilt werden.
Aktuell ermittle ich mit einer Batch den Inhalt der Verzeichnisse und gebe diese dann in einem File aus.
for /F "delims=" %%i in ('"dir /s /b /a-d "\\Sharename1\xyz\123\*.pvg" "') do (echo %%~nxi %%~ti >> c:\tmp\1\PC1)
for /F "delims=" %%i in ('"dir /s /b /a-d "\\Sharename2\xyz\123\*.pvg" "') do (echo %%~nxi %%~ti >> c:\tmp\1\PC2)
usw.
Jetzt wollte ich mittels einer Powershell den Inhalt der Dateien vergleichen und bei einem Unterschied soll er eine Email senden.
Das klappt auch mit 2 Dateien.
$PVG1 = Compare-Object (get-content $path$file1) (get-content $path$file2 ) -CaseSensitive -PassThru | where {$_.SideIndicator -eq '<='}
$PC1 = Compare-Object ($file1) ($file2 ) -CaseSensitive -PassThru | where {$_.SideIndicator -eq '<='}
#$PVG2 = Compare-Object (get-content $path$file1) (get-content $path$file3 ) -CaseSensitive -PassThru | where {$_.SideIndicator -eq '<='}
#$PC2 = Compare-Object ($file1) ($file3 ) -CaseSensitive -PassThru | where {$_.SideIndicator -eq '<='}
Write-Host $PVG1
Write-Host $PC1
Write-Host $PVG2
Write-Host $PC2
Send-MailMessage –To "Emailr@xy.123.com" `
–Subject ("ACHTUNG PVG DATEI '$PVG1' UNTERSCHIEDLICH!")`
–Body ("Die PVG '$PVG1' ist auf dem PC '$PC1' unterschiedlich")`
–SmtpServer "smtpcom" `
–From "noreplay@domain.com" `
-encoding ([System.Text.Encoding]::UTF8)
Das klappt auch soweit.
Aber wie kann ich hier 3 oder mehrere Files auf einmal überprüfen und dann eine einzige Email senden, in der dann nur der PC entahlten ist wo sich der Unterschied befindet?
Mir ist klar das man dies eleganter lösen könnte, aber ich bin schon mal froh, daß ich das soweit hinbekommen habe.
Bin für jede Hilfe Dankbar.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 841038546
Url: https://administrator.de/contentid/841038546
Ausgedruckt am: 17.11.2024 um 19:11 Uhr
16 Kommentare
Neuester Kommentar
Waren wir alle mal. Ich weiß jetzt nicht genau was du im Detail vor hast, aber vielleicht ist dir auch mit Compare-Object schon geholfen
Servus @sugram,
da führen viele Wege nach Rom aber von der Ausgabe in Textdateien solltest du dich endgültig verabschieden, das war schon zu Batch-Zeiten ein unnötiger Workaround und mit Powershell erst recht nicht mehr nötig.
Habe dir hier mal 3 unterschiedliche Varianten zum Vergleichen von Verzeichnis-Inhalten aufgeführt. Das Send-MailMessage habe ich hier jetzt weggelassen, denke das sollte sich von selbst erklären wo du es einbauen musst .
Viel Erfolg!
Grüße Uwe
da führen viele Wege nach Rom aber von der Ausgabe in Textdateien solltest du dich endgültig verabschieden, das war schon zu Batch-Zeiten ein unnötiger Workaround und mit Powershell erst recht nicht mehr nötig.
Habe dir hier mal 3 unterschiedliche Varianten zum Vergleichen von Verzeichnis-Inhalten aufgeführt. Das Send-MailMessage habe ich hier jetzt weggelassen, denke das sollte sich von selbst erklären wo du es einbauen musst .
Einfacher Vergleich eines Referenz-Ordners mit mehreren anderen Ordnern mittels der Properties Name und LastWriteTime
# Referenzordner
$ref_dir = 'D:\Referenzordner'
# Dateifilter
$filefilter = '*.pvg'
# Ordner die zu vergleichen sind
$shares = "\\Sharename1\xyz\123","\\Sharename2\xyz\123"
# Dateien des Referenzordners auflisten
$ref = ls $ref_dir -File -Filter $filefilter
# für jeden Ordner im Array ...
foreach ($share in $shares){
# vergleiche den Referenzordner mit dem in der Schleife aktuellen anhand Name und LastWriteTime
$diff = compare @($ref) @(ls $share -File -Filter $filefilter) -Property Name,LastWriteTime
# wenn es Unterschiede gibt ...
if ($diff){
"'$share' hat unterschiedliche Dateien"
$diff | ft -AutoSize
}
}
Vergleich eines Referenz-Ordners mit mehreren anderen Ordnern mittels Datei-Hashes
# Referenzordner
$ref_dir = 'D:\Referenzordner'
# Dateifilter
$filefilter = '*.pvg'
# Ordner die zu vergleichen sind
$shares = "\\Sharename1\xyz\123","\\Sharename2\xyz\123"
# Hashes für alle Dateien im Referenzordner ermitteln und Property für Name hinzufügen
$ref = Get-FileHash "$ref_dir\$filefilter" -Algorithm SHA256 | select Hash,@{n='Name';e={split-path $_.Path -Leaf}}
# für jeden Ordner im Array ...
foreach($share in $shares){
# Hashes des zu vergleichenden Ordners berechnen lassen und Property für Name hinzufügen
$dir_hashes = Get-FileHash "$share\$filefilter" | select Hash,@{n='Name';e={split-path $_.Path -Leaf}}
# vergleiche die Hashes/Dateinamen
$diff = compare @($ref) @($dir_hashes) -Property Name,Hash
# wenn es Unterschiede gibt ...
if ($diff){
"'$share' hat unterschiedliche Dateien"
$diff | ft -AutoSize
}
}
Vergleich eines Referenz-Ordners mit mehreren anderen Ordnern mit der Hilfe von Robocopy im Simulationsmodus
# Referenzordner
$ref_dir = 'D:\Referenzordner'
# Dateifilter
$filefilter = '*.pvg'
# Ordner die zu vergleichen sind
$shares = "\\Sharename1\xyz\123","\\Sharename2\xyz\123"
# für jeden Ordner im Array ...
foreach($share in $shares){
# Unterschiede zwischen Referenz und aktuellem Ordner mittels Robocopy ermitteln (Leerzeilen werden aus der Ausgabe entfernt und führenden Whitspace entfernt)
$diff = robocopy $ref_dir $share $filefilter /l /NDL /NJS /NJH /NC /NS /FP | ?{$_ -notmatch '^\s*$'} | %{$_ -replace '^\s*'}
# wenn es Unterschiede gibt ...
if ($diff.count -gt 0){
"'$share' hat unterschiedliche Dateien"
$diff
}
}
Bin in Powershell noch totaler Anfänger.
Da haben wir hier genau das richtige für dich, frisch aus dem Backofen: Powershell Link-Leitfaden für AnfängerViel Erfolg!
Grüße Uwe
Zitat von @sugram:
Das
klappt schon mal ganz gut, muss nur noch hinbekommen, daß er mir die unterschiedlichen Dateien ausgibt.
Aber sonst schaut das schon sehr vielversprechend aus
Die sind doch schon jeweils in der Variablen $diff gespeichert .Das
Einfacher Vergleich eines Referenz-Ordners mit mehreren anderen Ordnern mittels der Properties Name und LastWriteTime
klappt schon mal ganz gut, muss nur noch hinbekommen, daß er mir die unterschiedlichen Dateien ausgibt.
Aber sonst schaut das schon sehr vielversprechend aus
Btw. hatte einen kleinen Variablen-Schreibfehler Fehler in den Scripts korrigiert, als ich Variablen umbenannt hatte.
Zitat von @sugram:
Jetzt muss ich aber doch noch ein paar Files aus der Suche ignorieren.
Aber ich bekomme das mit dem Parameter -exclude nicht hin?!
Ist das nicht
?!
Nicht ganz bei Parameter Exclude muss man im Pfad-Parameter zusätzlich noch ein Wildcard setzen damit er das Exclude auch akzeptiert (MS hat das hier leider in bestimmten Konstellationen bei Get-ChildItem nicht so klar umgesetzt)Jetzt muss ich aber doch noch ein paar Files aus der Suche ignorieren.
Aber ich bekomme das mit dem Parameter -exclude nicht hin?!
Ist das nicht
> ls $ref_dir -File -Filter $filefilter -exclude *123456*
>
?!
$ref = ls "$ref_dir\*" -File -Filter $filefilter -exclude '*123456*'
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.
Zitat von @sugram:
Hallo
Leider ist dem nicht so.
wenn ich dann das in $diff.name ändere erhelte ich die Email mit dem Inhalt
Hallo
Leider ist dem nicht so.
wenn ich dann das in $diff.name ändere erhelte ich die Email mit dem Inhalt
> Die Datei .name ist auf \\Sharename2\xyz\123 unterschiedlich
>
Und wie sieht dein Ergebnis von $Diff aus? Sorry, aber wenn du Hilfe möchtest, dann liefere doch auch mal ein paar Infos. Ich habe keine Lust/Zeit deine Lösung hier nachzubauen, weil dafür werde ich nicht bezahlt
Setz zum Beispiel zum Testen mal ein
$diff
pause
Gruß
Doskias
Zitat von @sugram:
Aber das mit den Dateinamen bekomme ich nicht hin?!
Wenn ich mir nun dafür eine Email senden lasse, erhalte ich zwar den UNC Pfad, aber nicht den Dateinamen
$diff ist ein Object mit einem oder mehreren Objekten die Eigenschaften haben, ergo musst du dies ja erst na auswählen!Aber das mit den Dateinamen bekomme ich nicht hin?!
Die sind doch schon jeweils in der Variablen $diff gespeichert .
Wenn ich mir nun dafür eine Email senden lasse, erhalte ich zwar den UNC Pfad, aber nicht den Dateinamen
Und da es mehrere Dateien sein können musst du die auch entsprechend formatieren
write-host "Folgende Dateien sind unterschiedlich:`n$($diff.Name -join "`r`n")"
Zitat von @sugram:
Hallo
Leider ist dem nicht so.
wenn ich dann das in $diff.name ändere erhelte ich die Email mit dem Inhalt
Doch aber man muss Properties innerhalb von Anführungszeichen mit eine Subexpression ansprechenHallo
Leider ist dem nicht so.
wenn ich dann das in $diff.name ändere erhelte ich die Email mit dem Inhalt
> Die Datei .name ist auf \\Sharename2\xyz\123 unterschiedlich
>
"$($diff.Name) ist unterschiedlich"
Mussten und müssen wir alle (naja, nicht alle) noch. Schau am Besten hier:
Powershell Leitfaden für Anfänger
Powershell Leitfaden für Anfänger