PowerShell - Удаляем устаревшие файлы

imageЕсли внутри корпоративной сети используются всевозможные сетевые ресурсы доступные множеству пользователей и выполняющие функции файлообменников, например сетевые папки или каталоги 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'"

но если честно, такой тип вызова я не использую и даже не проверял.

Созданный командный файл располагаем в каталоге с скриптами и выполняем уже непосредственное его вызов из Планировщика задач по нужному нам расписанию

image

Всего комментариев: 11 Комментировать

  1. Rustam Khashimov /

    Пользуюсь командой в одну строчку:

    forfiles.exe /p :\ /s /m *.* /d -10 /c "cmd /c del /q /f @file"

  2. Rustam Khashimov /

    парсер съел часть пути:
    forfiles.exe /p D:svalka /s /m *.* /d -10 /c "cmd /c del /q /f @file"

    1. Алексей Максимов /

      В данном случае, - согласен. Как вариант. Утилиты командной строки это конечно хорошо, но когда немного понадобится изменить (усложнить) сценарий обработки файлов неоспоримое приемущество будет на стороне PowerShell

      1. Rustam Khashimov /

        Никто не спорит, PS более функционален.Иногда без него действительно не обойтись. Я лишь привел альтернативу. Для озвученной задачи - более легковесную.

  3. Обратная ссылка: PowerShell — Настраиваем очистку логов IIS | Блог IT-KB /

  4. Игорь /

    Добрый день.

    C:\FTP1S>powershell.exe -NoProfile -command C:\FTP1S\PS.ps1
    Имя "C:\FTP1S\PS_ScriptsDelOldFilesExchangeFolder.psl" не распознано как имя командлета, функции....

    С чем связана ошибка? Планировал применить для удаления старых каталогов.
    --
    С уважением, Игорь

  5. Игорь /

    Добрый день.
    Как добавить маску для удаляемых объектов? Необходимо удалять не все устаревший объекты, например, только каталоги вида 20160912.135411. Маска - '2016*.*'
    --
    С уважением, Морозов И.Г.

    1. Алексей Максимов / Автор записи

      Можно просто расширить условия. Например,заменить строку:

      ([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period

      на строку:

      ($_.Name -ilike "2016*") -and ($_.Attributes -eq "Directory") -and (([DateTime]::Now.Subtract($_.CreationTime)).Days -gt $Period)

      Первое условие - маска имени (без учёта регистра), второе - признак того, что объект является каталогом, третье - сравнение по дате создания.

  6. scman /

    Спасибо за статью, очень полезно. А как данный скрипт применить к сетевому хранилищу ? Например, чтобы файлы удалялись из папки \\server\files

  7. Василий /

    Я для таких целях придумал вот такую строчку:
    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 (:

  8. Shm /

    Чоткий скрипт удалил полностью все! на 10 дней плевать.

Добавить комментарий