Ниже приведено пошаговое решение задачи, включая два скрипта для Windows PowerShell. Каждый шаг описывает, что и зачем делается.
Шаг 1. Скрипт №1
Цель:
• Запросить у пользователя две папки через всплывающее окно (одну – для отслеживания, другую – для хранения архивов).
• Сохранить выбранные пути в конфигурационном файле (например, config.txt), чтобы второй скрипт знал, где брать информацию.
• Создать задание ...
$folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
$folderDialog.Description = Выберите папку для отслеживания изменений
if ($folderDialog.ShowDialog() -eq OK) {
$monitorFolder = $folderDialog.SelectedPath
} else {
Write-Host Папка не выбрана. Выход.
exit
}
$folderDialog.Description = Выберите папку для хранения архивов
if ($folderDialog.ShowDialog() -eq OK) {
$archiveFolder = $folderDialog.SelectedPath
} else {
Write-Host Папка не выбрана. Выход.
exit
}
$configFile = $PSScriptRoot\config.txt
MonitorFolder=$monitorFolder | Out-File $configFile -Encoding utf8
ArchiveFolder=$archiveFolder | Out-File $configFile -Append -Encoding utf8
$taskName = ArchiveScriptTask
$script2Path = $PSScriptRoot\Script2.ps1
$action = New-ScheduledTaskAction -Execute powershell.exe -Argument -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File
$trigger = New-ScheduledTaskTrigger -Daily -At 00:00
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskName -Description Запуск архивации файлов -User $env:USERNAME -RunLevel Highest
Write-Host Задание создано и конфигурационный файл сохранён: $configFile
Пояснения:
• $PSScriptRoot – переменная, содержащая путь к папке, в которой находится скрипт. Это позволяет корректно сохранять конфигурационный файл и запускать второй скрипт.
• Register-ScheduledTask создаёт задачу с указанными действием (action) и триггером (trigger). Здесь используется пользователь, от имени которого запущен скрипт.
• Параметры -NoProfile и -ExecutionPolicy Bypass гарантируют, что скрипт будет выполнен без влияния пользовательских настроек.
Шаг 2. Скрипт №2
Цель:
• При запуске планировщиком прочитать конфигурационный файл, из которого узнать папку для отслеживания и папку для архивов.
• Найти файлы в папке для отслеживания, которые были изменены за последние 7 дней.
• Если такие файлы обнаружены, создать ZIP-архив, в имя которого включена текущая дата, и сохранить архив в папке для архивов.
• Удалить из папки архивов старые архивы (старше 30 дней).
Реализация:
- В начале скрипта читаем конфигурационный файл (config.txt), который содержит строки вида MonitorFolder=путь и ArchiveFolder=путь.
- Проверяем, существуют ли указанные папки. Если нет – прекращаем выполнение.
- Используем команду Get-ChildItem с параметром -Recurse для поиска всех файлов в папке отслеживания.
- Фильтруем файлы по дате LastWriteTime. Выбираем те, у которых время изменения не раньше, чем текущая дата минус 7 дней.
- Если подходящие файлы найдены, формируем имя архива с текущей датой (например, ArchiveYYY-MM-DD.zip) и с помощью команды Compress-Archive архивируем найденные файлы.
- Далее с помощью Get-ChildItem получаем все ZIP-файлы из папки архивов и удаляем те, у которых дата изменения (LastWriteTime) старше 30 дней.
Ниже содержимое Скрипта №2 (например, Script2.ps1):
$configFile = $PSScriptRoot\config.txt
if (!(Test-Path $configFile)) {
Write-Host Конфигурационный файл не найден: $configFile
exit
}
$lines = Get-Content $configFile
lines | Where-Object { $_ -like MonitorFolder=* }) -replace MonitorFolder=,
lines | Where-Object { $_ -like ArchiveFolder=* }) -replace ArchiveFolder=,
if (-not (Test-Path $monitorFolder)) {
Write-Host Папка для отслеживания не существует: $monitorFolder
exit
}
if (-not (Test-Path $archiveFolder)) {
Write-Host Папка для хранения архивов не существует: $archiveFolder
exit
}
$cutoffDate = (Get-Date).AddDays(-7)
$files = Get-ChildItem -Path $monitorFolder -Recurse -File | Where-Object { $_.LastWriteTime -ge $cutoffDate }
if ($files.Count -gt 0) {
Формирование имени архива с текущей датой
$currentDate = (Get-Date -Format yyyy-MM-dd)
zipFile = Join-Path $archiveFolder Archive_currentDate.zip
Compress-Archive -Path $files.FullName -DestinationPath $zipFile -Force
Write-Host Создан архив: $zipFile
} else {
Write-Host Нет файлов, изменённых за последние 7 дней для архивации.
}
$archiveCutoff = (Get-Date).AddDays(-30)
$oldArchives = Get-ChildItem -Path $archiveFolder -Filter *.zip | Where-Object { $_.LastWriteTime -lt $archiveCutoff }
foreach ($archive in $oldArchives) {
Remove-Item $archive.FullName -Force
Write-Host Удалён архив: archive.FullName)
}
Пояснения:
• В начале скрипта проверяется наличие конфигурационного файла, из которого извлекаются папки для мониторинга и архивов.
• Использование Get-ChildItem с -Recurse позволяет искать файлы во всех вложенных папках.
• Compress-Archive создаёт архив на основе списка файлов. Параметр -Force позволяет перезаписать существующий архив с таким же именем.
• При удалении старых архивов фильтруются файлы по дате LastWriteTime. Если архив был изменён (то есть создан) более 30 дней назад, он удаляется.
Итоговое замечание:
После сохранения обоих скриптов (например, в одной папке), сначала запускаем скрипт Script1.ps1 – он попросит указать нужные папки и создаст задание в планировщике задач. Затем планировщик будет ежедневно вызывать Script2.ps1, который выполнит архивирование изменений и очистку старых архивов.