Expirar arquivos em uma pasta: Excluir arquivos após x dias


12

Estou procurando fazer uma "Drop Folder" em uma unidade compartilhada do Windows que seja acessível a todos. Eu gostaria que os arquivos fossem excluídos automaticamente se eles permanecerem na pasta por mais de X dias.

No entanto, parece que todos os métodos que encontrei para fazer isso usam a data da última modificação, a hora do último acesso ou a data de criação de um arquivo.

Estou tentando fazer desta uma pasta que um usuário possa soltar arquivos para compartilhar com alguém. Se alguém copiar ou mover arquivos para aqui, eu gostaria que o relógio começasse a marcar neste momento. No entanto, a data da última modificação e a data de criação de um arquivo não serão atualizadas, a menos que alguém realmente o modifique. O último horário de acesso é atualizado com muita frequência ... parece que apenas a abertura de um diretório no Windows Explorer atualizará o último horário de acesso.

Alguém sabe de uma solução para isso? Estou pensando que catalogar o hash de arquivos diariamente e, em seguida, expirar os arquivos com base em hashes mais antigos que uma determinada data pode ser uma solução ... mas tirar hashes de arquivos pode ser demorado.

Todas as idéias seriam muito apreciadas!

Nota:
Eu já procurei muitas respostas aqui ... procurei no File Server Resource Monitor, scripts de PowerShell, scripts em lote, etc. Eles ainda usam o último horário de acesso, o horário da última modificação ou o tempo de criação ... que, conforme descrito, não atendem às necessidades acima.


Uma pergunta, como mencionado por @Michael Kjorling, o cronômetro para de contar se o arquivo for modificado após ser descartado na caixa?
Get-HomeByFiveOClock

O que você está procurando é o equivalente do Windows tmpwatch.
Avery Payne

Respostas:


5

Usamos uma combinação de um script do PowerShell e uma política. A política especifica que o usuário deve criar uma pasta dentro do compartilhamento Drop_Zone e, em seguida, copiar os arquivos desejados para essa pasta. Quando a pasta chegar aos 7 dias (usando CreationTime), o script do PowerShell a excluirá.

Também adicionei alguns logs ao script do PowerShell para que pudéssemos verificar sua operação e ativamos as cópias de sombra apenas para salvar os completamente ineptos deles mesmos.

Aqui está o script sem todo o material de log.

$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
Isso parece mais simples, não modifica o carimbo de data e hora do arquivo, fluxos de dados alternativos ou requer alguma lista de arquivos e suas datas de lançamento. Eu estava indo para criar um roteiro incrível que fazia todo tipo de mágica, mas então eu vi isso.
BeowulfNode42

e não requer um evento de observação do sistema de arquivos acionando o script o tempo todo, pois ele pode ser executado uma vez por dia e não importa muito se um dia é perdido por qualquer motivo.
BeowulfNode42

2
Ótima idéia simples, como @ BeowulfNode42 apontou. Para garantir que os usuários criem uma pasta, um simples "Negar" da ACL "Criar arquivos / gravar dados" para "Somente esta pasta" garantirá que os usuários também criem subpastas.
Brett G

3

Se você puder assumir o NTFS, poderá escrever uma chave (Guid) em um fluxo alternativo do arquivo. Além da data, você pode basicamente armazenar o banco de dados nos arquivos.

Mais informações podem ser encontradas em

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

Basicamente, você pode armazenar conteúdo adicional em um fluxo separado codificado por um nome especial.


Como alguém faria isso?
Brett G

@BrettG Adicionado link para a documentação. "NTFS Alternate Data Stream" teria feito você encontrá-lo também no google, por precaução - você não conhece o google.
TomTom

Desculpe, eu sei o que são fluxos de dados alternativos, só estava tentando entender o uso deles nesse contexto. Então, você está dizendo que, em vez de usar um hash ou algo assim, use um GUID (e / ou data) no fluxo de dados alternativo para rastrear os arquivos ... aha.
Brett G

