Одной из наверное классических задач системного администратора является организация общей шары (файлопомойки), для оперативного обмена данными между сотрудниками.
Одной из проблем является то что этот "Обменник" превращается в инструмент долговременного хранения файлов, что недопустимо. посему всем сотрудникам сообщаем, что данные будут регулярно удаляться через 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-ItemP.s чукча не писатель и не великий кодер, пишу как умею
Ссылка на гит https://github.com/fiverok/psscripts/blob/main/Del_old_files.ps1
Комментарии (10)
 - mpa4b02.10.2024 08:54+1- $ crontab -l
 0 3 * * * /usr/bin/find /path/to/files/ -exec /usr/bin/touch {} +- И борьба сисодминов с пользователями на данном фронте заканчивается победой пользователей  - kuzzdra02.10.2024 08:54+2- /usr/bin/find - Сисадмин со скриптом на powershell: здесь что то по линуксовому, не могу разобрать ;) 
 
 - Akina02.10.2024 08:54+3- Одной из проблем является то что этот "Обменник" превращается в инструмент долговременного хранения файлов, что недопустимо. - Насчёт недопустимости - есть весьма большие сомнения. Или у вас один сервер для оперативного обмена, второй для долговременного хранения, третий архивный? хорошо живёте... - Далее. Расскажите, что вы будете делать, когда выяснится, что скрипт удалил весьма важный файл? причём не потому, что сотрудник ушами хлопал, а по форс-мажору (заболел внезапно). Кстати, а вы смотрели, КУДА этот скрипт удаляет? А удаляет он сразу в никуда, минуя корзину... - Далее. Некоторые программные средства копирования сохраняют дату создания оригинального файла у его копии. Скопированный так файл улетит при первом же запуске скрипта. Или некоторые программные средства редактирования - обновляют файл, а не перезаписывают свежей копией, соответственно не обновляя дату создания. - Далее. От какой учётной записи будете запускать скрипт? - И ещё. А что, если юзер продвинутый, и поставит явный атрибут Delete = Deny для всех? А он владелец, ему можно... И текущий Remove-Item грохнется по ошибке, не обработав остаток массива. И -Force не поможет. - И ещё всякоразного можно накидать... только думать лениво.  - fiverok Автор02.10.2024 08:54- Данная шара это не обязательно отдельный сервер, а именно шара, потому плодить сервера не нужно, насчет того что вдруг удалится важный файл, так вот там его быть не должно, для важных файлов у сотрудников есть отдельное хранилище, за сохранностью данных на котором мы следим. Мехазм рассчитан на среднестатистических пользователей, а не на супер продвинутых (с продвинутыми проще договориться), - Запускаться от УЗ которая обладает правами на удаление содержимого в данной шаре 
 
 - gotch02.10.2024 08:54+1- Файлы с именем > 255(?) символов удаляться не будут (для обхода ограничения используется AlphaFS.dll). Возможно стоит анализировать и другие временные атрибуты. - Выложить скрипт на github? ) - Орфография грустная, в коде много висящих пробелов в конце строк, пробелы перед запятой, использование алиасов, сомнительное оформление блоков и ошибки регистра.  - fiverok Автор02.10.2024 08:54- выложил https://github.com/fiverok/psscripts/blob/main/Del_old_files.ps1, насчет длинных имен надо подумать  - gotch02.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) } }
 
 
 - khulster02.10.2024 08:54+2- Я бы посоветовал присмотреться к утилите Agestore. - https://learn.microsoft.com/ru-ru/windows-hardware/drivers/debugger/agestore - Работает искаропки и зачастую она куда лучше в таких вопросах. Agestore удаляет файлы исходя не из даты их создание или изменения, а исходя из последнего обращения к файлу. Т.е. если лежит что-то, чем никто не интересовался и не пользовался X дней - выпиливаем. В случае временных или кешей это куда удобнее, чем жесткие лимиты в днях. 
 
           
 
FanatPHP
А зачем tee, если задача для планировщика? Вроде бы, обычное перенаправление потока и в венде работает?
fiverok Автор
для проверки вывода использовал, можно смело сносить