Expiration des fichiers dans un dossier: supprimer des fichiers après x jours

12

Je cherche à créer un "dossier de dépôt" dans un lecteur partagé Windows accessible à tous. J'aimerais que les fichiers soient supprimés automatiquement s'ils restent dans le dossier pendant plus de X jours.

Cependant, il semble que toutes les méthodes que j'ai trouvées pour ce faire, utilisent la dernière date de modification, la dernière heure d'accès ou la date de création d'un fichier.

J'essaie d'en faire un dossier dans lequel un utilisateur peut déposer des fichiers à partager avec quelqu'un. Si quelqu'un copie ou déplace des fichiers ici, j'aimerais que l'horloge commence à tourner à ce stade. Cependant, la dernière date de modification et la date de création d'un fichier ne seront pas mises à jour à moins que quelqu'un ne modifie réellement le fichier. Le dernier temps d'accès est mis à jour trop fréquemment ... il semble que l'ouverture d'un répertoire dans l'explorateur Windows mettra à jour le dernier temps d'accès.

Quelqu'un connaît une solution à cela? Je pense que cataloguer le hachage des fichiers quotidiennement, puis expirer les fichiers en fonction de hachages antérieurs à une certaine date pourrait être une solution ... mais prendre des hachages de fichiers peut prendre du temps.

Toutes les idées seraient grandement appréciées!

Remarque:
j'ai déjà examiné pas mal de réponses ici ... j'ai examiné le moniteur de ressources du serveur de fichiers, les scripts PowerShell, les scripts batch, etc. Ils utilisent toujours la dernière heure d'accès, la dernière heure modifiée ou l'heure de création ... qui, comme décrit, ne répondent pas aux besoins ci-dessus.

Brett G
la source
Une question, comme l'a mentionné @Michael Kjorling, le minuteur arrête-t-il de compter si le fichier est modifié après avoir été déposé dans la boîte?
Get-HomeByFiveOClock
Ce que vous cherchez, c'est l'équivalent de Windows tmpwatch.
Avery Payne

Réponses:

5

Nous avons utilisé une combinaison d'un script PowerShell et d'une stratégie. La stratégie spécifie que l'utilisateur doit créer un dossier dans le partage Drop_Zone, puis copier les fichiers qu'il souhaite dans ce dossier. Lorsque le dossier atteint 7 jours (à l'aide de CreationTime), le script PowerShell le supprime.

J'ai également ajouté une partie de la journalisation au script powershell afin que nous puissions vérifier son fonctionnement et activer les clichés instantanés juste pour sauver les complètement incompétents d'eux-mêmes.

Voici le script sans tous les trucs de journalisation.

$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
  }
}
murisonc
la source
1
Cela semble plus simple, ne fausse pas le tampon de date / heure du fichier, les flux de données alternatifs ou ne nécessite pas une liste de fichiers et leurs dates de suppression. J'allais créer un script génial qui faisait toutes sortes de magie, mais j'ai vu ça.
BeowulfNode42
et ne nécessite pas un événement de surveillance du système de fichiers déclenchant le script tout le temps, car il peut être exécuté une fois par jour, et peu importe si une journée est manquée pour une raison quelconque.
BeowulfNode42
2
Grande idée simple, tout comme @ BeowulfNode42 l'a souligné. Pour garantir que les utilisateurs doivent créer un dossier, une simple ACL "Créer des fichiers / écrire des données" dans "Ce dossier uniquement" garantira que les utilisateurs doivent également créer des sous-dossiers.
Brett G
3

Si vous pouvez supposer NTFS, vous pouvez écrire une clé (Guid) dans un autre flux du fichier. Plus la date, vous pouvez donc stocker la base de données dans les fichiers.

Plus d'informations peuvent être trouvées sur

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

Fondamentalement, vous pouvez stocker du contenu supplémentaire dans un flux distinct codé par un nom spécial.

TomTom
la source
Comment ferait-on cela?
Brett G
@BrettG Ajout d'un lien vers la documentation. "NTFS Alternate Data Stream" vous aurait fait le trouver aussi dans google, juste au cas où - vous ne connaissez pas google.
TomTom
Désolé, je sais ce que sont les flux de données alternatifs, j'essayais simplement de comprendre leur utilisation dans ce contexte. Donc, vous dites qu'au lieu d'utiliser un hachage ou quelque chose, utilisez un GUID (et / ou une date) dans le flux de données alternatif afin de suivre les fichiers .. aha.
Brett G
Ouais. Si vous pouvez MARQUER un fichier de manière fiable - vous pouvez même y mettre la date de marquage - alors vous n'avez pas besoin de calculer un hachage.
TomTom
Faites simplement attention si un fichier est copié hors du magasin, modifié, puis recopié. Vous souhaitez ensuite redémarrer le minuteur, pour lequel un hachage pourrait être utile.
un CVn
2

