Сегодня для пятничных посиделок предлагаю взглянуть на PS1-скрипт резервирования файлов профиля пользователя.
Скрипт отлично зарекомендовал себя и как автономный метод резервного копирования файлов из профиля пользователя, так и в виде назначенного задания по срабатыванию определённого триггера.
В массиве $foldersToCopy хранятся названия папок, расположенных в профиле пользователя, которые требуется забэкапить в сетевое хранилище. Ограничившись базовым набором каталогов профиля, я умышленно не стал добавлять в массив системные директории и прочие целевые новомодные папки. Как правило, пользовательские файлы обитают исключительно в документах, загрузках и на рабочем столе (это уже классика).
А ещё у скрипта есть прогресс-бар, но это уже детали…
# Заголовок консоли скрипта #
[System.Console]::Title = "Копирование профиля текущего пользователя"
# Укажите путь к профилю пользователя #
$sourcePath = "$env:USERPROFILE"
# Укажите путь к целевой папке с именем пользователя #
$destinationPath = "\\192.168.1.1\userprofiles\$($env:USERNAME)"
# Определяем массив папок, которые нужно скопировать #
$foldersToCopy = @( "Desktop", "Documents", "Downloads", "Pictures", "Music" )
# Создаем целевую папку, если она не существует #
if (!(Test-Path -Path $destinationPath))
{
New-Item -ItemType Directory -Path $destinationPath
}
# Общая информация для прогресса #
$totalFolders = $foldersToCopy.Count
$currentFolderIndex = 0
# Копирование файлов #
foreach ($folder in $foldersToCopy)
{
$currentFolderIndex++
$sourceFolder = Join-Path -Path $sourcePath -ChildPath $folder
$targetFolder = Join-Path -Path $destinationPath -ChildPath $folder
# Устанавливаем заголовок прогресса #
$progressMessage = "Копирование $folder"
# Отображаем прогресс #
Write-Progress -Activity "Копирование папок" -Status $progressMessage -PercentComplete (($currentFolderIndex / $totalFolders) * 100)
# Копируем папку, если она существует #
if (Test-Path -Path $sourceFolder)
{
# Создаем целевую папку, если она не существует #
if (!(Test-Path -Path $targetFolder))
{ New-Item -ItemType Directory -Path $targetFolder }
# Получаем файлы для копирования, исключая desktop.ini и thumbs.db #
$filesToCopy = Get-ChildItem -Path $sourceFolder -Recurse | Where-Object { $_.Name -ne 'desktop.ini' -and $_.Name -ne 'thumbs.db' }
# Копируем файлы #
$totalFiles = $filesToCopy.Count
$currentFileIndex = 0
foreach ($file in $filesToCopy)
{
$currentFileIndex++
$destinationFile = Join-Path -Path $targetFolder -ChildPath $file.FullName.Substring($sourceFolder.Length + 1)
$destinationFileDir = Split-Path -Path $destinationFile -Parent
# Создаем директорию файла, если она не существует #
if (!(Test-Path -Path $destinationFileDir))
{ New-Item -ItemType Directory -Path $destinationFileDir -Force }
# Копируем файл #
Copy-Item -Path $file.FullName -Destination $destinationFile -Force
# Отображаем прогресс по файлам #
Write-Progress -Activity "Копирование файлов" -Status "Копирование $($file.Name)" -PercentComplete (($currentFileIndex / $totalFiles) * 100)
}
}
}
# Завершение копирования #
Write-Progress -Activity "Копирование папок" -Status "Завершено!" -Completed
Нужно только актуализировать $destinationPath не затрагивая переменную с именем пользователя. И, само собой, нужно обеспечить постоянную доступность сетевого пути.
У скрипта есть один, но существенный минус — не предусмотрено хранение истории версий файлов, но эта тема уже скорее не про скрипты…