Scade i file in una cartella: elimina i file dopo x giorni


12

Sto cercando di creare una "cartella di rilascio" in un'unità condivisa di Windows accessibile a tutti. Vorrei che i file vengano eliminati automaticamente se rimangono nella cartella per più di X giorni.

Tuttavia, sembra che tutti i metodi che ho trovato per fare questo, utilizzare la data dell'ultima modifica, l'ora dell'ultimo accesso o la data di creazione di un file.

Sto cercando di rendere questa una cartella in cui un utente può rilasciare i file per condividerli con qualcuno. Se qualcuno copia o sposta i file qui, mi piacerebbe che l'orologio iniziasse a ticchettare a questo punto. Tuttavia, la data dell'ultima modifica e la data di creazione di un file non verranno aggiornate a meno che qualcuno non modifichi effettivamente il file. L'ultimo orario di accesso viene aggiornato troppo frequentemente ... sembra che solo l'apertura di una directory in Windows Explorer aggiornerà l'ora dell'ultimo accesso.

Qualcuno sa di una soluzione a questo? Sto pensando che catalogare l'hash dei file su base giornaliera e quindi scadere i file in base a hash più vecchi di una certa data potrebbe essere una soluzione .... ma prendere hash di file può richiedere molto tempo.

Qualsiasi idea sarebbe molto apprezzata!

Nota:
ho già esaminato molte risposte qui ... ho esaminato Monitoraggio risorse file server, script PowerShell, script batch, ecc. Usano ancora l'ora dell'ultimo accesso, l'ora dell'ultima modifica o l'ora della creazione ... che, come descritto, non soddisfano le esigenze di cui sopra.


Una domanda, come menzionato da @Michael Kjorling, il timer smette di contare se il file viene modificato dopo essere stato eliminato nella casella?
Get-HomeByFiveOClock

Quello che stai cercando è l'equivalente di Windows tmpwatch.
Avery Payne,

Risposte:


5

Abbiamo usato una combinazione di uno script PowerShell e una politica. La politica specifica che l'utente deve creare una cartella all'interno della condivisione Drop_Zone e quindi copiare tutti i file che desidera in quella cartella. Quando la cartella avrà 7 giorni (usando CreationTime) lo script PowerShell la cancellerà.

Ho anche aggiunto un po 'di registrazione allo script PowerShell in modo da poter verificare il suo funzionamento e attivare le copie shadow solo per salvare completamente inetti da loro stessi.

Ecco lo script senza tutte le cose di registrazione.

$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
Questo sembra più semplice, non confonde con il timbro datetime del file, flussi di dati alternativi o richiede un elenco di file e le relative date di rilascio. Stavo per creare una sceneggiatura fantastica che faceva tutti i tipi di magia, ma poi ho visto questo.
BeowulfNode42,

e non richiede un evento di controllo del file system che attiva continuamente lo script, poiché può essere eseguito una volta al giorno e non importa molto se un giorno viene perso per qualsiasi motivo.
BeowulfNode42,

2
Ottima idea semplice, proprio come ha sottolineato @ BeowulfNode42. Per garantire che gli utenti debbano creare una cartella, un semplice "Nega" di "Crea file / Scrivi dati" ACL in "Solo questa cartella" garantirà che anche gli utenti debbano creare sottocartelle.
Brett G,

3

Se puoi assumere NTFS puoi scrivere una chiave (Guid) in un flusso alternativo del file. Più la data, quindi puoi praticamente archiviare il database nei file.

Ulteriori informazioni sono disponibili all'indirizzo

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

Fondamentalmente è possibile archiviare contenuti aggiuntivi in ​​un flusso separato codificato da un nome speciale.


Come si farebbe questo?
Brett G,

@BrettG Aggiunto link alla documentazione. "Flusso di dati alternativi NTFS" ti avrebbe fatto trovare anche su Google, per ogni evenienza: non conosci Google.
TomTom,

Spiacente, so quali flussi di dati alternativi sono, stavo solo cercando di capire il loro utilizzo in questo contesto. Quindi stai dicendo invece di usare un hash o qualcosa del genere, usa un GUID (e / o data) nel flusso di dati alternativo per tenere traccia dei file .. aha.
Brett G,

