Files
DBAdmin/toolbox/s3_backup_transfer.ps1
T
Paweł Domański 1c1037b6ab Jul 2, 2026, 9:33 AM
2026-07-02 07:33:30 +00:00

146 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.
.PARAMETER RcloneRemote
Nazwa połączenia rclone (remote) zakończona dwukropkiem.
Domyślnie: 's3-backup-remote:'
#>
param(
[string]$FolderName
)
$ErrorActionPreference = "Stop"
# ========================================================
# KONFIGURACJA
# ========================================================
$RcloneExePath = "C:\DBAdmin\rclone.exe"# Zmień na właściwą ścieżkę do rclone.exe
$BaseSourceDir = "H:\month" # Katalog główny z backupami baz danych
$S3BasePath = "backup-s3-ovh-ch/Switzerland_SQLServer_DB_Backups/Month"
$LogDir = "C:\DBAdmin\logs"
$CurrentYear = (Get-Date).Year.ToString()
$RcloneRemote = "ovh:"
# 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