<# .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