Sim. Se você pode MARCAR um arquivo de maneira confiável - você pode até colocar a data da marcação -, não é necessário calcular um hash.
TomTom

Apenas observe se um arquivo é copiado para fora da loja, editado e depois copiado novamente. Você deseja reiniciar o cronômetro, para o qual um hash pode ser útil.
um CVn

2

Você pode usar o IO.FileSystemWatcher, que permite "vigiar" uma pasta para novos arquivos criados. Aqui estão as peças que você precisa para fazer isso funcionar.

Essas variáveis ​​configuram o caminho a ser observado e um filtro para ajustar quais arquivos rastrear:

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

Isso configura os parâmetros para a pasta a ser observada e as ações a serem executadas quando o evento ocorrer. Basicamente, isso redefine o LastWriteTime em cada arquivo conforme está escrito:

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

O evento pode não ser registrado, se necessário, usando este:

Unregister-Event -SourceIdentifier FileCreated

Por fim, você pode executá-lo uma vez por dia para limpar os arquivos antigos:

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

Isso deve ser tudo o que você precisa ...


Editou isso para definir o atributo LastWriteTime quando o arquivo é criado e, em seguida, use-o para excluir os arquivos posteriormente.
Tim Ferrill

1

Já faz um tempo, mas eu configurei um método relativamente direto para resolver isso.

Eu tocava em qualquer arquivo adicionado ao diretório suspenso (monitorado por meio de um utilitário de monitoramento de recursos) e definia a data da última modificação para a data adicionada à pasta.

Eu poderia então usar a data da última modificação para limpar todos os arquivos que precisam ser envelhecidos. Isso também tem a vantagem de que, se alguém realmente atualizar o arquivo, redefinirá a contagem regressiva.


Idéia perfeita. Eu farei minha própria pesquisa .. mas alguma idéia de qual utilitário de monitoramento de recursos você usou?
Brett G

@BrettG honestamente, foi há quase 10 anos. Não me lembro. Você está me fazendo sentir velha. :) Se eu fizesse hoje, executaria um trabalho com base nos eventos de auditoria do sistema de arquivos no visualizador de eventos. O objeto FileSystemWatcher .NET está disponível no PowerShell, eu acho. Seria outra opção.
Tim Brigham

Ha, eu não percebi que você quis dizer tanto tempo quando disse "um tempo". É engraçado o suficiente, eu estava apenas olhando para o FileSystemWatcher. Embora eu não ache que funcione com arquivos movidos / copiados. Obrigado pela resposta!
Brett G

1
@BrettG - O Filesystemwatcher pode ser usado em conjunto com uma tabela de rastreamento, mas tem seus próprios problemas. Veja aqui: stackoverflow.com/questions/1764809/… stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP:

1
@BrettG - Além disso, esta é uma boa extensão para o FSW: codeproject.com/Articles/58740/…
JohnP

1

Não há como confiar nas datas de quando um arquivo foi copiado ou movido para uma pasta. O Windows consegue preservá-lo em sistemas de arquivos, unidades, compartilhamentos de rede etc. Você pode conseguir resolver algo com um servidor de arquivos linux ou impedir que as pessoas copiem arquivos diretamente usando FTP ou um sistema de upload baseado na Web.

Se você concorda com as pessoas que não conseguem modificar os arquivos após o upload, você pode ter pastas de upload e acesso separadas e um script que move os arquivos entre elas e as atualiza novamente. Mas parece que você deseja que as pessoas possam modificar os arquivos diretamente.

Portanto, uma solução simples, embora um tanto invasiva, seria mexer com as datas. Eu escreveria dois scripts:

Script de alteração de data por hora

Faça com que um script seja executado uma vez por hora, no seu idioma preferido, que:

  • Procura qualquer arquivo com uma data modificada nos últimos 20 anos.
  • Quando encontrar esse arquivo, altere sua data de modificação para hoje menos 20 anos.

