Dateien in einem Ordner verfallen lassen: Dateien nach x Tagen löschen


12

Ich möchte einen "Ablageordner" in einem freigegebenen Windows-Laufwerk erstellen, auf den jeder zugreifen kann. Ich möchte, dass Dateien automatisch gelöscht werden, wenn sie länger als X Tage im Ordner verbleiben.

Es scheint jedoch so, als ob alle Methoden, die ich gefunden habe, das Datum der letzten Änderung, die letzte Zugriffszeit oder das Erstellungsdatum einer Datei verwenden.

Ich versuche, dies zu einem Ordner zu machen, in den ein Benutzer Dateien ablegen kann, um sie für jemanden freizugeben. Wenn hier Dateien kopiert oder verschoben werden, möchte ich, dass die Uhr an dieser Stelle beginnt zu ticken. Das Datum der letzten Änderung und das Erstellungsdatum einer Datei werden jedoch nur aktualisiert, wenn die Datei tatsächlich geändert wird. Die letzte Zugriffszeit wird zu häufig aktualisiert. Es scheint, dass nur das Öffnen eines Verzeichnisses im Windows Explorer die letzte Zugriffszeit aktualisiert.

Kennt jemand eine Lösung dafür? Ich denke, dass das tägliche Katalogisieren des Hashs von Dateien und das anschließende Ablaufen von Dateien auf der Grundlage von Hashes, die älter als ein bestimmtes Datum sind, eine Lösung sein kann. Das Erstellen von Hashes von Dateien kann jedoch zeitaufwändig sein.

Irgendwelche Ideen wäre sehr dankbar!

Hinweis:
Ich habe hier bereits eine ganze Reihe von Antworten gelesen ... Ich habe mir File Server Resource Monitor, Powershell-Skripte, Batch-Skripte usw. angesehen. Sie verwenden weiterhin die letzte Zugriffszeit, die letzte Änderungszeit oder die Erstellungszeit ... welche, wie beschrieben, nicht die oben genannten Bedürfnisse erfüllen.


Eine Frage, die von @Michael Kjorling gestellt wurde, lautet: Hört der Timer auf zu zählen, wenn die Datei nach dem Ablegen in der Box geändert wird?
Get-HomeByFiveOClock

Was Sie suchen, ist das Windows-Äquivalent von tmpwatch.
Avery Payne

Antworten:


5

Wir haben eine Kombination aus einem Powershell-Skript und einer Richtlinie verwendet. Die Richtlinie gibt an, dass der Benutzer einen Ordner in der Drop_Zone-Freigabe erstellen und anschließend alle gewünschten Dateien in diesen Ordner kopieren muss. Wenn der Ordner 7 Tage alt ist (mit CreationTime), wird er vom Powershell-Skript gelöscht.

Ich habe dem Powershell-Skript auch einige Protokollierungsschritte hinzugefügt, damit wir überprüfen können, ob es funktioniert, und Schattenkopien aktiviert, nur um die völlig Unfähigen vor sich selbst zu retten.

Hier ist das Skript ohne das gesamte Protokollierungsmaterial.

$location = Get-ChildItem \\foo.bar\Drop_Zone
$date = Get-Date
foreach ($item in $location) {
  # Check to see if this is the readme folder
  if($item.PsIsContainer -and $item.Name -ne '_ReadMe') {
    $itemAge = ((Get-Date) - $item.CreationTime).Days
    if($itemAge -gt 7) {
      Remove-Item $item.FullName -recurse -force
    }
  }
  else {
  # must be a file
  # you can check age and delete based on that or just delete regardless
  # because they didn't follow the policy
  }
}

1
Dies scheint am einfachsten zu sein, ist nicht mit dem Dateidatum-Zeitstempel oder alternativen Datenströmen zu verwechseln oder erfordert eine Liste von Dateien und deren Ablegedaten. Ich wollte ein großartiges Skript erstellen, das alle Arten von Magie ausführte, aber dann sah ich das.
BeowulfNode42

und es ist kein Dateisystem-Überwachungsereignis erforderlich, das das Skript die ganze Zeit auslöst, da es einmal pro Tag ausgeführt werden kann, und es spielt keine Rolle, ob ein Tag aus irgendeinem Grund verpasst wird.
BeowulfNode42

