Видаліть файли старше 15 днів за допомогою PowerShell


186

Я хотів би видалити лише ті файли, які були створені більше 15 днів тому в певній папці. Як я можу це зробити за допомогою PowerShell?


5
Більшість відповідей використовують CreationTime, однак він скидається, коли файл копіюється, щоб ви могли не отримати потрібних результатів. LastWriteTime - це те, що відповідає "Дата зміни" в Провіднику Windows.
Roland Schaer

Відповіді:


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
Дякуємо, що не використовуєте псевдоніми. Для того, хто не знайомий із владою і знайшов цю публікацію за допомогою пошуку в Google, я вважаю вашу відповідь найкращою.
Джефф Дауді

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

6
Якщо файли можуть бути використані, також варто додати "-ErrorAction SilentlyContinue" до команди RemoveItem.
Кевін Оуен

17
Дякую! Я використовую $ _. LastwriteTime замість $ _. CreationTime
Lauri Lubi

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занадто багато, ні? Перелік реєстру є рекурсивним, вилучення пункту не повинно бути включеним для дітей, правда?
Joost

Якщо в каталозі, з яким ви працюєте, є два каталоги глибокі, потрібен другий повтор.
Брайан С.

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. набирається в [часовий проміжок] автоматично):

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

Крім того, він ніколи не дістанеться до іншого твердження, тому що якщо $Filesвін порожній, він не вводить оператор foreach . Ви повинні розмістити передбачення у виписці if .
Дітер

@mati насправді це може дійти до іншого твердження. У нас є подібний цикл на основі списку файлів, і він регулярно вводить цикл for за допомогою змінної $ File як null
BeowulfNode42,

Я здогадуюсь так - просто наткнувся на той самий сценарій тут; networknet.nl/apps/wp/published/…
Shawson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.