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