2
Tolle einfache Idee, genau wie @ BeowulfNode42 darauf hingewiesen hat. Um sicherzustellen, dass Benutzer einen Ordner erstellen müssen, muss durch einfaches "Verweigern" der Zugriffssteuerungsliste "Dateien erstellen / Daten schreiben" auf "Nur dieser Ordner" sichergestellt werden, dass Benutzer auch Unterordner erstellen müssen.
Brett G

3

Wenn Sie NTFS annehmen können, können Sie einen Schlüssel (Guid) in einen alternativen Stream der Datei schreiben. Plus das Datum, so dass Sie im Grunde die Datenbank in den Dateien speichern können.

Weitere Informationen finden Sie unter

http://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx

Grundsätzlich können Sie zusätzlichen Inhalt in einem separaten Stream speichern, der durch einen speziellen Namen codiert ist.


Wie würde man das machen?
Brett G

@BrettG Link zur Dokumentation hinzugefügt. "NTFS Alternate Data Stream" hätte dazu geführt, dass Sie es auch in Google finden, nur für den Fall - Sie kennen Google nicht.
TomTom

Entschuldigung, ich weiß, was alternative Datenströme sind. Ich habe nur versucht, ihre Verwendung in diesem Kontext zu verstehen. Sie sagen also, anstatt einen Hash oder etwas zu verwenden, verwenden Sie eine GUID (und / oder ein Datum) im alternativen Datenstrom, um die Dateien zu verfolgen.
Brett G

Ja. Wenn Sie eine Datei zuverlässig MARKIEREN können - Sie können sogar das Markierungsdatum einfügen -, müssen Sie keinen Hash berechnen.
TomTom

Achten Sie einfach darauf, ob eine Datei aus dem Speicher kopiert, bearbeitet und dann zurückkopiert wird. Sie möchten dann den Timer neu starten, wofür ein Hash nützlich sein könnte.
ein Lebenslauf

2

Sie können IO.FileSystemWatcher verwenden, mit dem Sie einen Ordner auf neu erstellte Dateien "überwachen" können. Hier sind die Teile, die Sie benötigen, um diese Arbeit zu machen.

Diese Variablen konfigurieren den zu überwachenden Pfad und einen Filter zur Feinabstimmung der zu verfolgenden Dateien:

$watchFolderPath = $env:USERPROFILE
$watchFolderFilter = "*.*"

Hiermit werden die Parameter für den Ordner festgelegt, der überwacht werden soll, und die Aktionen, die ausgeführt werden sollen, wenn das Ereignis eintritt. Grundsätzlich setzt dies die LastWriteTime für jede Datei zurück, wie sie geschrieben wurde:

$watcher = New-Object IO.FileSystemWatcher $watchFolderPath, $watchFolderFilter -Property @{
    IncludeSubdirectories = $true
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
    }
$onCreated = Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
    $FileName = $Event.SourceEventArgs.FullPath
    $file = Get-Item $FileName
    $file.LastWriteTime = Get-Date
    }

Das Ereignis kann bei Bedarf folgendermaßen abgemeldet werden:

Unregister-Event -SourceIdentifier FileCreated

Schließlich können Sie dies einmal täglich ausführen, um die alten Dateien zu bereinigen:

Get-ChildItem $watchFolderPath -Recurse | Where-Object {((Get-Date)-$_.LastWriteTime).TotalDays -gt 6} | Remove-Item

Das sollte alles sein, was Sie brauchen ...


Bearbeitet, um das LastWriteTime-Attribut festzulegen, wenn die Datei erstellt wird, und um diese zu einem späteren Zeitpunkt zum Löschen von Dateien zu verwenden.
Tim Ferrill

1

Es ist schon eine Weile her, aber ich habe eine relativ einfache Methode entwickelt, um dies zu beheben.

Ich würde alle Dateien berühren, die dem Ablageverzeichnis hinzugefügt wurden (überwacht über ein Dienstprogramm zur Ressourcenüberwachung) und das Datum der letzten Änderung auf das Datum setzen, das dem Ordner hinzugefügt wurde.

