Ordner auf Änderungen prüfen?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet
für jeden Ordner der Liste einen Hash erstelle 

...Eine prächtige Idee! 👍

Manchmal sieht man den Wald vor lauter Bäumen nicht. Um ehrlich zu sein, so weit hätte ich nicht mal gedacht.

und Natürlich lässt sich das realisieren sogar recht einfach:

#region FunctionDefine
function Get-FolderHash {
    Param(
      [Parameter(ValueFromPipeline=$true,Mandatory=$true)][string]$Path
    )
     #für das Einbeziehen von Unterverzeichnissen den Parameter -Recurse in die folgende Zeile einfügen.
    $FolderString =(Get-ChildItem $Path -File -Force -ErrorAction SilentlyContinue |
        Select-Object -Property Name,LastWriteTime,Length,Mode|
        ConvertTo-Csv -NoTypeInformation| #mache aus der Objektliste  ein CSV
        Select-Object -Skip 1) -Join ';' #entferne  den Header und vereinige alle Zeilen zu einen einzigen String


    Write-Host $FolderString -fo yellow #Debug: den MörderString mal anzeigen 
    
     #erzeuge  einen SHA512-Hash des erzeugten Strings
    $hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha512')
    $hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($FolderString))
    $hashString = [System.BitConverter]::ToString($hash)
    $hashString.Replace('-', '')
}
#endregion


$FolderList= @(
    'c:\windows\system32',
    "$env:UserProfile\Documents",
    "$env:UserProfile\Downloads",
    "$env:UserProfile\Desktop\testfolder"
)
$HashFile='FolderHashes.csv'
if (!(Test-Path $HashFile)){
     #wenn noch keine gespeicherten Werte existieren:
    $HashList=$FolderList|
        ForEach-Object {
            $Hash=Get-FolderHash $_
            [PSCustomObject]@{
                Path = $_
                Hash = $Hash
            }
        }
}
else {
    #vergleiche gespeicherte Hashes mit aktuellen
    $HashList=Import-Csv -Path $HashFile
    $HashList=$HashList|
         ForEach-Object {
            $NewHash=Get-FolderHash $_.Path


             #Debug: mal gucken
            Write-Host $_.Path :
            Write-Host alt: $_.Hash  -fo green
            Write-Host neu: $NewHash  -fo red


            if ($NewHash -eq $_.Hash){
                $HasChanged=$False
            }
            else {
                $HasChanged=$True
            }
             #diesmal den Objekten mitgeben ob sie sich verändert haben (HasChanged)
            [PSCustomObject]@{
                Path = $_.Path
                Hash = $NewHash
                HasChanged = $HasChanged
            }
        }
}


 #mal alle  anzeigen
$HashList|ft
 #nur Ordner die sich verändet haben verarbeiten 
$HashList|
    Where-Object{$_.HasChanged}|
    ForEach-Object {
         #was immer geschehen soll (hier  nur Meldung)
        Write-Host Der Ordner : $_.Path wurde veraendert  -fo red
    }


#Hashes als csv speichern
$HashList|
    Select-Object -Property Path,Hash | #wir brauchen  HasChanged nicht speichern, also abwählen
    Export-Csv -Path $HashFile -NoTypeInformation
pause


Das Script arbeitet beim ersten "Lauf" mit der FolderListe .

Existiert "FolderHashes.csv" wird die Folderliste ignoriert und es werden die im CSV gespeicherten Pfade verglichen. (dh. "FolderHashes.csv" löschen, wenn du die Folderlist änderst!)

Zum Hashen nutze ich hier "SHA512", Warsheinlich würde auch ein "schmalerer" Hashalgorithmus wie "MD5" oder "SHA1" ausreichen. ...aber was soll der Geiz...

in der vorliegenden Form werden nur die Dateien im angegebenen Ordner gehasht. Um unterordner einzubeziehen muss:

Get-ChildItem $Path -File -Force -ErrorAction SilentlyContinue 

...zu :

Get-ChildItem $Path -File -Recurse -Force -ErrorAction SilentlyContinue 

... geändert werden.

Erschrecke nicht beim Ausführen, ich habe ein paar Debug-Ausgaben eingebaut, damit du mal einen Einblick bekommst wie etwaige Zwischenergebnisse aussehen. (sind mit #Debug:... markiert)

Die zu hashenden yellow-Strings können ziemlich Fett werden 😮

das Verzeichnis in welchem du die HashDatei speichers sollte natürluch nicht verlichen werden, die wäre immer anders. (könnte man mit einem -Exclude auf den Dateinamen lösen, da hatte ich aber keine Lust mehr.

Du sollst ja auch noch was zu tun haben...😅

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

V4Cmeister 
Fragesteller
 24.10.2022, 08:38

Vielen Dank für die umfangreiche und sehr hilfreiche Antwort.
Ich werde das Script durchlesen und schauen das ich alles verstehe und werde.

Danke für deine investierte Zeit. :)

0