Удалите файлы старше 15 дней с помощью PowerShell


186

Я хотел бы удалить только те файлы, которые были созданы более 15 дней назад в определенной папке. Как я могу сделать это с помощью PowerShell?


5
В большинстве ответов используется CreationTime, однако он сбрасывается при копировании файла, поэтому вы можете не получить желаемых результатов. LastWriteTime - это то, что соответствует дате изменения в проводнике Windows.
— Роланд Шаер

Ответы:


308

Приведенные ответы будут удалять только файлы (что, как известно, содержится в заголовке этого поста), но вот некоторый код, который сначала удалит все файлы старше 15 дней, а затем рекурсивно удалит все пустые каталоги, которые могли остаться позади. Мой код также использует -Forceопцию для удаления скрытых файлов и файлов только для чтения. Кроме того , я решил не использовать псевдонимы , как OP является новым для PowerShell и не могу понять , что gci, ?, %и т.д. есть.

$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

И, конечно, если вы хотите увидеть, какие файлы / папки будут удалены перед их фактическим удалением, вы можете просто добавить -WhatIfпереключатель к Remove-Itemвызову командлета в конце обеих строк.

Показанный здесь код совместим с PowerShell v2.0, но я также показываю этот код и более быстрый код PowerShell v3.0 в качестве удобных функций многократного использования в моем блоге .


22
Спасибо, что не используете псевдонимы. Если вы новичок в powershell и нашли этот пост в поиске Google, я считаю ваш ответ лучшим.
— Джефф Доуди

1
Я попробовал предложение @ deadlydog и, независимо от того, указал ли я -15 или -35 с разными датами создания файла, начиная с месяцев (или последних), он удаляет все содержимое каталога.
— Мишель

6
Если файлы могут использоваться, также стоит добавить «-ErrorAction SilentlyContinue» в команду RemoveItem.
— Кевин Оуэн

17
Спасибо! Я использую $ _. LastwriteTime вместо $ _. CreationTime
— Лаури Луби

2
Вторая команда в этом скрипте всегда получает ошибку, что Get-ChildItem не может найти часть пути. Он получает каталог не найден исключение. Тем не менее, он удаляет пустые папки без проблем. Не уверен, почему он получает ошибку, несмотря на работу.
— Натан МакКаскл

51

просто (PowerShell V5)

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

16

Другой способ - вычесть 15 дней из текущей даты и сравнить CreationTimeс этим значением:

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

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

13

По сути, вы перебираете файлы по заданному пути, вычитаете CreationTimeиз каждого найденного файла текущее время и сравниваете его со Daysсвойством результата. -WhatIfВыключатель будет сказать вам , что будет происходить без удаления файлов (какие файлы будут удалены), снимите переключатель на самом деле удалить файлы:

$old = 15
$now = Get-Date

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

8

Попробуй это:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force

Я считаю, что последнее -recurseслишком много, нет? Список dir рекурсивно, удаление элемента не должно быть с включенными childs, верно?
— Joost

Если каталог, с которым вы работаете, - это два глубоких каталога, необходим второй -recurse.
— Брайан С.

5

Сценарий Esperento57 не работает в старых версиях PowerShell. Этот пример делает:

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

1
Я обновил свой ответ, чтобы исключить каталоги, спасибо.
— KERR

3

Другой вариант (15. автоматически набирается на [timespan]):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose

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

Это удалит старые папки и его содержимое.


0

Если у вас возникли проблемы с приведенными выше примерами на Windows 10, попробуйте заменить .CreationTimeна .LastwriteTime. Это сработало для меня.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force

LastwriteTimeэто не то же самое CreationTime, LastwriteTimeобновляется каждый раз, когда файл изменяется.
— MisterSmith

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

Кроме того, он никогда не достигнет оператора else , потому что если $Filesон пуст, он не будет входить в оператор foreach . Вы должны поместить foreach в операторе if .
— Дитер

@mati на самом деле это может достигнуть оператора else. У нас есть аналогичный цикл for, основанный на списке файлов, и он регулярно входит в цикл for с переменной $ File как null
— BeowulfNode42

Я предполагаю, что так - просто наткнулся на тот же сценарий здесь; networknet.nl/apps/wp/published/…
— Шоусон,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.