Ich könnte dann das Datum der letzten Änderung verwenden, um alle Dateien zu löschen, die gealtert werden müssen. Dies hat auch den Vorteil, dass der Countdown zurückgesetzt wird, wenn jemand die Datei wirklich aktualisiert.


Perfekte Idee. Ich werde meine eigenen Nachforschungen anstellen. Aber weißt du, welches Dienstprogramm zur Ressourcenüberwachung du verwendet hast?
Brett G

@BrettG ehrlich gesagt war es fast 10 Jahre her. Ich kann mich nicht erinnern. Du machst mich alt. :) Wenn ich es heute tun würde, würde ich einen Job basierend auf Dateisystem-Überwachungsereignissen in der Ereignisanzeige ausführen. Das FileSystemWatcher .NET-Objekt ist meiner Meinung nach über PowerShell verfügbar. Es wäre eine andere Option.
Tim Brigham

Ha, ich wusste nicht, dass du das so lange meintest, als du "eine Weile" gesagt hast. Ja, komischerweise habe ich mir gerade FileSystemWatcher angesehen. Obwohl, ich glaube nicht, dass es mit verschobenen / kopierten Dateien funktionieren würde. Danke für die Antwort!
Brett G

1
@BrettG - Filesystemwatcher kann in Verbindung mit einer Tracking-Tabelle verwendet werden, hat jedoch eigene Probleme. Siehe hier: stackoverflow.com/questions/1764809/… stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP

1
@ BrettG - Auch dies ist eine gute Erweiterung zu FSW: codeproject.com/Articles/58740/…
JohnP

1

Es gibt keine Möglichkeit, sich auf die Daten zu verlassen, an denen eine Datei kopiert oder in einen Ordner verschoben wurde. Windows kann es zwischen Dateisystemen, Laufwerken, Netzwerkfreigaben usw. beibehalten. Möglicherweise können Sie einen Fehler mit einem Linux-Dateiserver beheben oder verhindern, dass Benutzer Dateien mithilfe von FTP oder einem webbasierten Upload-System direkt kopieren.

Wenn Sie damit einverstanden sind, dass Benutzer die Dateien nach dem Hochladen nicht ändern können, haben Sie möglicherweise separate Upload- und Zugriffsordner sowie ein Skript, mit dem Dateien zwischen ihnen verschoben und neu datiert werden. Es hört sich jedoch so an, als ob Sie möchten, dass die Benutzer die Dateien direkt ändern können.

Eine einfache, wenn auch etwas abgedroschene Lösung wäre es, mit den Daten herumzuspielen. Ich würde zwei Skripte schreiben:

Stündliches Date Changer-Skript

Lassen Sie ein Skript etwa einmal pro Stunde in Ihrer bevorzugten Sprache ausführen, um Folgendes zu tun:

  • Sucht nach Dateien mit einem Datum, das in den letzten 20 Jahren geändert wurde.
  • Wenn eine solche Datei gefunden wird, ändern Sie das Datum auf heute minus 20 Jahre.

In Powershell würde es ungefähr so ​​aussehen:

$path = "D:\test"

$today = Get-Date
$before = $today.AddDays(-7300) #356*20 days

Get-ChildItem -Recurse -Path $path | foreach {
    if ($_.LastWriteTime -gt $before) {
        Write-Host $_.Name
        $_.LastWriteTime = $before
    }
}

Wenn Sie dieses Skript heute (27. Mai) ausführen, wird das Änderungsdatum aller Dateien auf den 1. Juni 1994 festgelegt - genau vor 356 * 20 Tagen. Da nur Dateien geändert werden, die neuer sind als der Wert "$ before", werden Dateien, die bereits in der Vergangenheit liegen, nicht berührt.

Bereinigungsskript

Das Bereinigungsskript würde jede Nacht ausgeführt und:

  • Suche nach Dateien mit dem Änderungsdatum "vor 20 Jahren und X Tagen"
  • Lösche sie

Ich werde das Skript für diesen Teil nicht schreiben - es gibt viele Dienstprogramme, mit denen Sie Dateien löschen können, die älter als ein bestimmtes Datum sind. Wählen Sie, was Sie möchten. Der wichtige Teil ist, nach Dateien zu suchen, die 7300 + X Tage alt sind, wobei X die Anzahl der Tage angibt, die Sie seit der letzten Änderung aufbewahren möchten.

