Как вы удаляете временные файлы? Вручную запускаете CCleaner или аналогичную программу, либо настроили ее запуск по расписанию? Я обхожусь встроенными средствами Windows, причем все сводится буквально к одной команде. Я хочу поделиться с вами двумя скриптами, которые давно служат мне верой и правдой для удаления ненужных файлов.
В Windows есть утилита для очистки диска, которую можно настроить для удаления заданных категорий файлов по расписанию. Она легко справится с очисткой временных файлов из расположений, известных системе, но не позволит удалять ненужные файлы из заданной вами папки. С помощью скриптов можно очищать не только временные файлы, но и любую папку. Например, я удаляю файлы из папок Test и Temp, которые служат для экспериментов и временного хранения файлов как в загрузках, так и документах.
В отличие от программных чистильщиков, скрипты можно гибко настроить, а регулярность выполнения очистки легко реализовать с помощью планировщика заданий Windows.
Эти скрипты позволяют удалять только файлы заданного «возраста» вместо полной очистки папки.
В статье вы найдете примеры скриптов и рассказ о том, как настроить задачу в планировщике одной командой. Вы также сможете скачать готовые файлы и создать задание для очистки папок за пару минут.
Скрипты
Вы можете воспользоваться на выбор скриптами CMD, VBS и PowerShell.
CMD
Можно использовать утилиту командной строки forfiles.exe, входящую в состав Windows 7 и новее (когда-то она входила в Windows 2000 Resource Kit). Одной командой удаляются все файлы из указанной папки и вложенных в нее.
Команда для выполнения
forfiles.exe /p %temp% /s /m *.* /d -14 /c "cmd /c del /q /f @file"
- Вместо %temp% (временной папки в профиле) подставьте свою папку (параметр /p)
- Возраст файлов по умолчанию 14 дней (параметр /d), но вы можете задать любое значение
- Можно удалять файлы определенного расширения по маске (например, /m *.log)
- За рекурсивное удаление (во вложенных папках) отвечает параметр /s
Конечно, в скрипте вы можете использовать несколько команд, каждая из которых будет удалять заданную папку. Справка по использованию утилиты вызывается командой forfiles /?.
VBS
Приведенный ниже скрипт VBS удаляет все файлы и папки, включая защищенные, с выводом списка удаленных файлов.
On Error Resume Next intDays = Int(Wscript.arguments.Item(0)) strFldr = Wscript.arguments.Item(1) Set objFSO = CreateObject("Scripting.FileSystemObject") DelOld strFldr, intDays Function DelOld(sFldr, iDays) On Error Resume Next Dim oD, cF, cD, oI Set oD = objFSO.GetFolder(sFldr) Set cF = oD.Files Set cD = oD.SubFolders For Each oI In cF If DateDiff("d", oI.DateLastModified, Now) > iDays Then WScript.Echo oI.Path oI.Attributes = 0 oI.Delete End If Next For Each oI In cD DelOld oI.Path, iDays If oI.Size = 0 Then oI.Attributes = 0 oI.Delete End If Next End Function
- Файлы удаляются по дате изменения. Чтобы удалять по дате создания, замените .DateLastModified на .DateCreated
- Если не хотите удалять защищенные файлы, закомментируйте строку
‘ oI.Attributes = 0
Команда для выполнения
Скрипт можно запускать из командного файла (CMD).
cscript //Nologo MyCleanUp.VBS 14 %windir%\temp >MyCleanupScript.Log
- Вместо %windir%\temp подставьте свою папку (в этом примере удаляются файлы из временной папки в системном каталоге)
- Возраст файлов по умолчанию 14 дней, но вы можете задать любое значение
- Список удаленных файлов будет по умолчанию сохранен в файле %windir%\system32\MyCleanupScript.Log, хотя можно указать любой путь и имя файла
Как и в случае с утилитой forefiles.exe, можно реализовать очистку различных папок, указав каждую в отдельной команде.
PowerShell
Скрипт на PowerShell был в блоге Сергея Мариничева в рамках урока об операциях с файлами, но теперь страница доступна только в архиве интернета. Я скопировал ключевое содержимое для вас:
#из заданной папки удалять все файлы и папки старше 14 дней $Path = "C:\temp" $Days = "-14" $CurrentDate = Get-Date $OldDate = $CurrentDate.AddDays($Days) Get-ChildItem $Path -Recurse | Where-Object { $_.LastWriteTime -lt $OldDate } | Remove-Item
Запуск скрипта:
powershell.exe -ExecutionPolicy Bypass -noprofile -file Script.ps1
Выполнение очистки по расписанию
Для выполнения очистки папки по расписанию нужно создать скрипт с именем cleanup.cmd, содержащий команду для запуска, и скопировать его в любую папку из PATH (например, %windir%\system32). Поместите туда же скрипт VBS или PowerShell, если вы решили использовать его, а не утилиту forfiles.ехе.
Задание в планировщике создается одной командой:
Schtasks.exe /Create /RL Highest /TN CleanUP /SC Weekly /D SUN /ST 14:00 /TR "%WINDIR%\system32\cleanup.cmd"
Задание с именем CleanUp будет выполняться:
- с наивысшими правами (параметр /RL)
- раз в неделю (параметр /SC)
- по воскресеньям (параметр /D)
- в 14:00 (параметр /ST)
Откройте Пуск – Поиск – Планировщик заданий и вы увидите в библиотеке планировщика задание CleanUp.
Увеличить рисунок
Можете проверить работу задания в планировщике. Для этого щелкните правой кнопкой мыши по заданию и выберите Выполнить.
Готовые файлы
Загрузите архив и распакуйте в любую папку. В архиве варианты forfiles и VBS.
- Задайте путь к папке и возраст файлов в скрипте CleanUp.cmd в одной из папок (каждая соответствует одному из описанных выше способов), после чего скопируйте все содержимое папки в %windir%\system32.
- Щелкните правой кнопкой мыши на файле schedule.cmd и выберите Запуск от имени администратора, чтобы создать задание.
Благодарности
Авторами скриптов, которые я когда-то почерпнул из этой темы конференции OSZone, являются Keeper2006 и amel27 соответственно. В этой же теме вы найдете другие интересные варианты решения данной задачи, и туда же следует направлять вопросы по доработке скриптов под свои нужды.
А как вы избавляетесь от ненужных файлов – программой или скриптом? Настроена ли у вас очистка по расписанию?
Хочу сегодня показать вам очередной скрипт PowerShell. В этот раз – для удаления старых файлов и пустых папок. Такой скрипт может пригодиться для отчистки, например файловых серверов, или каких-нибудь временных или обменных папок.
Скачать скрипт можно тут. Скрипт на GitHub.
Текст скрипта:
$Now = Get-Date $Days = "7" $TargetFolder = "C:\Users\sanglyb\Documents\" $Extension = "*" $LastWrite = $Now.AddDays(-$Days) $Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where{$_.CreationTime -le "$LastWrite" -and $_.LastWriteTime -le "$LastWrite"} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName foreach ($File in $Files) { if ($File -ne $NULL -and !$File.PSIsContainer) { write-host "Deleting File $File" -ForegroundColor "Magenta" Remove-Item $File.FullName -Force | out-null } elseif ($File -ne $NULL -and $File.PSIsContainer) { $FolderInfo = get-Childitem $File.FullName | Measure-Object if ($folderInfo.count -eq 0) { write-host "Deleting directory - $File" -foregroundcolor "green" Remove-Item $File.FullName -Force | out-null } } else { Write-Host "No more files to delete!" -foregroundcolor "Green" } } #удаляем пустые папки, не зависимо от времени создания $folderInfo="" $Folders = Get-Childitem $TargetFolder -Recurse | Where{$_.PSIsContainer} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName foreach ($Folder in $Folders) { if ($Folder -ne $null) { $FolderInfo = get-Childitem $Folder.FullName | Measure-Object if ($folderInfo.count -eq 0) { write-host "Deleting directory - $Folder" -foregroundcolor "yellow" Remove-Item $Folder.FullName -force | out-null } } }
Пару слов, о том, что тут происходит.
$Days = "7" $TargetFolder = "C:\Users\sanglyb\Documents\" $Extension = "*"
Тут мы указываем количество дней, файлы старше которых должны быть удалены, задаем путь до отчищаемой папки и желаемые расширения файлов, если вам нужно удалять определенные типы файлов, например можно задать *.js тогда будут удалены все старые JavaScript файлы.
$LastWrite = $Now.AddDays(-$Days) $Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where{$_.CreationTime -le "$LastWrite" -and $_.LastWriteTime -le "$LastWrite"} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName
В этом участке мы находим все файлы, которые подходят под наши критерии. А также сортируем список, что бы всё шло от большего пути к меньшему. Это нужно, если у вас будут вложенные папки, что бы скрипт всегда сперва удалял файлы, а потом уже пытался удалить папку, где расположены эти папки.
foreach ($File in $Files) { if ($File -ne $NULL -and !$File.PSIsContainer) { write-host "Deleting File $File" -ForegroundColor "Magenta" Remove-Item $File.FullName -Force | out-null }
Собственно, удаляем файл.
elseif ($File -ne $NULL -and $File.PSIsContainer) { $FolderInfo = get-Childitem $File.FullName | Measure-Object if ($folderInfo.count -eq 0) { write-host "Deleting directory - $File" -foregroundcolor "green" Remove-Item $File.FullName -Force | out-null } }
Тут мы удаляем папку, но перед ее удалением, проверяем, что бы она была пустая.
$folderInfo="" $Folders = Get-Childitem $TargetFolder -Recurse | Where{$_.PSIsContainer} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName foreach ($Folder in $Folders) { if ($Folder -ne $null) { $FolderInfo = get-Childitem $Folder.FullName | Measure-Object if ($folderInfo.count -eq 0) { write-host "Deleting directory - $Folder" -foregroundcolor "yellow" Remove-Item $Folder.FullName -force | out-null } } }
По сути, это повторение уже проделанной операции. Но тут мы проходимся по всем папкам, ищем пустые папки и удаляем их.
Такой вот не хитрый, но думаю весьма полезный в хозяйстве скриптик. Надеюсь, информация окажется вам полезной.
Выражаю свою большую благодарность ival за помощь и корректировку направления моих мыслей
Ранее, в процессе решения данного вопроса, на просторах сети наткнулся на очень любопытную статью:
«Автоматическое удаление старых файлов [скрипт PowerShell]»
https://www.mytechnote.ru/article/avtomaticheskoe-udalenie-staryh-faylov-skript-powershell
Там автор еще более изящно чистит файлы и папки, учитывая их возраст (дату создания).
Может кому-то в будущем будет в самый раз, например, для чистки определённых папок на терминальном сервере.
С позволения уважаемой администрации форума приведу содержимое всего PS-скрипта и пояснения автора тут (вдруг исчезнет та статься) с уже внесенной моей поправкой на пути к папкам, которые будем чистить — «C:\Windows\Temp\» и «C:\Users\имя_текущего_пользователя\Appdata\Local\Temp» (в скрипте это выглядит как «$env:temp\»)
В этом блоке указываем количество дней (в данном случае это — 7 дней), файлы старше которых должны быть удалены, задаем путь до очищаемой папки/папок (пути к нужным папкам пишутся в кавычках и разделяются между собой запятой + пробел) и желаемые расширения файлов.
Если вам нужно удалять определенные типы файлов, например можно задать «*.js» — тогда будут удалены все старые JavaScript файлы.
$Days = "7"
$TargetFolder = "C:\Windows\Temp\", "$env:temp\"
$Extension = "*"
В следующем участке мы находим все файлы, которые подходят под наши критерии. А также сортируем список, что бы всё шло от большего пути к меньшему. Это нужно, если у вас будут вложенные папки, что бы скрипт всегда сперва удалял файлы, а потом уже пытался удалить папку, где расположены эти папки.
$LastWrite = $Now.AddDays(-$Days)
$Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where{$_.CreationTime -le "$LastWrite" -and $_.LastWriteTime -le "$LastWrite"} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName
Собственно, удаляем файл.
foreach ($File in $Files)
{
if ($File -ne $NULL -and !$File.PSIsContainer)
{
write-host "Deleting File $File" -ForegroundColor "Magenta"
Remove-Item $File.FullName -Force | out-null
}
Тут мы удаляем папку, но перед ее удалением, проверяем, что бы она была пустая.
elseif ($File -ne $NULL -and $File.PSIsContainer)
{
$FolderInfo = get-Childitem $File.FullName | Measure-Object
if ($folderInfo.count -eq 0)
{
write-host "Deleting directory - $File" -foregroundcolor "green"
Remove-Item $File.FullName -Force | out-null
}
}
По сути, это повторение уже проделанной операции. Но тут мы проходимся по всем папкам, ищем пустые папки и удаляем их.
$folderInfo=""
$Folders = Get-Childitem $TargetFolder -Recurse | Where{$_.PSIsContainer} | Sort-Object -Descending {$_.FullName.Split('\').Count},FullName
foreach ($Folder in $Folders)
{
if ($Folder -ne $null)
{
$FolderInfo = get-Childitem $Folder.FullName | Measure-Object
if ($folderInfo.count -eq 0)
{
write-host "Deleting directory - $Folder" -foregroundcolor "yellow"
Remove-Item $Folder.FullName -force | out-null
}
}
}
Работоспособность указанного скрипта проверено лично мной. Со своей задачей он справляется без проблем.
Также в архиве «delete-old-files.zip», прикрепленном к этому сообщению, находится уже модифицированный PS-скрипт для чистки указанных выше папок:
«C:\Windows\Temp\» и «C:\Users\имя_текущего_пользователя\Appdata\Local\Temp».
Если кому-то нужно чистить другие папки — просто замените пути на свои в «$TargetFolder =».
Достаточно типовая задача, по удалению всех файлов и содержащихся папок внутри директории без удаления её самой вызывает определенные трудности.
Файлы могут быть скрыты, помечены только для чтения, может содержать системные файлы.
Простейшим способом удаления будет рекурсивное удаление самой директории с последующим созданием, но в этом случае теряются назначенные права доступа к папке.
RMDIR /S /Q C:\Путь-до-директории
MKDIR C:\Путь-до-директории
Ключь /S — удаление указанного каталога и всех содержащихся в нем файлов и подкаталогов.
Ключь /Q — Отключение запроса подтверждения при удалении.
Альтернативный рабочий вариант, это переход в указанную папку и указание на нее же при удалении
CD "Путь-до-директории"
RMDIR . /S /Q
Недостаток данного способа в том, что иногда не хочется менять рабочую директорию по различным причинам.
Более сложный вариант, требует гораздо больше количества кода с учетом особенностей, например FOR игнорирует директории со скрытыми атрибутами, поэтому итоговый вариант пакетного BAT файла будет следующим:
@ECHO OFF
SET THEDIR=название-директории-в-которой-происходит-удаление
Echo Удаляем все файлы в %THEDIR%
DEL "%THEDIR%\*" /F /Q /A
Echo Удаляем все директории в %THEDIR%
FOR /F "eol=| delims=" %%I in ('dir "%THEDIR%\*" /AD /B 2^>nul') do RMDIR /Q /S "%THEDIR%\%%I"
@ECHO Удаление завершено.
EXIT
Ключи в DEL обозначают следующее: /A — удалить системные и скрытые, /F — принудительное удаление файлов доступных только для чтения, /Q — не задавать вопросы.
Название директории заключается в коде в двойные кавычки потому, что оно может содержать пробел или один из символов &()[]{}^=;!’+,`~ , если этого не сделать, то пакетный файл отработает с ошибками.
Время чтение: 4 минуты
2013-05-15
В основном, загружаемые файлы с интернета в первую очередь попадают в папку «Загрузки»… Как правило, файлы там и остаются, например архивы, rar, zip. После распаковки можно просто забыть их удалить. Со временем файлов становится больше, а свободного места меньше!
Сегодня я обнаружил, что моя папка «Загрузки» весит почти 30 Гб. Вот накачал, подумал я и решил, что надо как-то решать эту «проблему».
В голову пришло два варианта, как реализовать автоматическое удаление всех файлов из папки «Загрузки» каждый день в определённое время!
1) Простой пакетный файл, в народе «батник».
2) Тоже не сложный сценарий в «Windows PowerShell».
Я покажу все два варианта удаления файлов из папки загрузка, а Вам останется только выбрать, какой из них использовать.
Пакетный файл.
Тут совсем все просто, и я имею все шансы получить по башке, за этот криво написанный батник. Знаю кривой, но зато работает хорошо!
Используется две простые команды «DIR» что бы вести «log» файл, в него попадают название удаляемых файлов, что бы при необходимости можно было посмотреть, что было удаленно, и команда «del» которая, в общем, и удаляется все из заданной директории.
@echo off chcp 1251 DIR /B «C:\Users\ Ваше Имя \Downloads\*.*» >> C:\Temp\log.log del /Q C:\Users\ Ваше Имя \Downloads\*.*; |
Если Вам нужно удалять только, например zip архивы, то вместо «*.*» напишите «*.zip» и так далее.
Теперь сохраните файл с расширением «bat» например в «C:\temp\del.bat» Что нужно делать с ним дальше, расскажу немного позже!
Сценарий в «PowerShell»
Что такое «PowerShell» я рассказывать не буду, а в конце поста дам ссылку на загрузку не большой книги по «PowerShell»
Сценарий для удаления всех файлов из папки загрузка я написал такова вида.
$Directory = «C:\Users\Ваше Имя\Downloads» $DeleteFiles = dir —path $Directory —recurse —IncLude *.* $LogFile = «C:\Temp\log_Delete.log» foreach ($file in $DeleteFiles){ if ($DeleteFiles) { «Файл $file удалён « + (Get—date) >> $LogFile del $file } else { «Файлов для удаления не существует « + (Get—date) >> $LogFile } } |
Принцип работы сценария такой: Если в папке загрузка имеются файлы, то он удаляет их все, и записывает в лог файл «log_Delete.log» имя файла, дату и время удаления.
Если же папка «загрузки» была пустая на момент выполнения сценария, то в лог файл будет записана строка «Файлов для удаления не существует – Дата Время»
Теперь сохраните сценарий с расширением «ps1» и поместите файл, в нужную Вам директорию, например в «C:\temp\del.ps1»
Как автоматически использовать оба варианта.
Что бы «батник» или «сценарий PowerShell» автоматически запускались и чистили папку «Загрузки» нужно создать простую задачу. Для этого в меню Пуск в поле поиска введите «планировщик заданий» откройте его и нажмите ссылку «Создать простую задачу».
Создавать задачу будем на примере сценария!
В открывшемся окне введите любое имя задачи.
На следующем шаге, после нажатия кнопки «далее» выберете нужный Вам параметр. Я выбрал «Ежедневно».
Тут у Вас есть возможность выбрать нужное для Вас время, когда будет выполняться сценарий.
В окне выбора действия для задачи, поставьте отметку «Запустить программу»
На следующем шаге, в поле «Программа или сценарий» просто напишите «powershell» а в качестве аргумента укажите полный путь до файла «del.ps1»
Нажмите кнопку «Далее» затем «Готова» На этом создание простой задачи закончено.
Теперь сценарий будет выполняться каждый день в нужное для Вас время, и удалять все из папки «Загрузка»
Самое главное, после всех выше перечисленных действий, не забывать в папке «Загрузки» нужные Вам файлы и перемещать их в другой каталог, что бы они не были удалены!
Книга PowerShell.zip