Files
DBAdmin/toolbox/s3_backup_transfer.ps1
Paweł Domański 03cad97b75 Jul 2, 2026, 9:43 AM
2026-07-02 07:43:37 +00:00

153 lines
6.2 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"
try {
if (-not [System.Diagnostics.EventLog]::SourceExists($EventSource)) {
New-EventLog -LogName Application -Source $EventSource
}
Write-EventLog -LogName Application -Source $EventSource -EntryType $Type -EventId $Id -Message $Message
} catch {
# Ignorujemy błędy EventLog (np. brak uprawnień administratora)
# Informacja i tak została już wypisana na ekran przez Write-Host
}
}
# ========================================================
# 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 struktury docelowej na S3: $S3DestinationParent/" -ForegroundColor Gray
# Sprawdzamy czy folder roczny istnieje, wyłącznie w celach informacyjnych.
# W S3 foldery tworzą się same automatycznie w momencie wgrania pierwszego pliku.
$s3Dirs = & $RcloneExePath lsf --dirs-only "$S3DestinationParent/" 2>$null
if ($s3Dirs -contains "$CurrentYear/") {
Write-Host " Folder '$CurrentYear/' istnieje na S3. Aktualizowanie danych..." -ForegroundColor Green
} else {
Write-Host " Folder '$CurrentYear/' nie istnieje na S3. Zostanie utworzony automatycznie podczas pierwszego transferu." -ForegroundColor Cyan
}
$LogFile = Join-Path $LogDir "rclone_backup_$($folder)_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
# 2, 3, 4. Pokazywanie progresu, wypisywanie plików i logowanie
# --progress (-P) - pokazuje interaktywny pasek postępu i prędkość
# --verbose (-v) - wypisuje nazwy przenoszonych plików
$RcloneArgs = @(
"move", $SourceDir, $S3Destination,
"--checksum",
"--retries", "5",
"--retries-sleep", "15s",
"--delete-empty-src-dirs",
"--progress",
"--verbose",
"--log-file=$LogFile"
)
# 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