Vorteile

Dies hat einige Vorteile gegenüber den anderen Antworten hier:

  • Der Timer wird zurückgesetzt, wenn jemand die Datei ändert.
  • Es sind keine alternativen NTFS-Streams zum Markieren der Dateien erforderlich (diese werden beim Verschieben der Datei beibehalten und können daher zum vorzeitigen Löschen einer geänderten Datei führen).
  • Sollte nur minimale Auswirkungen auf die Leistung haben. Keine Notwendigkeit, eine Datenbank oder eine Liste von Dateinamen und / oder Hashes zu führen.
  • Nichts bricht schrecklich, wenn die Skripte nicht ausgeführt werden können. Es ist kein Dienst oder ständig laufendes Programm erforderlich, um das Datum zu aktualisieren. Nur ein paar geplante Aufgaben. Lösungen, die darauf angewiesen sind, nach neuen Dateien zu suchen und deren letzten Änderungszeitpunkt auf den aktuellen Stand zu bringen, können dazu führen, dass neue Dateien gelöscht werden, wenn der Dienst ausfällt oder ein Race Condition auftritt.

Das einzige Problem, das ich sehen kann, ist, ob Leute eine Datei, die vor 20 Jahren zuletzt geändert wurde, in den Ablageordner kopieren. Ich denke, in den meisten Szenarien ist das wahrscheinlich kein großes Problem, aber es könnte auftauchen.


0

Sie können das Hinzufügen von Dateien zur Dropbox über eine Webseite mit einem "Upload" -IFRAME formalisieren. Der Benutzer könnte dann die Datei "posten", wodurch ein PHP / ASP-Job auf dem Server aufgerufen wird, der die Datei aufnimmt und an der Pucker-Position ablegt. Das PHP / ASP kann eine beliebige Anzahl von Index- / Analyseoperationen ausführen.


0

Wenn hier Dateien kopiert oder verschoben werden, möchte ich, dass die Uhr an dieser Stelle beginnt zu ticken. Das Datum der letzten Änderung und das Erstellungsdatum einer Datei werden jedoch nur aktualisiert, wenn die Datei tatsächlich geändert wird.

Ich würde ein Skript erstellen, das alle fünf Minuten als geplante Aufgaben ausgeführt wird und zwei Dinge ausführt.

  1. Bei der ersten Aktion wird eine Kopie aller in den Ordner kopierten Dateien erstellt, der Datei ein Präfix hinzugefügt und das Original gelöscht. Dies würde sicherstellen, dass das Erstellungsdatum der Datei für die Anwendung einheitlich ist.
  2. Bei der zweiten Aktion werden alle Dateien mit dem festgelegten Präfix (festgelegt mit Aktion 1) geprüft und alle Dateien mit einem Erstellungsdatum gelöscht, das älter als X Tage ist. Dies würde das Problem mit dem Änderungs- / Zugriffsdatum lösen.

0

Es gibt einen Mechanismus zum Markieren von Dateien, das Archivbit. Es gibt es seit den Anfängen von DOS und es ist sowohl auf FAT als auch auf NTFS vorhanden.

Grundsätzlich ist für jede Datei das Archivbit standardmäßig gesetzt. Wenn Sie eine Datei mit dem Archivbit in Ihrem Ablageordner sehen, (1) löschen Sie dieses Bit und (2) setzen Sie das Datum auf heute. Wenn Sie eine Datei ohne dieses Bit und mit einem Datum <= 7 Tage in der Vergangenheit sehen, löschen Sie sie.

Wenn ein Benutzer in die Datei schreibt, während sie sich im Ablageordner befindet, wird das Archivbit erneut gesetzt, sodass auch die Lebensdauer auf 7 Tage zurückgesetzt wird. Immerhin handelt es sich um eine neue Datei.

Sie können FileSystemWatcher jetzt problemlos verwenden. Alle Probleme (wie doppelte Ereignisse, Verlust detaillierter Informationen durch Pufferüberlauf) spielen keine Rolle mehr, da alle relevanten Informationen in den Dateimetadaten enthalten sind.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.