Si. Se è possibile CONTROLLARE in modo affidabile un file, è anche possibile inserire la data di marcatura, non è necessario calcolare un hash.
TomTom,

Fai solo attenzione se un file viene copiato fuori dal negozio, modificato e quindi copiato nuovamente. Quindi si desidera riavviare il timer, per cui un hash potrebbe essere utile.
un CVn

2

È possibile utilizzare IO.FileSystemWatcher, che consente di "guardare" una cartella per i nuovi file creati. Ecco i pezzi che ti serviranno per farlo funzionare.

Queste variabili configurano il percorso da guardare e un filtro per mettere a punto quali file tenere traccia:

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

Questo imposta i parametri per la cartella da guardare e le azioni da eseguire quando si verifica l'evento. Fondamentalmente questo reimposta LastWriteTime su ogni file mentre è scritto:

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

Se necessario, è possibile annullare la registrazione dell'evento utilizzando questo:

Unregister-Event -SourceIdentifier FileCreated

Infine, puoi eseguirlo una volta al giorno per ripulire i vecchi file:

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

Dovrebbe essere tutto ciò di cui hai bisogno ...


Modificato questo per impostare l'attributo LastWriteTime quando viene creato il file e quindi utilizzarlo per eliminare i file in un secondo momento.
Tim Ferrill,

1

È passato un po 'di tempo, ma ho impostato un metodo relativamente semplice per affrontare questo problema.

Vorrei toccare qualsiasi file aggiunto alla directory di rilascio (monitorato tramite un'utilità di monitoraggio delle risorse) e impostare l'ultima data modificata sulla data aggiunta alla cartella.

Potrei quindi utilizzare la data dell'ultima modifica per eliminare tutti i file che devono essere obsoleti. Questo ha anche il vantaggio che se qualcuno aggiorna davvero il file ripristinerà il conto alla rovescia.


Idea perfetta. Farò le mie ricerche ... ma hai idea di quale utilità di monitoraggio delle risorse hai usato?
Brett G,

@BrettG onestamente era quasi 10 anni fa. Non ricordo. Mi stai facendo sentire vecchio. :) Se dovessi farlo oggi, eseguirei un lavoro basato sugli eventi di controllo del file system nel Visualizzatore eventi. L'oggetto FileSystemWatcher .NET è disponibile tramite PowerShell credo. Sarebbe un'altra opzione.
Tim Brigham,

Ah, non avevo capito che intendevi tanto tempo quando dicevi "un po '". Sì, abbastanza divertente, stavo solo guardando FileSystemWatcher. Anche se, non penso che funzionerebbe con i file spostati / copiati. Grazie per la risposta!
Brett G,

1
@BrettG - Filesystemwatcher può essere utilizzato insieme a una tabella di tracciamento, ma ha i suoi problemi. Vedi qui: stackoverflow.com/questions/1764809/... stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP

1
@BrettG - Inoltre, questa è una buona estensione di FSW: codeproject.com/Articles/58740/…
JohnP,

1

Non è possibile fare affidamento sulle date in cui un file è stato copiato o spostato in una cartella. Windows riesce a preservarlo attraverso filesystem, unità, condivisioni di rete, ecc. Potresti essere in grado di elaborare qualcosa con un file server linux o impedire alle persone di copiare direttamente i file utilizzando FTP o un sistema di upload basato sul web.

Se sei d'accordo con le persone che non sono in grado di modificare i file dopo il caricamento, potresti avere cartelle di accesso e caricamento separate e uno script che sposta i file tra di loro e li aggiorna. Ma sembra che tu voglia che le persone siano in grado di modificare direttamente i file.

Quindi una soluzione semplice, anche se un po 'confusa, sarebbe quella di pasticciare con le date. Scriverei due script:

Script di modifica della data oraria

Fai eseguire uno script all'incirca una volta all'ora, nella tua lingua preferita, che:

  • Cerca qualsiasi file con una data modificata negli ultimi 20 anni.
  • Quando trova un file del genere, cambia la sua data modificata oggi meno 20 anni.

In PowerShell, sarebbe simile a questo:

