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

Одной из проблем является то что этот "Обменник" превращается в инструмент долговременного хранения файлов, что недопустимо. посему всем сотрудникам сообщаем, что данные будут регулярно удаляться через N дней после их размещения на шаре.

А сами вооружаемся powershell и task scheduler, создаем скрипт со следующим содержимым и в планировщике ставим его на ежедневное исполнение

#Дата с которой сравнивать. В этом случае -15 дней от текущей даты
$date = (Get-Date).AddDays(-15)
#Путь до директории откуда удалять файлы
$path = "d:\data\public"
#Расположение отчетов 
$report = "C:\scripts\Result\file_list.txt"

#Работаем с файлами
#Вывод спписка всех файлов без  папок (в т.ч. внутри папок) старше чем значение в $date
$filelist = Get-ChildItem -Recurse -Path $path -file | Where-Object -Property CreationTime -lT $date  
$filelist  | Sort-Object -Property CreationTime | ft CreationTime ,VersionInfo | tee $report
#Удаляем файлы
#$filelist | Remove-Item 

#Работаем с каталогами
#вывод списка пустых директорий(где нет ни файлов ни директорий) старше чем дата $date 
$folderlist =  Get-ChildItem -Recurse -Path $path -Directory | Where-Object -Property LastWriteTime -lT $date | where { $_.psiscontainer -eq $true -and $_.GetFiles().count -eq 0 -and $_.GetDirectories().count -eq 0 } 
#вывод списка пустых директорий (где нет файлов, но есть директории)  старше чем дата $date 
#$folderlist =  Get-ChildItem -Recurse -Path $path -Directory | Where-Object -Property LastWriteTime -lT $date | where { $_.psiscontainer -eq $true -and $_.GetFiles().count -eq 0 } 
$folderlist | Sort-Object -Property LastWriteTime | ft LastWriteTime ,FullName | tee $report -Append
#Удаляем каталоги
#$folderlist | Remove-Item

P.s чукча не писатель и не великий кодер, пишу как умею

Ссылка на гит https://github.com/fiverok/psscripts/blob/main/Del_old_files.ps1

Комментарии (10)


  1. FanatPHP
    02.10.2024 08:54

    А зачем tee, если задача для планировщика? Вроде бы, обычное перенаправление потока и в венде работает?


    1. fiverok Автор
      02.10.2024 08:54

      для проверки вывода использовал, можно смело сносить


  1. mpa4b
    02.10.2024 08:54
    +1

    $ crontab -l
    0 3 * * * /usr/bin/find /path/to/files/ -exec /usr/bin/touch {} +

    И борьба сисодминов с пользователями на данном фронте заканчивается победой пользователей


    1. kuzzdra
      02.10.2024 08:54
      +2

      /usr/bin/find

      Сисадмин со скриптом на powershell: здесь что то по линуксовому, не могу разобрать ;)


  1. Akina
    02.10.2024 08:54
    +3

    Одной из проблем является то что этот "Обменник" превращается в инструмент долговременного хранения файлов, что недопустимо.

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

    Далее. Расскажите, что вы будете делать, когда выяснится, что скрипт удалил весьма важный файл? причём не потому, что сотрудник ушами хлопал, а по форс-мажору (заболел внезапно). Кстати, а вы смотрели, КУДА этот скрипт удаляет? А удаляет он сразу в никуда, минуя корзину...

    Далее. Некоторые программные средства копирования сохраняют дату создания оригинального файла у его копии. Скопированный так файл улетит при первом же запуске скрипта. Или некоторые программные средства редактирования - обновляют файл, а не перезаписывают свежей копией, соответственно не обновляя дату создания.

    Далее. От какой учётной записи будете запускать скрипт?

    И ещё. А что, если юзер продвинутый, и поставит явный атрибут Delete = Deny для всех? А он владелец, ему можно... И текущий Remove-Item грохнется по ошибке, не обработав остаток массива. И -Force не поможет.

    И ещё всякоразного можно накидать... только думать лениво.


    1. fiverok Автор
      02.10.2024 08:54

      Данная шара это не обязательно отдельный сервер, а именно шара, потому плодить сервера не нужно, насчет того что вдруг удалится важный файл, так вот там его быть не должно, для важных файлов у сотрудников есть отдельное хранилище, за сохранностью данных на котором мы следим. Мехазм рассчитан на среднестатистических пользователей, а не на супер продвинутых (с продвинутыми проще договориться),

      Запускаться от УЗ которая обладает правами на удаление содержимого в данной шаре


  1. gotch
    02.10.2024 08:54
    +1

    Файлы с именем > 255(?) символов удаляться не будут (для обхода ограничения используется AlphaFS.dll). Возможно стоит анализировать и другие временные атрибуты.

    Выложить скрипт на github? )

    Орфография грустная, в коде много висящих пробелов в конце строк, пробелы перед запятой, использование алиасов, сомнительное оформление блоков и ошибки регистра.


    1. fiverok Автор
      02.10.2024 08:54

      выложил https://github.com/fiverok/psscripts/blob/main/Del_old_files.ps1, насчет длинных имен надо подумать


      1. gotch
        02.10.2024 08:54
        +2

        Вот пара сокращенных кусочков, в которых вся суть этой библиотеки.

        В полном ещё учитываются файлы-исключения (System Volume Information, если чистить от корня), уровень вложенности удаляемых пустых директорий (оставить пустые папки верхнего уровня с фамилиями или отделами).

        Import-Module -name "$(Split-Path $MyInvocation.MyCommand.Path)\AlphaFS.dll"
        
        $files = @([Alphaleonis.Win32.Filesystem.Directory]::EnumerateFiles($FileExchangePath,'*',[System.IO.SearchOption]::'AllDirectories'))
        
        foreach ($record in $files) {
            $file = [Alphaleonis.Win32.Filesystem.File]::GetFileSystemEntryInfo($record)
            if ($file.FullPath -notmatch $FilesToExclude){
                if ($file.CreationTime -le $OldDate -and $file.LastAccessTime -le $OldDate -and $file.LastWriteTime -le $oldDate){
                    [Alphaleonis.Win32.Filesystem.File]::Delete($file.FullPath, $true)
                }
            }
        }
        
        $dirs = @([Alphaleonis.Win32.Filesystem.Directory]::EnumerateDirectories($FileExchangePath,'*',[System.IO.SearchOption]::'AllDirectories'))|sort length -Descending
        foreach ($dir in $dirs) {
            if ($dir -notmatch $FilesToExclude){
                $dirfilescount = @([Alphaleonis.Win32.Filesystem.Directory]::EnumerateFiles($dir,'*',[System.IO.SearchOption]::'AllDirectories')).count
                [Alphaleonis.Win32.Filesystem.Directory]::Delete($dir, $true)
            }
        }


  1. khulster
    02.10.2024 08:54
    +2

    Я бы посоветовал присмотреться к утилите Agestore.

    https://learn.microsoft.com/ru-ru/windows-hardware/drivers/debugger/agestore

    Работает искаропки и зачастую она куда лучше в таких вопросах. Agestore удаляет файлы исходя не из даты их создание или изменения, а исходя из последнего обращения к файлу. Т.е. если лежит что-то, чем никто не интересовался и не пользовался X дней - выпиливаем. В случае временных или кешей это куда удобнее, чем жесткие лимиты в днях.