Обновить MailBoxBackup_TB.ps1

This commit is contained in:
2026-03-05 08:58:52 +00:00
parent e1cfeda4e3
commit 31292e159c

View File

@@ -1,448 +1,448 @@
<# <#
.SYNOPSIS .SYNOPSIS
Скрипт для закрытия Thunderbird и резервного копирования профиля Скрипт для закрытия Thunderbird и резервного копирования профиля
.DESCRIPTION .DESCRIPTION
Выполняет поиск процессов Thunderbird, завершает их, ожидает полного закрытия Выполняет поиск процессов Thunderbird, завершает их, ожидает полного закрытия
и создает копию папки профиля в указанное место. Автоматически создает папки назначения. и создает копию папки профиля в указанное место. Автоматически создает папки назначения.
.NOTES .NOTES
Author: Author: RobinHood
Date: $(Get-Date -Format 'dd.MM.yyyy') Date: $(Get-Date -Format 'dd.MM.yyyy')
#> #>
# === НАСТРОЙКИ === # === НАСТРОЙКИ ===
$ThunderbirdProcessName = "thunderbird" # Имя процесса без .exe $ThunderbirdProcessName = "thunderbird" # Имя процесса без .exe
$SourceProfilePath = "$env:APPDATA\Thunderbird\Profiles" # Стандартный путь к профилям $SourceProfilePath = "$env:APPDATA\Thunderbird\Profiles" # Стандартный путь к профилям
# Настройка пути для резервной копии (папка создастся автоматически) # Настройка пути для резервной копии (папка создастся автоматически)
$BackupRoot = "E:\Backups\Thunderbird" # Корневая папка для бэкапов $BackupRoot = "E:\Backups\Thunderbird" # Корневая папка для бэкапов
$BackupDestination = Join-Path -Path $BackupRoot -ChildPath (Get-Date -Format 'yyyy-MM-dd') # Папка с датой $BackupDestination = Join-Path -Path $BackupRoot -ChildPath (Get-Date -Format 'yyyy-MM-dd') # Папка с датой
$MaxWaitTimeSeconds = 30 # Максимальное время ожидания закрытия Thunderbird (в секундах) $MaxWaitTimeSeconds = 30 # Максимальное время ожидания закрытия Thunderbird (в секундах)
$CopyRetryCount = 3 # Количество попыток копирования при ошибках $CopyRetryCount = 3 # Количество попыток копирования при ошибках
$MinFreeSpaceMB = 500 # Минимальное свободное место на диске назначения (МБ) $MinFreeSpaceMB = 500 # Минимальное свободное место на диске назначения (МБ)
# ================= # =================
# Функция для записи лога # Функция для записи лога
function Write-Log { function Write-Log {
param( param(
[string]$Message, [string]$Message,
[string]$Type = "INFO" [string]$Type = "INFO"
) )
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Цвета для разных типов сообщений # Цвета для разных типов сообщений
switch ($Type) { switch ($Type) {
"SUCCESS" { $color = "Green" } "SUCCESS" { $color = "Green" }
"ERROR" { $color = "Red" } "ERROR" { $color = "Red" }
"WARNING" { $color = "Yellow" } "WARNING" { $color = "Yellow" }
"INFO" { $color = "Cyan" } "INFO" { $color = "Cyan" }
default { $color = "White" } default { $color = "White" }
} }
Write-Host "[$timestamp] [$Type] " -NoNewline Write-Host "[$timestamp] [$Type] " -NoNewline
Write-Host "$Message" -ForegroundColor $color Write-Host "$Message" -ForegroundColor $color
} }
# Функция для создания папки назначения # Функция для создания папки назначения
function New-BackupFolder { function New-BackupFolder {
param( param(
[string]$FolderPath [string]$FolderPath
) )
try { try {
if (-not (Test-Path $FolderPath)) { if (-not (Test-Path $FolderPath)) {
Write-Log "Папка назначения не существует. Создание: $FolderPath" -Type "INFO" Write-Log "Папка назначения не существует. Создание: $FolderPath" -Type "INFO"
# Создаем все папки в пути рекурсивно # Создаем все папки в пути рекурсивно
New-Item -Path $FolderPath -ItemType Directory -Force | Out-Null New-Item -Path $FolderPath -ItemType Directory -Force | Out-Null
Write-Log "Папка успешно создана" -Type "SUCCESS" Write-Log "Папка успешно создана" -Type "SUCCESS"
} else { } else {
Write-Log "Папка назначения уже существует: $FolderPath" -Type "INFO" Write-Log "Папка назначения уже существует: $FolderPath" -Type "INFO"
} }
return $true return $true
} catch { } catch {
Write-Log "ОШИБКА при создании папки назначения: $_" -Type "ERROR" Write-Log "ОШИБКА при создании папки назначения: $_" -Type "ERROR"
return $false return $false
} }
} }
# Функция для проверки свободного места на диске # Функция для проверки свободного места на диске
function Test-FreeSpace { function Test-FreeSpace {
param( param(
[string]$Path, [string]$Path,
[long]$RequiredSpaceMB = 500 [long]$RequiredSpaceMB = 500
) )
try { try {
# Получаем корневой диск из пути # Получаем корневой диск из пути
$rootPath = Split-Path -Path $Path -Qualifier $rootPath = Split-Path -Path $Path -Qualifier
if ([string]::IsNullOrEmpty($rootPath)) { if ([string]::IsNullOrEmpty($rootPath)) {
$rootPath = $Path[0] + ":" $rootPath = $Path[0] + ":"
} }
$drive = Get-PSDrive -Name $rootPath[0] -ErrorAction Stop $drive = Get-PSDrive -Name $rootPath[0] -ErrorAction Stop
$freeSpaceMB = [math]::Round($drive.Free / 1MB, 2) $freeSpaceMB = [math]::Round($drive.Free / 1MB, 2)
Write-Log "Свободное место на диске $rootPath : $freeSpaceMB MB" -Type "INFO" Write-Log "Свободное место на диске $rootPath : $freeSpaceMB MB" -Type "INFO"
if ($drive.Free -lt ($RequiredSpaceMB * 1MB)) { if ($drive.Free -lt ($RequiredSpaceMB * 1MB)) {
Write-Log "НЕДОСТАТОЧНО МЕСТА! Требуется: $RequiredSpaceMB MB, доступно: $freeSpaceMB MB" -Type "ERROR" Write-Log "НЕДОСТАТОЧНО МЕСТА! Требуется: $RequiredSpaceMB MB, доступно: $freeSpaceMB MB" -Type "ERROR"
return $false return $false
} }
Write-Log "Места достаточно: $freeSpaceMB MB свободно" -Type "SUCCESS" Write-Log "Места достаточно: $freeSpaceMB MB свободно" -Type "SUCCESS"
return $true return $true
} catch { } catch {
Write-Log "Не удалось проверить свободное место: $_" -Type "WARNING" Write-Log "Не удалось проверить свободное место: $_" -Type "WARNING"
return $true # Продолжаем, если не удалось проверить return $true # Продолжаем, если не удалось проверить
} }
} }
# Функция для проверки, запущен ли Thunderbird # Функция для проверки, запущен ли Thunderbird
function Test-ThunderbirdRunning { function Test-ThunderbirdRunning {
$processes = Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue $processes = Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue
return ($processes.Count -gt 0) return ($processes.Count -gt 0)
} }
# Функция для закрытия Thunderbird # Функция для закрытия Thunderbird
function Stop-ThunderbirdGracefully { function Stop-ThunderbirdGracefully {
Write-Log "Поиск запущенных процессов Thunderbird..." -Type "INFO" Write-Log "Поиск запущенных процессов Thunderbird..." -Type "INFO"
if (Test-ThunderbirdRunning) { if (Test-ThunderbirdRunning) {
$processCount = (Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue).Count $processCount = (Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue).Count
Write-Log "Найдено процессов Thunderbird: $processCount. Попытка корректного завершения..." -Type "WARNING" Write-Log "Найдено процессов Thunderbird: $processCount. Попытка корректного завершения..." -Type "WARNING"
# Пытаемся закрыть окна Thunderbird (более мягкий способ) # Пытаемся закрыть окна Thunderbird (более мягкий способ)
$thunderbirdWindows = Get-Process -Name $ThunderbirdProcessName | Where-Object { $_.MainWindowTitle -ne "" } $thunderbirdWindows = Get-Process -Name $ThunderbirdProcessName | Where-Object { $_.MainWindowTitle -ne "" }
if ($thunderbirdWindows) { if ($thunderbirdWindows) {
foreach ($proc in $thunderbirdWindows) { foreach ($proc in $thunderbirdWindows) {
$windowTitle = if ($proc.MainWindowTitle) { $proc.MainWindowTitle } else { "Без заголовка" } $windowTitle = if ($proc.MainWindowTitle) { $proc.MainWindowTitle } else { "Без заголовка" }
Write-Log "Закрытие окна: $windowTitle" Write-Log "Закрытие окна: $windowTitle"
$proc.CloseMainWindow() | Out-Null $proc.CloseMainWindow() | Out-Null
} }
} else { } else {
Write-Log "Нет видимых окон Thunderbird, но процессы запущены" -Type "WARNING" Write-Log "Нет видимых окон Thunderbird, но процессы запущены" -Type "WARNING"
} }
# Даем время на закрытие # Даем время на закрытие
$waitCounter = 0 $waitCounter = 0
Write-Host "" Write-Host ""
while ((Test-ThunderbirdRunning) -and ($waitCounter -lt $MaxWaitTimeSeconds)) { while ((Test-ThunderbirdRunning) -and ($waitCounter -lt $MaxWaitTimeSeconds)) {
Start-Sleep -Seconds 1 Start-Sleep -Seconds 1
$waitCounter++ $waitCounter++
# Простой индикатор прогресса # Простой индикатор прогресса
$progress = [math]::Round(($waitCounter / $MaxWaitTimeSeconds) * 100) $progress = [math]::Round(($waitCounter / $MaxWaitTimeSeconds) * 100)
Write-Host "`rОжидание закрытия Thunderbird: $progress% " -NoNewline Write-Host "`rОжидание закрытия Thunderbird: $progress% " -NoNewline
} }
Write-Host "" Write-Host ""
# Если всё ещё запущен - принудительно завершаем # Если всё ещё запущен - принудительно завершаем
if (Test-ThunderbirdRunning) { if (Test-ThunderbirdRunning) {
Write-Log "Thunderbird не закрылся за отведенное время. Принудительное завершение..." -Type "ERROR" Write-Log "Thunderbird не закрылся за отведенное время. Принудительное завершение..." -Type "ERROR"
$remainingProcesses = Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue $remainingProcesses = Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue
foreach ($proc in $remainingProcesses) { foreach ($proc in $remainingProcesses) {
try { try {
Stop-Process -Id $proc.Id -Force Stop-Process -Id $proc.Id -Force
Write-Log "Процесс PID $($proc.Id) принудительно завершен" -Type "WARNING" Write-Log "Процесс PID $($proc.Id) принудительно завершен" -Type "WARNING"
} catch { } catch {
Write-Log "Не удалось завершить процесс PID $($proc.Id): $_" -Type "ERROR" Write-Log "Не удалось завершить процесс PID $($proc.Id): $_" -Type "ERROR"
} }
} }
Start-Sleep -Seconds 3 Start-Sleep -Seconds 3
} else { } else {
Write-Log "Thunderbird успешно закрыт" -Type "SUCCESS" Write-Log "Thunderbird успешно закрыт" -Type "SUCCESS"
} }
} else { } else {
Write-Log "Thunderbird не запущен" -Type "INFO" Write-Log "Thunderbird не запущен" -Type "INFO"
} }
# Финальная проверка # Финальная проверка
if (Test-ThunderbirdRunning) { if (Test-ThunderbirdRunning) {
Write-Log "ВНИМАНИЕ: Некоторые процессы Thunderbird всё еще запущены!" -Type "ERROR" Write-Log "ВНИМАНИЕ: Некоторые процессы Thunderbird всё еще запущены!" -Type "ERROR"
# Показываем оставшиеся процессы # Показываем оставшиеся процессы
Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue | Get-Process -Name $ThunderbirdProcessName -ErrorAction SilentlyContinue |
ForEach-Object { Write-Log " - PID: $($_.Id), Запущен: $($_.StartTime)" -Type "ERROR" } ForEach-Object { Write-Log " - PID: $($_.Id), Запущен: $($_.StartTime)" -Type "ERROR" }
Write-Log "Продолжаем копирование, но некоторые файлы могут быть заблокированы" -Type "WARNING" Write-Log "Продолжаем копирование, но некоторые файлы могут быть заблокированы" -Type "WARNING"
return $false return $false
} }
return $true return $true
} }
# Функция для получения размера папки # Функция для получения размера папки
function Get-FolderSize { function Get-FolderSize {
param([string]$Path) param([string]$Path)
try { try {
if (Test-Path $Path) { if (Test-Path $Path) {
$size = (Get-ChildItem $Path -Recurse -ErrorAction SilentlyContinue | $size = (Get-ChildItem $Path -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum
if ($size) { if ($size) {
return [math]::Round($size / 1MB, 2) return [math]::Round($size / 1MB, 2)
} }
} }
} catch { } catch {
# Игнорируем ошибки при подсчете размера # Игнорируем ошибки при подсчете размера
} }
return 0 return 0
} }
# Функция для копирования профиля # Функция для копирования профиля
function Copy-ThunderbirdProfile { function Copy-ThunderbirdProfile {
param( param(
[string]$Source, [string]$Source,
[string]$Destination [string]$Destination
) )
Write-Log "Начало копирования профиля..." -Type "INFO" Write-Log "Начало копирования профиля..." -Type "INFO"
Write-Log " Источник: $Source" -Type "INFO" Write-Log " Источник: $Source" -Type "INFO"
Write-Log " Назначение: $Destination" -Type "INFO" Write-Log " Назначение: $Destination" -Type "INFO"
# Проверяем существование исходной папки # Проверяем существование исходной папки
if (-not (Test-Path $Source)) { if (-not (Test-Path $Source)) {
Write-Log "Папка профиля НЕ НАЙДЕНА: $Source" -Type "ERROR" Write-Log "Папка профиля НЕ НАЙДЕНА: $Source" -Type "ERROR"
return $false return $false
} }
# Получаем размер исходной папки # Получаем размер исходной папки
$sourceSizeMB = Get-FolderSize -Path $Source $sourceSizeMB = Get-FolderSize -Path $Source
Write-Log "Размер исходной папки: ~$sourceSizeMB MB" -Type "INFO" Write-Log "Размер исходной папки: ~$sourceSizeMB MB" -Type "INFO"
# Проверяем свободное место # Проверяем свободное место
$requiredSpace = [math]::Max($MinFreeSpaceMB, $sourceSizeMB + 100) # +100 МБ запас $requiredSpace = [math]::Max($MinFreeSpaceMB, $sourceSizeMB + 100) # +100 МБ запас
if (-not (Test-FreeSpace -Path $Destination -RequiredSpaceMB $requiredSpace)) { if (-not (Test-FreeSpace -Path $Destination -RequiredSpaceMB $requiredSpace)) {
Write-Log "Недостаточно места для копирования. Операция отменена." -Type "ERROR" Write-Log "Недостаточно места для копирования. Операция отменена." -Type "ERROR"
return $false return $false
} }
# СОЗДАЕМ ПАПКУ НАЗНАЧЕНИЯ (ключевое изменение!) # СОЗДАЕМ ПАПКУ НАЗНАЧЕНИЯ (ключевое изменение!)
if (-not (New-BackupFolder -FolderPath $Destination)) { if (-not (New-BackupFolder -FolderPath $Destination)) {
return $false return $false
} }
# Получаем список всех профилей в папке Profiles # Получаем список всех профилей в папке Profiles
$profiles = Get-ChildItem -Path $Source -Directory -ErrorAction SilentlyContinue $profiles = Get-ChildItem -Path $Source -Directory -ErrorAction SilentlyContinue
if ($profiles.Count -eq 0) { if ($profiles.Count -eq 0) {
Write-Log "В папке Profiles не найдено профилей!" -Type "WARNING" Write-Log "В папке Profiles не найдено профилей!" -Type "WARNING"
Write-Log "Проверяем наличие файлов напрямую..." -Type "INFO" Write-Log "Проверяем наличие файлов напрямую..." -Type "INFO"
# Если нет подпапок, возможно копируем содержимое самой папки Profiles # Если нет подпапок, возможно копируем содержимое самой папки Profiles
$files = Get-ChildItem -Path $Source -File $files = Get-ChildItem -Path $Source -File
if ($files.Count -gt 0) { if ($files.Count -gt 0) {
Write-Log "Найдены файлы в корне папки Profiles, копируем их" -Type "INFO" Write-Log "Найдены файлы в корне папки Profiles, копируем их" -Type "INFO"
# Пытаемся скопировать содержимое папки Profiles # Пытаемся скопировать содержимое папки Profiles
$robocopyArgs = @( $robocopyArgs = @(
"`"$Source`"", "`"$Source`"",
"`"$Destination`"", "`"$Destination`"",
"/E", # Копировать подпапки, включая пустые "/E", # Копировать подпапки, включая пустые
"/COPY:DAT", # Копировать данные, атрибуты, временные метки "/COPY:DAT", # Копировать данные, атрибуты, временные метки
"/R:3", # Retry count "/R:3", # Retry count
"/W:5", # Wait time "/W:5", # Wait time
"/NP", # No Progress "/NP", # No Progress
"/NJH", # No Job Header "/NJH", # No Job Header
"/NJS" # No Job Summary "/NJS" # No Job Summary
) )
try { try {
$robocopyResult = Start-Process -FilePath "robocopy.exe" -ArgumentList $robocopyArgs -Wait -PassThru -NoNewWindow $robocopyResult = Start-Process -FilePath "robocopy.exe" -ArgumentList $robocopyArgs -Wait -PassThru -NoNewWindow
if ($robocopyResult.ExitCode -ge 8) { if ($robocopyResult.ExitCode -ge 8) {
throw "Robocopy завершился с ошибкой. Код: $($robocopyResult.ExitCode)" throw "Robocopy завершился с ошибкой. Код: $($robocopyResult.ExitCode)"
} }
Write-Log "Файлы скопированы" -Type "SUCCESS" Write-Log "Файлы скопированы" -Type "SUCCESS"
return $true return $true
} catch { } catch {
Write-Log "Ошибка при копировании: $_" -Type "ERROR" Write-Log "Ошибка при копировании: $_" -Type "ERROR"
return $false return $false
} }
} else { } else {
Write-Log "Папка Profiles пуста" -Type "WARNING" Write-Log "Папка Profiles пуста" -Type "WARNING"
return $false return $false
} }
} }
# Копируем каждый профиль с повторами при ошибках # Копируем каждый профиль с повторами при ошибках
$attempt = 1 $attempt = 1
$allCopied = $false $allCopied = $false
while ($attempt -le $CopyRetryCount -and -not $allCopied) { while ($attempt -le $CopyRetryCount -and -not $allCopied) {
try { try {
Write-Log "Попытка копирования #$attempt из $CopyRetryCount..." Write-Log "Попытка копирования #$attempt из $CopyRetryCount..."
$successCount = 0 $successCount = 0
$failCount = 0 $failCount = 0
foreach ($profile in $profiles) { foreach ($profile in $profiles) {
$profileName = $profile.Name $profileName = $profile.Name
$sourceProfilePath = $profile.FullName $sourceProfilePath = $profile.FullName
$destProfilePath = Join-Path -Path $Destination -ChildPath $profileName $destProfilePath = Join-Path -Path $Destination -ChildPath $profileName
Write-Log " Копирование профиля: $profileName" Write-Log " Копирование профиля: $profileName"
# Используем Robocopy для надежного копирования # Используем Robocopy для надежного копирования
$robocopyArgs = @( $robocopyArgs = @(
"`"$sourceProfilePath`"", "`"$sourceProfilePath`"",
"`"$destProfilePath`"", "`"$destProfilePath`"",
"/MIR", # Mirror (точная копия) "/MIR", # Mirror (точная копия)
"/R:3", # Retry count (3 повтора при ошибке) "/R:3", # Retry count (3 повтора при ошибке)
"/W:5", # Wait time between retries (5 сек) "/W:5", # Wait time between retries (5 сек)
"/NP", # No Progress (чтобы не засорять вывод) "/NP", # No Progress (чтобы не засорять вывод)
"/NJH", # No Job Header "/NJH", # No Job Header
"/NJS" # No Job Summary "/NJS" # No Job Summary
) )
Write-Log " Команда: robocopy $sourceProfilePath $destProfilePath /MIR /R:3 /W:5" -Type "INFO" Write-Log " Команда: robocopy $sourceProfilePath $destProfilePath /MIR /R:3 /W:5" -Type "INFO"
$robocopyResult = Start-Process -FilePath "robocopy.exe" -ArgumentList $robocopyArgs -Wait -PassThru -NoNewWindow $robocopyResult = Start-Process -FilePath "robocopy.exe" -ArgumentList $robocopyArgs -Wait -PassThru -NoNewWindow
# Robocopy возвращает коды: 0-7 - успех, 8+ - ошибка # Robocopy возвращает коды: 0-7 - успех, 8+ - ошибка
if ($robocopyResult.ExitCode -ge 8) { if ($robocopyResult.ExitCode -ge 8) {
Write-Log " Robocopy завершился с ошибкой. Код: $($robocopyResult.ExitCode)" -Type "ERROR" Write-Log " Robocopy завершился с ошибкой. Код: $($robocopyResult.ExitCode)" -Type "ERROR"
$failCount++ $failCount++
} else { } else {
Write-Log " Профиль $profileName скопирован (код: $($robocopyResult.ExitCode))" -Type "SUCCESS" Write-Log " Профиль $profileName скопирован (код: $($robocopyResult.ExitCode))" -Type "SUCCESS"
$successCount++ $successCount++
} }
} }
if ($failCount -eq 0) { if ($failCount -eq 0) {
$allCopied = $true $allCopied = $true
Write-Log "Все профили успешно скопированы! ($successCount профилей)" -Type "SUCCESS" Write-Log "Все профили успешно скопированы! ($successCount профилей)" -Type "SUCCESS"
} else { } else {
Write-Log "Скопировано: $successCount, Ошибок: $failCount" -Type "WARNING" Write-Log "Скопировано: $successCount, Ошибок: $failCount" -Type "WARNING"
if ($attempt -lt $CopyRetryCount) { if ($attempt -lt $CopyRetryCount) {
Write-Log "Повторная попытка через 5 секунд..." -Type "INFO" Write-Log "Повторная попытка через 5 секунд..." -Type "INFO"
Start-Sleep -Seconds 5 Start-Sleep -Seconds 5
} }
} }
} catch { } catch {
Write-Log "Ошибка при копировании (попытка $attempt): $_" -Type "ERROR" Write-Log "Ошибка при копировании (попытка $attempt): $_" -Type "ERROR"
$failCount = $profiles.Count $failCount = $profiles.Count
} }
$attempt++ $attempt++
} }
return ($allCopied -or ($successCount -gt 0)) return ($allCopied -or ($successCount -gt 0))
} }
# Функция для создания информационного файла о бэкапе # Функция для создания информационного файла о бэкапе
function New-BackupInfoFile { function New-BackupInfoFile {
param( param(
[string]$BackupPath, [string]$BackupPath,
[string]$SourcePath [string]$SourcePath
) )
try { try {
$infoFile = Join-Path -Path $BackupPath -ChildPath "_backup_info.txt" $infoFile = Join-Path -Path $BackupPath -ChildPath "_backup_info.txt"
$computerInfo = @( $computerInfo = @(
"# Информация о резервной копии Thunderbird", "# Информация о резервной копии Thunderbird",
"Дата создания: $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss')", "Дата создания: $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss')",
"Компьютер: $env:COMPUTERNAME", "Компьютер: $env:COMPUTERNAME",
"Пользователь: $env:USERNAME", "Пользователь: $env:USERNAME",
"Исходная папка: $SourcePath", "Исходная папка: $SourcePath",
"Размер исходной папки: $(Get-FolderSize -Path $SourcePath) MB", "Размер исходной папки: $(Get-FolderSize -Path $SourcePath) MB",
"---", "---",
"Создано скриптом: $($MyInvocation.MyCommand.Path)" "Создано скриптом: $($MyInvocation.MyCommand.Path)"
) )
$computerInfo | Out-File -FilePath $infoFile -Encoding UTF8 $computerInfo | Out-File -FilePath $infoFile -Encoding UTF8
Write-Log "Создан информационный файл: _backup_info.txt" -Type "INFO" Write-Log "Создан информационный файл: _backup_info.txt" -Type "INFO"
} catch { } catch {
Write-Log "Не удалось создать информационный файл: $_" -Type "WARNING" Write-Log "Не удалось создать информационный файл: $_" -Type "WARNING"
} }
} }
# === ОСНОВНАЯ ЧАСТЬ СКРИПТА === # === ОСНОВНАЯ ЧАСТЬ СКРИПТА ===
Clear-Host Clear-Host
Write-Log "===================================================" -Type "INFO" Write-Log "===================================================" -Type "INFO"
Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ ПРОФИЛЯ THUNDERBIRD" -Type "INFO" Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ ПРОФИЛЯ THUNDERBIRD" -Type "INFO"
Write-Log "===================================================" -Type "INFO" Write-Log "===================================================" -Type "INFO"
Write-Log "" Write-Log ""
# 1. Проверяем и создаем корневую папку для бэкапов, если нужно # 1. Проверяем и создаем корневую папку для бэкапов, если нужно
Write-Log "Проверка корневой папки для бэкапов: $BackupRoot" -Type "INFO" Write-Log "Проверка корневой папки для бэкапов: $BackupRoot" -Type "INFO"
New-BackupFolder -FolderPath $BackupRoot | Out-Null New-BackupFolder -FolderPath $BackupRoot | Out-Null
Write-Log "" Write-Log ""
# 2. Проверяем наличие исходной папки # 2. Проверяем наличие исходной папки
if (-not (Test-Path $SourceProfilePath)) { if (-not (Test-Path $SourceProfilePath)) {
Write-Log "Исходная папка не найдена: $SourceProfilePath" -Type "ERROR" Write-Log "Исходная папка не найдена: $SourceProfilePath" -Type "ERROR"
Write-Log "Проверьте путь и права доступа" -Type "INFO" Write-Log "Проверьте путь и права доступа" -Type "INFO"
exit 1 exit 1
} }
# 3. Закрываем Thunderbird # 3. Закрываем Thunderbird
Write-Log "Этап 1: Закрытие Thunderbird" -Type "INFO" Write-Log "Этап 1: Закрытие Thunderbird" -Type "INFO"
Write-Log "------------------------------" -Type "INFO" Write-Log "------------------------------" -Type "INFO"
$closed = Stop-ThunderbirdGracefully $closed = Stop-ThunderbirdGracefully
Write-Log "" Write-Log ""
# 4. Небольшая пауза для гарантии # 4. Небольшая пауза для гарантии
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
# 5. Копируем профили # 5. Копируем профили
Write-Log "Этап 2: Копирование профилей" -Type "INFO" Write-Log "Этап 2: Копирование профилей" -Type "INFO"
Write-Log "-----------------------------" -Type "INFO" Write-Log "-----------------------------" -Type "INFO"
$copySuccess = Copy-ThunderbirdProfile -Source $SourceProfilePath -Destination $BackupDestination $copySuccess = Copy-ThunderbirdProfile -Source $SourceProfilePath -Destination $BackupDestination
Write-Log "" Write-Log ""
# 6. Создаем информационный файл (если копирование успешно) # 6. Создаем информационный файл (если копирование успешно)
if ($copySuccess) { if ($copySuccess) {
New-BackupInfoFile -BackupPath $BackupDestination -SourcePath $SourceProfilePath New-BackupInfoFile -BackupPath $BackupDestination -SourcePath $SourceProfilePath
# 7. Итог # 7. Итог
Write-Log "===================================================" -Type "SUCCESS" Write-Log "===================================================" -Type "SUCCESS"
Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ УСПЕШНО ЗАВЕРШЕНО" -Type "SUCCESS" Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ УСПЕШНО ЗАВЕРШЕНО" -Type "SUCCESS"
Write-Log "===================================================" -Type "SUCCESS" Write-Log "===================================================" -Type "SUCCESS"
Write-Log "Папка с резервной копией: $BackupDestination" -Type "INFO" Write-Log "Папка с резервной копией: $BackupDestination" -Type "INFO"
# Показываем содержимое папки с бэкапом # Показываем содержимое папки с бэкапом
if (Test-Path $BackupDestination) { if (Test-Path $BackupDestination) {
$items = Get-ChildItem -Path $BackupDestination $items = Get-ChildItem -Path $BackupDestination
Write-Log "Содержимое папки с бэкапом:" -Type "INFO" Write-Log "Содержимое папки с бэкапом:" -Type "INFO"
foreach ($item in $items) { foreach ($item in $items) {
$itemSize = if ($item.PSIsContainer) { $itemSize = if ($item.PSIsContainer) {
"<папка>" "<папка>"
} else { } else {
"$([math]::Round($item.Length / 1KB, 2)) KB" "$([math]::Round($item.Length / 1KB, 2)) KB"
} }
Write-Log " - $($item.Name) ($itemSize)" -Type "INFO" Write-Log " - $($item.Name) ($itemSize)" -Type "INFO"
} }
} }
# Предложение открыть папку # Предложение открыть папку
$openFolder = Read-Host "`nОткрыть папку с резервной копией? (Y/N)" $openFolder = Read-Host "`nОткрыть папку с резервной копией? (Y/N)"
if ($openFolder -eq "Y" -or $openFolder -eq "y") { if ($openFolder -eq "Y" -or $openFolder -eq "y") {
Invoke-Item $BackupDestination Invoke-Item $BackupDestination
} }
} else { } else {
Write-Log "===================================================" -Type "ERROR" Write-Log "===================================================" -Type "ERROR"
Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ ЗАВЕРШИЛОСЬ С ОШИБКАМИ" -Type "ERROR" Write-Log " РЕЗЕРВНОЕ КОПИРОВАНИЕ ЗАВЕРШИЛОСЬ С ОШИБКАМИ" -Type "ERROR"
Write-Log "===================================================" -Type "ERROR" Write-Log "===================================================" -Type "ERROR"
exit 1 exit 1
} }
# Для запуска с параметрами командной строки (раскомментируйте если нужно): # Для запуска с параметрами командной строки (раскомментируйте если нужно):
# param( # param(
# [string]$BackupPath = "D:\Backups\Thunderbird\$(Get-Date -Format 'yyyy-MM-dd')" # [string]$BackupPath = "D:\Backups\Thunderbird\$(Get-Date -Format 'yyyy-MM-dd')"
# ) # )
# $BackupDestination = $BackupPath # $BackupDestination = $BackupPath