Если внутри корпоративной сети используются всевозможные сетевые ресурсы доступные множеству пользователей и выполняющие функции файлообменников, например сетевые папки или каталоги FTP серверов, то иногда может возникнуть необходимость в обслуживании таких ресурсов, например периодического удаления файлов и подкаталогов имеющих определённый срок давности. Хочу поделиться маленьким примером когда-то найденного (уже не вспомню где) PowerShell скрипта, который решает у меня такую задачу
Param ( #период в днях старше которого файл считается пригодным к удалению [int]$Period = 10 , #каталог для просмотра [String]$PATH = "D:\IIS_FTP\port_21\Public" , #включать ли вложенные каталоги [bool]$recurse = $true ) filter Get-OldFiles{ Param ( [int]$Period = 10 ) if( ([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period ) {return $_ } } if ($recurse) {dir -path $PATH -recurse | Get-OldFiles -Period $Period | Remove-Item -recurse -force} else {dir -path $PATH | Get-OldFiles -Period $Period | Remove-Item -force}
Другим примером применения такого скрипта может стать необходимость периодической очистки каких либо текстовых лог-файлов.
Если например присутствует дополнительное условие, при котором нельзя удалять вложенные каталоги можно заменить строчку…
([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period
… на блок…
($_.Attributes -ne "Directory") ` -and ` (([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period)
Если на файловом сервере несколько каталогов которые нужно обслуживать на предмет удаления старых данных и при этом условия удаления различаются, то можно создать единый командный файл который будет запускаться в последствии из Планировщика задач. Пример содержимого такого командного файла
powershell.exe -NoProfile -command "C:\PS_Scripts\DelOldFilesExchangeFolder.ps1" powershell.exe -NoProfile -command "C:\PS_Scripts\DelOldFilesScanToFTPFolder.ps1" powershell.exe -NoProfile -command "C:\PS_Scripts\DelOldFilesFTPPublicFolder.ps1"
В описании к скрипту я так же нашёл информацию о том что можно производить вызов скрипта с передачей параметров, например так:
powershell.exe -NoProfile -NonInteractive -command "C:\PS_Scripts\DelOldFiles.ps1 -Period 4 -Path 'D:\SHARE_Exchange'"
но если честно, такой тип вызова я не использую и даже не проверял.
Созданный командный файл располагаем в каталоге с скриптами и выполняем уже непосредственное его вызов из Планировщика задач по нужному нам расписанию
Пользуюсь командой в одну строчку:
forfiles.exe /p :\ /s /m *.* /d -10 /c "cmd /c del /q /f @file"
парсер съел часть пути:
forfiles.exe /p D:svalka /s /m *.* /d -10 /c "cmd /c del /q /f @file"
В данном случае, - согласен. Как вариант. Утилиты командной строки это конечно хорошо, но когда немного понадобится изменить (усложнить) сценарий обработки файлов неоспоримое приемущество будет на стороне PowerShell
Никто не спорит, PS более функционален.Иногда без него действительно не обойтись. Я лишь привел альтернативу. Для озвученной задачи - более легковесную.
Обратная ссылка: PowerShell — Настраиваем очистку логов IIS | Блог IT-KB /
Добрый день.
C:\FTP1S>powershell.exe -NoProfile -command C:\FTP1S\PS.ps1
Имя "C:\FTP1S\PS_ScriptsDelOldFilesExchangeFolder.psl" не распознано как имя командлета, функции....
С чем связана ошибка? Планировал применить для удаления старых каталогов.
--
С уважением, Игорь
Добрый день.
Как добавить маску для удаляемых объектов? Необходимо удалять не все устаревший объекты, например, только каталоги вида 20160912.135411. Маска - '2016*.*'
--
С уважением, Морозов И.Г.
Можно просто расширить условия. Например,заменить строку:
([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period
на строку:
($_.Name -ilike "2016*") -and ($_.Attributes -eq "Directory") -and (([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period)
Первое условие - маска имени (без учёта регистра), второе - признак того, что объект является каталогом, третье - сравнение по дате создания.
Спасибо за статью, очень полезно. А как данный скрипт применить к сетевому хранилищу ? Например, чтобы файлы удалялись из папки \\server\files
Я для таких целях придумал вот такую строчку:
Get-ChildItem "D:\IIS_FTP\port_21\Public" -recurse | Where-Object {(Get-Date).AddDays(-10).CompareTo($_.LastWriteTime) -eq 1} | Remove-Item -recurse -Force
Усложнять фильтры можно в Where-Object (:
Чоткий скрипт удалил полностью все! на 10 дней плевать.