Vous pouvez utiliser IO.FileSystemWatcher, qui vous permet de "surveiller" un dossier pour les nouveaux fichiers créés. Voici les pièces dont vous auriez besoin pour que cela fonctionne.

Ces variables configurent le chemin à surveiller et un filtre pour affiner les fichiers à suivre:

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

Cela définit les paramètres du dossier à surveiller et les actions à effectuer lorsque l'événement se produit. Fondamentalement, cela réinitialise le LastWriteTime sur chaque fichier tel qu'il est écrit:

$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
    }

L'événement peut être annulé si nécessaire en utilisant ceci:

Unregister-Event -SourceIdentifier FileCreated

Enfin, vous pouvez l'exécuter une fois par jour afin de nettoyer les anciens fichiers:

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

Cela devrait être tout ce dont vous avez besoin ...

Tim Ferrill
la source
Modifié cela pour définir l'attribut LastWriteTime lorsque le fichier est créé, puis l'utiliser pour supprimer des fichiers plus tard.
Tim Ferrill
1

Cela fait un moment mais j'ai mis en place une méthode relativement simple pour résoudre ce problème.

Je toucherais tous les fichiers ajoutés au répertoire de dépôt (surveillé via un utilitaire de surveillance des ressources) et définirais la dernière date de modification à la date ajoutée au dossier.

Je pourrais alors utiliser la dernière date modifiée pour purger tous les fichiers qui doivent être vieillis. Cela a également l'avantage que si quelqu'un met vraiment à jour le fichier, il réinitialisera le compte à rebours.

Tim Brigham
la source
Idée parfaite. Je ferai mes propres recherches .. mais une idée de l'utilitaire de surveillance des ressources que vous avez utilisé?
Brett G
@BrettG honnêtement c'était il y a près de 10 ans. Je ne m'en souviens pas. Tu me fais me sentir vieux. :) Si je devais le faire aujourd'hui, j'exécuterais un travail basé sur les événements d'audit du système de fichiers dans l'Observateur d'événements. L'objet FileSystemWatcher .NET est disponible via PowerShell je pense. Ce serait une autre option.
Tim Brigham
Ha, je ne savais pas que tu voulais dire si longtemps quand tu as dit "un moment". Oui, assez drôle, je regardais FileSystemWatcher. Cependant, je ne pense pas que cela fonctionnerait avec des fichiers déplacés / copiés. Merci pour la réponse!
Brett G
1
@BrettG - Filesystemwatcher peut être utilisé conjointement avec une table de suivi, mais il a ses propres problèmes. Voir ici: stackoverflow.com/questions/1764809/… stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP
1
@BrettG - De plus, cela est une bonne extension FSW: codeproject.com/Articles/58740/...
JohnP
1

Il n'y a aucun moyen de se fier aux dates auxquelles un fichier a été copié ou déplacé dans un dossier. Windows parvient à le conserver sur les systèmes de fichiers, les lecteurs, les partages réseau, etc. Vous pouvez peut-être travailler avec un serveur de fichiers Linux ou empêcher les gens de copier directement des fichiers à l'aide de FTP ou d'un système de téléchargement basé sur le Web.

Si vous êtes d'accord avec les personnes ne pouvant pas modifier les fichiers après leur téléchargement, vous pouvez avoir des dossiers de téléchargement et d'accès séparés, et un script qui déplace les fichiers entre eux et les remodèle. Mais il semble que vous souhaitiez que les utilisateurs puissent modifier directement les fichiers.

Donc, une solution simple, quoique quelque peu hacky, serait de jouer avec les dates. J'écrirais deux scripts:

Script de changement de date horaire

Faites exécuter un script environ une fois par heure, dans votre langue préférée, qui:

  • Recherche tout fichier dont la date a été modifiée au cours des 20 dernières années.
  • Lorsqu'il trouve un tel fichier, changez sa date de modification à aujourd'hui moins 20 ans.

En PowerShell, cela ressemblerait à ceci:

$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
    }
}