No PowerShell, seria algo parecido com isto:

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

A execução desse script hoje (27 de maio) define a data de modificação de todos os arquivos para 1º de junho de 1994 - exatamente há 356 * 20 dias. Como está alterando apenas arquivos mais recentes que o valor $ before, não tocará nos arquivos que já definiu para o passado.

Script de limpeza

O script de limpeza seria executado todas as noites e:

  • Pesquise arquivos com data de modificação "há 20 anos e X dias atrás"
  • Exclua-os

Não escreverei o script para esta parte - há muitos utilitários que podem lidar com a exclusão de arquivos anteriores a uma data especificada, escolha o que desejar. A parte importante é procurar arquivos com mais de 7300 + X dias, em que X é o número de dias que você deseja mantê-los desde a última modificação.

Vantagens

Isso tem algumas vantagens sobre as outras respostas aqui:

  • O cronômetro será redefinido se alguém modificar o arquivo.
  • Não há necessidade de fluxos alternativos do NTFS para marcar os arquivos (que são preservados ao mover o arquivo, portanto, isso pode causar a exclusão prematura de um arquivo modificado)
  • Deve ter um impacto mínimo, se houver, no desempenho. Não há necessidade de manter um banco de dados ou lista de nomes de arquivos e / ou hashes.
  • Nada quebra horrivelmente se os scripts falharem na execução. Não há nenhum serviço ou programa em execução constante necessário para atualizar a data. Apenas algumas tarefas agendadas. As soluções que dependem da observação de novos arquivos e da atualização da última hora modificada para o momento podem acabar excluindo novos arquivos se o serviço falhar ou executar uma condição de corrida.

O único problema que vejo é se as pessoas copiam um arquivo modificado pela última vez há 20 anos para a pasta suspensa. Acho que, na maioria dos cenários, é pouco provável que isso seja um problema, mas pode surgir.


0

Você pode formalizar a adição de arquivos à caixa suspensa por meio de uma página da Web, que possui um IFRAME de "upload". O usuário pode então "postar" o arquivo, que chama um trabalho PHP / ASP no servidor, que pega o arquivo e o coloca no local do enrugamento. O PHP / ASP pode realizar qualquer número de operações de índice / análise.


0

Se alguém copiar ou mover arquivos para aqui, eu gostaria que o relógio começasse a marcar neste momento. No entanto, a data da última modificação e a data de criação de um arquivo não serão atualizadas, a menos que alguém realmente o modifique.

Eu criaria um script que é executado como tarefas agendadas a cada cinco minutos e faz duas coisas.

  1. A primeira ação faria uma cópia de qualquer arquivo copiado para a pasta, colocaria um prefixo no arquivo e excluiria o original. Isso garantiria que a data de criação do arquivo fosse uniforme para o aplicativo.
  2. A segunda ação examinaria todos os arquivos com o prefixo predeterminado (definido com a ação 1) e excluiria aqueles com uma data de criação anterior a X dias. Isso resolveria o problema da modificação / data de acesso.

0

Existe um mecanismo existente para marcar arquivos, o bit Archive. Está presente desde os primeiros dias do DOS e está presente no FAT e no NTFS.

Basicamente, cada arquivo terá seu bit de arquivamento definido por padrão. Se você vir um arquivo com o bit de arquivamento na pasta suspensa, (1) limpe esse bit e (2) defina sua data para hoje. Se você vir um arquivo sem esse bit e com uma data <= 7 dias no passado, exclua-o.

Se um usuário gravar no arquivo enquanto estiver na pasta suspensa, seu bit de arquivamento será definido novamente, para que sua vida útil também seja redefinida para 7 dias. Afinal, é um novo arquivo.

Agora você pode usar o FileSystemWatcher com segurança. Qualquer problema que ele tenha (como eventos duplicados, estouro de buffer que perde informações detalhadas) não importa mais, pois as informações relevantes estão todas nos metadados do arquivo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.