Удалите файлы старше 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.