$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'esecuzione di questo script oggi (27 maggio), imposta la data modificata di tutti i file al 1 ° giugno 1994, esattamente 356 * 20 giorni fa. Poiché sta cambiando solo i file più recenti del valore $ before, non toccherà i file che ha già impostato sul passato.

Script di pulizia

Lo script di pulizia verrà eseguito ogni notte e:

  • Cerca file con data modificata "20 anni e X giorni fa"
  • Eliminali

Non scriverò lo script per questa parte - ci sono molte utility in grado di gestire la cancellazione di file più vecchi di una data specificata, scegli quello che preferisci. La parte importante è cercare i file che hanno 7300 + X giorni, dove X è il numero di giorni che vuoi conservare dall'ultima modifica.

vantaggi

Questo ha alcuni vantaggi rispetto alle altre risposte qui:

  • Il timer si reimposterà se qualcuno modifica il file.
  • Non sono necessari flussi alternativi NTFS per contrassegnare i file (che vengono conservati quando si sposta il file, quindi potrebbe causare la cancellazione prematura di un file modificato)
  • Dovrebbe avere un impatto minimo sulle prestazioni. Non è necessario conservare un database o un elenco di nomi di file e / o hash.
  • Nulla si rompe in modo orribile se gli script non vengono eseguiti. Non è necessario alcun servizio o programma in esecuzione costante per aggiornare la data. Solo un paio di attività programmate. Le soluzioni che fanno affidamento sulla ricerca di nuovi file e sull'aggiornamento dell'ultimo tempo modificato in questo momento potrebbero finire con l'eliminazione di nuovi file se il servizio fallisce o si verifica una condizione di competizione.

L'unico problema che posso vedere è se le persone copiano un file che è stato modificato l'ultima volta 20 anni fa nella cartella di rilascio. Penso che nella maggior parte degli scenari, è improbabile che ciò costituisca un grosso problema, ma potrebbe presentarsi.


0

È possibile formalizzare l'aggiunta di file nella casella a discesa attraverso una pagina Web, che ha un "upload" IFRAME. L'utente può quindi "pubblicare" il file, che richiama un lavoro PHP / ASP sul server, che prende il file e lo posiziona nella posizione del pucker. PHP / ASP potrebbe eseguire qualsiasi numero di operazioni di indice / analisi.


0

Se qualcuno copia o sposta i file qui, mi piacerebbe che l'orologio iniziasse a ticchettare a questo punto. Tuttavia, la data dell'ultima modifica e la data di creazione di un file non verranno aggiornate a meno che qualcuno non modifichi effettivamente il file.

Vorrei creare uno script che viene eseguito come attività pianificate ogni cinque minuti e fa due cose.

  1. La prima azione farebbe una copia di qualsiasi file copiato nella cartella, mettere un prefisso sul file ed eliminare l'originale. Ciò garantirebbe che la data di creazione del file fosse uniforme per l'applicazione.
  2. La seconda azione esaminerebbe tutti i file con il prefisso predeterminato (impostato con l'azione 1) ed eliminerebbe quelli con una data di creazione più vecchia di X giorni. Ciò risolverebbe il problema di modifica / data di accesso.

0

Esiste un meccanismo esistente per contrassegnare i file, il bit Archive. È presente fin dai primi giorni di DOS ed è presente sia su FAT che su NTFS.

Fondamentalmente, ogni file avrà il suo bit di archivio impostato per impostazione predefinita. Se vedi un file con il bit di archivio nella cartella di rilascio, (1) cancella quel bit e (2) imposta la data su oggi. Se vedi un file senza quel bit e con una data <= 7 giorni nel passato, eliminalo.

Se un utente scrive nel file mentre si trova nella cartella di rilascio, il suo bit di archivio viene reimpostato in modo che anche la sua durata venga ripristinata a 7 giorni. È in effetti un nuovo file, dopo tutto.

Ora puoi usare tranquillamente FileSystemWatcher. Eventuali problemi (come eventi duplicati, overflow del buffer che perdono informazioni dettagliate) non contano più poiché le informazioni pertinenti sono tutte contenute nei metadati del file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.