L'exécution de ce script aujourd'hui (27 mai) définit la date de modification de tous les fichiers au 1er juin 1994 - il y a exactement 356 * 20 jours. Parce qu'il ne modifie que les fichiers plus récents que la valeur $ before, il ne touchera pas les fichiers qu'il a déjà définis dans le passé.

Script de nettoyage

Le script de nettoyage s'exécuterait tous les soirs et:

  • Rechercher des fichiers dont la date a été modifiée "il y a 20 ans et X jours"
  • Supprime-les

Je n'écrirai pas le script de cette partie - il existe de nombreux utilitaires qui peuvent gérer la suppression de fichiers plus anciens qu'une date spécifiée, choisissez celui que vous aimez. La partie importante est de rechercher les fichiers qui ont plus de 7300 jours X, où X est le nombre de jours que vous souhaitez les conserver depuis leur dernière modification.

Les avantages

Cela présente quelques avantages par rapport aux autres réponses ici:

  • Le minuteur se réinitialise si quelqu'un modifie le fichier.
  • Pas besoin de flux alternatifs NTFS pour marquer les fichiers (qui sont conservés lors du déplacement du fichier, ce qui pourrait entraîner la suppression prématurée d'un fichier modifié)
  • Doit avoir un impact minimal ou nul sur les performances. Pas besoin de conserver une base de données ou une liste de noms de fichiers et / ou de hachages.
  • Rien ne se brise horriblement si les scripts ne s'exécutent pas. Aucun service ou programme en cours d'exécution n'est nécessaire pour mettre à jour la date. Juste quelques tâches planifiées. Les solutions qui reposent sur la recherche de nouveaux fichiers et la mise à jour de leur dernière heure de modification à l'heure actuelle pourraient finir par supprimer de nouveaux fichiers si le service échoue ou se trouve dans une condition de concurrence critique.

Le seul problème que je peux voir est que les gens copient un fichier modifié pour la dernière fois il y a 20 ans dans le dossier de dépôt. Je pense que dans la plupart des scénarios, ce n'est probablement pas un gros problème, mais cela pourrait se produire.

Subvention
la source
0

Vous pouvez formaliser l'ajout de fichiers à la boîte de dépôt via une page Web, qui a un IFRAME "upload". L'utilisateur pourrait alors "publier" le fichier, qui invoque un travail PHP / ASP sur le serveur, qui prend le fichier et le place à l'emplacement du pucker. Le PHP / ASP pourrait effectuer n'importe quel nombre d'opérations d'indexation / d'analyse.

Simon Catlin
la source
0

Si quelqu'un copie ou déplace des fichiers ici, j'aimerais que l'horloge commence à tourner à ce stade. Cependant, la dernière date de modification et la date de création d'un fichier ne seront pas mises à jour à moins que quelqu'un ne modifie réellement le fichier.

Je voudrais créer un script qui s'exécute en tant que tâches planifiées toutes les cinq minutes et fait deux choses.

  1. La première action consiste à faire une copie de tout fichier copié dans le dossier, à mettre un préfixe sur le fichier et à supprimer l'original. Cela garantirait que la date de création du fichier était uniforme pour l'application.
  2. La deuxième action consisterait à regarder tous les fichiers avec le préfixe prédéterminé (défini avec l'action 1) et à supprimer tous ceux dont la date de création est antérieure à X jours. Cela résoudrait le problème de modification / date d'accès.
user1914368
la source
0

Il existe un mécanisme existant pour marquer les fichiers, le bit d'archive. Il existe depuis les premiers jours de DOS et est présent sur FAT et NTFS.

Fondamentalement, chaque fichier aura son bit d'archivage défini par défaut. Si vous voyez un fichier avec le bit d'archive dans votre dossier de dépôt, (1) effacez ce bit et (2) définissez sa date sur aujourd'hui. Si vous voyez un fichier sans ce bit et avec une date <= 7 jours dans le passé, supprimez-le.

Si un utilisateur écrit dans le fichier alors qu'il se trouve dans le dossier de dépôt, son bit d'archivage est à nouveau défini de sorte que sa durée de vie est également réinitialisée à 7 jours. Il s'agit en fait d'un nouveau fichier, après tout.

Vous pouvez désormais utiliser FileSystemWatcher en toute sécurité. Tous les problèmes rencontrés (tels que les événements en double, le débordement de la mémoire tampon et la perte d'informations détaillées) n'ont plus d'importance car les informations pertinentes figurent toutes dans les métadonnées du fichier.

MSalters
la source