Excluir arquivos com mais de 15 dias usando o PowerShell

186

Gostaria de excluir apenas os arquivos criados mais de 15 dias atrás em uma pasta específica. Como eu poderia fazer isso usando o PowerShell?

user2470170
fonte
5
A maioria das respostas usa o CreationTime, no entanto, ela é redefinida quando um arquivo é copiado, portanto você pode não obter os resultados desejados. LastWriteTime é o que corresponde à "Data da modificação" no Windows Explorer.
Roland Schaer

Respostas:

308

As respostas fornecidas apenas excluirão arquivos (que é o que está no título desta postagem), mas aqui está um código que primeiro excluirá todos os arquivos anteriores a 15 dias e, em seguida, excluirá recursivamente todos os diretórios vazios que possam ter sido deixados atrás. Meu código também usa a -Forceopção de excluir arquivos ocultos e somente leitura. Além disso, optei por não usar aliases como o OP é novo para PowerShell e não pode entender o que gci, ?, %, etc, são.

$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

E, claro, se você deseja ver quais arquivos / pastas serão excluídos antes de excluí-los, basta adicionar a -WhatIfopção à Remove-Itemchamada de cmdlet no final das duas linhas.

O código mostrado aqui é compatível com o PowerShell v2.0, mas também mostro esse código e o código mais rápido do PowerShell v3.0 como funções reutilizáveis ​​úteis no meu blog .

cão mortal
fonte
22
Obrigado por não usar o pseudônimo. Para alguém que é novo no PowerShell e encontrou esta postagem através de uma pesquisa no Google, considero sua resposta a melhor.
Geoff Dawdy 22/10
1
Eu tentei a sugestão do @ deadlydog e não importa se eu especifico -15 ou -35 com datas de criação de arquivo variadas, meses atrás (ou recentes), ele está excluindo todo o conteúdo do diretório.
Michele
6
Se os arquivos estiverem em uso, também vale a pena adicionar "-ErrorAction SilentlyContinue" ao comando RemoveItem.
Kevin Owen
17
Obrigado! Eu uso $ _. LastwriteTime em vez de $ _. CreationTime
Lauri Lubi
2
O segundo comando nesse script sempre obtém um erro que Get-ChildItem não pode encontrar parte do caminho. Ele obtém uma exceção de diretório não encontrado. No entanto, exclui as pastas vazias sem problemas. Não sei por que está recebendo um erro, apesar de funcionar.
Nathan McKaskle
51

simplesmente (PowerShell V5)

Get-ChildItem "C:\temp" -Recurse -File | Where CreationTime -lt  (Get-Date).AddDays(-15)  | Remove-Item -Force
Esperento57
fonte
16

Outra maneira é subtrair 15 dias da data atual e comparar CreationTimecom esse valor:

$root  = 'C:\root\folder'
$limit = (Get-Date).AddDays(-15)

Get-ChildItem $root -Recurse | ? {
  -not $_.PSIsContainer -and $_.CreationTime -lt $limit
} | Remove-Item
Ansgar Wiechers
fonte
13

Basicamente, você repete os arquivos no caminho especificado, subtrai o CreationTimearquivo de cada arquivo encontrado a partir do horário atual e compara com a Dayspropriedade do resultado. A -WhatIfopção informará o que acontecerá sem excluir os arquivos (quais arquivos serão excluídos); remova a opção para excluir os arquivos:

$old = 15
$now = Get-Date

Get-ChildItem $path -Recurse |
Where-Object {-not $_.PSIsContainer -and $now.Subtract($_.CreationTime).Days -gt $old } |
Remove-Item -WhatIf
Shay Levy
fonte
8

Tente o seguinte:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force
Roland Jansen
fonte
Eu acredito que o último -recurseé demais, não? A listagem de diretórios é recursiva; a exclusão do item não deve ser feita com crianças incluídas, certo?
Joost
Se o diretório com o qual você estiver trabalhando tiver dois diretórios, será necessária uma segunda -recurso.
Bryan S.
5

O script do Esperento57 não funciona nas versões mais antigas do PowerShell. Este exemplo faz:

Get-ChildItem -Path "C:\temp" -Recurse -force -ErrorAction SilentlyContinue | where {($_.LastwriteTime -lt  (Get-Date).AddDays(-15) ) -and (! $_.PSIsContainer)} | select name| Remove-Item -Verbose -Force -Recurse -ErrorAction SilentlyContinue
KERR
fonte
1
Atualizei minha resposta para excluir diretórios agora, obrigado.
KERR
3

Outra alternativa (15. é digitada em [timespan] automaticamente):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose
js2010
fonte
1
$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Recurse

Isso excluirá pastas antigas e seu conteúdo.

Aigar
fonte
0

Se você estiver tendo problemas com os exemplos acima em uma caixa do Windows 10, tente substituir .CreationTimepor .LastwriteTime. Isso funcionou para mim.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force
Jeff Blumenthal
fonte
LastwriteTimenão é o mesmo que CreationTime, LastwriteTimeé atualizado sempre que o arquivo é modificado.
MisterSmith 8/02/19
-1
#----- Define parameters -----#
#----- Get current date ----#
$Now = Get-Date
$Days = "15" #----- define amount of days ----#
$Targetfolder = "C:\Logs" #----- define folder where files are located ----#
$Extension = "*.log" #----- define extension ----#
$Lastwrite = $Now.AddDays(-$Days)

#----- Get files based on lastwrite filter and specified folder ---#
$Files = Get-Children $Targetfolder -include $Extension -Recurse | where {$_.LastwriteTime -le "$Lastwrite"}

foreach ($File in $Files)
{
    if ($File -ne $Null)
    {
        write-host "Deleting File $File" backgroundcolor "DarkRed"
        Remove-item $File.Fullname | out-null
    }
    else
        write-host "No more files to delete" -forgroundcolor "Green"
    }
}
Ikruzzz
fonte
Além disso, nunca alcançará a instrução else , porque se $Filesestiver vazio, não entrará na instrução foreach . Você deve colocar o foreach na instrução if .
Dieter
@mati, na verdade, pode chegar à declaração else. Temos um semelhante para o laço baseado em uma lista de arquivos e entra regularmente o loop com a variável $ File como nula
BeowulfNode42
Eu acho que sim - apenas tropeçou no mesmo script aqui; networknet.nl/apps/wp/published/…
Shawson 04/04