Files
DBAdmin/toolbox/s3_backup_transfer.ps1
T
Paweł Domański 111c042bef Jul 2, 2026, 9:10 AM
2026-07-02 07:10:19 +00:00

144 lines
5.9 KiB
PowerShell

<#
.SYNOPSIS
Skrypt do bezpiecznego przenoszenia backupów SQL na S3 przy użyciu rclone.
.DESCRIPTION
Używa operacji 'rclone move', aby najpierw bezpiecznie skopiować pliki na S3,
zweryfikować je, a następnie usunąć z lokalnego dysku serwera.
W przypadku błędu raportuje zdarzenie do Windows Event Log.
.PARAMETER FolderName
Nazwa folderu z backupami do przesłania. Może to być nazwa konkretnego folderu
(np. 'BISW12PFASTA02') lub słowo 'all', aby przesłać wszystkie foldery.
Jeśli parametr nie zostanie podany, skrypt wyświetli listę dostępnych folderów.
#>
param(
[string]$FolderName
)
$ErrorActionPreference = "Stop"
# ========================================================
# KONFIGURACJA
# ========================================================
$RcloneExePath = "C:\ProgramData\chocolatey\bin\rclone.exe" # Zmień na właściwą ścieżkę do rclone.exe
$BaseSourceDir = "H:\month" # Katalog główny z backupami baz danych
$RcloneRemote = "s3-backup-remote:" # Nazwa skonfigurowanego remote (z rclone config)
$S3BasePath = "backup-s3-ovh-ch/Switzerland_SQLServer_DB_Backups/Month"
$LogDir = "C:\DBAdmin\logs"
$CurrentYear = (Get-Date).Year.ToString()
# Upewnij się, że katalog logów istnieje
if (-not (Test-Path $LogDir)) {
New-Item -Path $LogDir -ItemType Directory -Force | Out-Null
}
# ========================================================
# WALIDACJA PARAMETRÓW I WYBÓR FOLDERÓW
# ========================================================
if (-not (Test-Path $BaseSourceDir)) {
Write-Host "BŁĄD: Katalog bazowy $BaseSourceDir nie istnieje." -ForegroundColor Red
exit 1
}
$AvailableFolders = Get-ChildItem -Path $BaseSourceDir -Directory | Select-Object -ExpandProperty Name
if ([string]::IsNullOrWhiteSpace($FolderName)) {
Write-Host "Nie podano parametru z nazwą folderu." -ForegroundColor Yellow
Write-Host "Dostępne opcje to:" -ForegroundColor Cyan
Write-Host " all (aby przenieść wszystkie poniższe foldery)" -ForegroundColor Green
foreach ($folder in $AvailableFolders) {
Write-Host " $folder"
}
Write-Host "`nPrzykład użycia:"
Write-Host " .\s3_backup_transfer.ps1 -FolderName BISW12PSQLDB01"
Write-Host " .\s3_backup_transfer.ps1 -FolderName all"
exit 0
}
$FoldersToProcess = @()
if ($FolderName -eq "all") {
$FoldersToProcess = $AvailableFolders
Write-Host "Wybrano przeniesienie WSZYSTKICH folderów z $BaseSourceDir." -ForegroundColor Cyan
} else {
if ($AvailableFolders -contains $FolderName) {
$FoldersToProcess = @($FolderName)
Write-Host "Wybrano przeniesienie folderu: $FolderName." -ForegroundColor Cyan
} else {
Write-Host "BŁĄD: Folder '$FolderName' nie istnieje w $BaseSourceDir." -ForegroundColor Red
Write-Host "Dostępne foldery:"
$AvailableFolders | ForEach-Object { Write-Host " $_" }
exit 1
}
}
# Funkcja pomocnicza do logowania zdarzeń
function Write-AppEventLog {
param([string]$Type, [int]$Id, [string]$Message)
$EventSource = "SQLBackupToS3"
if (-not [System.Diagnostics.EventLog]::SourceExists($EventSource)) {
try { New-EventLog -LogName Application -Source $EventSource } catch { }
}
try { Write-EventLog -LogName Application -Source $EventSource -EntryType $Type -EventId $Id -Message $Message } catch { }
}
# ========================================================
# URUCHOMIENIE TRANSFERU DLA WYBRANYCH FOLDERÓW
# ========================================================
$GlobalExitCode = 0
foreach ($folder in $FoldersToProcess) {
$SourceDir = Join-Path $BaseSourceDir $folder
$S3DestinationParent = "$RcloneRemote$S3BasePath/$folder"
$S3Destination = "$S3DestinationParent/$CurrentYear"
Write-Host "`n[$(Get-Date -Format 'HH:mm:ss')] Przetwarzanie: $folder ..." -ForegroundColor Yellow
Write-Host " Sprawdzanie istnienia docelowego folderu na S3: $S3DestinationParent/$CurrentYear/" -ForegroundColor Gray
# Walidacja obecności folderu (roku) po stronie S3 za pomocą rclone lsf (wypisuje tylko foldery)
$s3Dirs = & $RcloneExePath lsf --dirs-only "$S3DestinationParent/" 2>$null
if ($s3Dirs -notcontains "$CurrentYear/") {
$errMsg = "Brak wymaganego folderu '$CurrentYear/' w lokalizacji '$S3DestinationParent/' na S3. Pomijam transfer."
Write-Host " Błąd: $errMsg" -ForegroundColor Red
Write-AppEventLog -Type Warning -Id 1002 -Message $errMsg
$GlobalExitCode = 1
continue
}
Write-Host " Folder '$CurrentYear/' znaleziony. Rozpoczynam transfer danych..." -ForegroundColor Green
$LogFile = Join-Path $LogDir "rclone_backup_$($folder)_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
$RcloneArgs = @(
"move", $SourceDir, $S3Destination,
"--checksum",
"--retries", "5",
"--retries-sleep", "15s",
"--delete-empty-src-dirs",
"--log-file=$LogFile",
"--log-level=INFO"
)
# Uruchomienie rclone
& $RcloneExePath $RcloneArgs
$RcloneExitCode = $LASTEXITCODE
if ($RcloneExitCode -eq 0) {
$successMsg = "Pomyślnie przeniesiono folder $folder na S3. Log: $LogFile"
Write-Host " Sukces: $folder" -ForegroundColor Green
Write-AppEventLog -Type Information -Id 1000 -Message $successMsg
} else {
$errorMsg = "Błąd przenoszenia folderu $folder. Kod wyjścia rclone: $RcloneExitCode. Log: $LogFile"
Write-Host " Błąd: $folder (Kod $RcloneExitCode)" -ForegroundColor Red
Write-AppEventLog -Type Error -Id 1001 -Message $errorMsg
$GlobalExitCode = 1
}
}
Write-Host "`nProces zakończony."
if ($GlobalExitCode -ne 0) {
Write-Host "Wystąpiły błędy podczas transferu niektórych folderów lub brakowało docelowych katalogów na S3. Sprawdź logi." -ForegroundColor Red
}
exit $GlobalExitCode