<# .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 i przygotowywanie docelowego folderu na S3: $S3DestinationParent/$CurrentYear/" -ForegroundColor Gray # 1. Tworzenie folderu na S3 (rclone mkdir upewni się, że struktura istnieje) # Tłumimy ostrzeżenie (2>$null), ponieważ S3 to "object storage" i ostrzega, że nie obsługuje pustych folderów. & $RcloneExePath mkdir "$S3Destination" 2>$null Write-Host " Folder gotowy. Rozpoczynam transfer danych..." -ForegroundColor Green $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