diff --git a/RestoreScript.ps1 b/RestoreScript.ps1 index 374ad9f..8dbc526 100644 --- a/RestoreScript.ps1 +++ b/RestoreScript.ps1 @@ -1,6 +1,6 @@ param( [Parameter(Mandatory=$true)] - [string]$FolderPath, + [string]$LiveMountRoot, [Parameter(Mandatory=$false)] [string]$DatabaseName, @@ -25,13 +25,30 @@ function Catalog-Backups { $baseName = $file.BaseName $parts = $baseName -split '_' if ($parts.Length -lt 4) { continue } - $dbName = $parts[1] - $type = $parts[2] - $dateStr = $parts[3] - $timeStr = $parts[4] + + # Find the type position (FULL, DIFF, LOG) + $typeIndex = -1 + $validTypes = @('FULL', 'DIFF', 'LOG') + for ($i = 0; $i -lt $parts.Length; $i++) { + if ($validTypes -contains $parts[$i]) { + $typeIndex = $i + break + } + } + if ($typeIndex -eq -1 -or ($parts.Length - $typeIndex) -lt 3) { continue } + + # Assume parts[0] is prefix if typeIndex > 1, else dbName is parts[0] + if ($typeIndex -eq 1) { + $dbName = $parts[0] + } else { + $dbName = $parts[1..($typeIndex-1)] -join '_' + } + $type = $parts[$typeIndex] + $dateStr = $parts[$typeIndex + 1] + $timeStr = $parts[$typeIndex + 2] $stripe = 0 - if ($parts.Length -gt 5) { - $stripe = [int]$parts[5] + if ($parts.Length -gt $typeIndex + 3) { + $stripe = [int]$parts[$typeIndex + 3] } $key = "$dateStr$timeStr" @@ -143,15 +160,47 @@ function Verify-Backups { } catch { Write-Host "Verification failed for $type $key : $($_.Exception.Message)" } + + # Get backup header information + $header = Get-BackupInfo -Files $files -Instance $Instance + if ($header) { + Write-Host " Backup Details:" + Write-Host " Start Date: $($header.BackupStartDate)" + Write-Host " Finish Date: $($header.BackupFinishDate)" + Write-Host " First LSN: $($header.FirstLSN)" + Write-Host " Last LSN: $($header.LastLSN)" + if ($header.DatabaseBackupLSN) { + Write-Host " Database Backup LSN: $($header.DatabaseBackupLSN)" + } + if ($header.DifferentialBaseLSN) { + Write-Host " Differential Base LSN: $($header.DifferentialBaseLSN)" + } + } } } Write-Host "" } } +# Function to get backup header information +function Get-BackupInfo { + param([System.IO.FileInfo[]]$Files, [string]$Instance) + + $fileList = $Files | ForEach-Object { "DISK = '$($_.FullName)'" } + $headerQuery = "RESTORE HEADERONLY FROM $($fileList -join ', ')" + + try { + $header = Invoke-Sqlcmd -ServerInstance $Instance -Query $headerQuery -QueryTimeout 0 + return $header + } catch { + Write-Warning "Failed to get header for $($Files[0].Name): $($_.Exception.Message)" + return $null + } +} + # Main script if ($Action -eq "catalog") { - $catalog = Catalog-Backups -Path $FolderPath + $catalog = Catalog-Backups -Path $LiveMountRoot if ($DatabaseName) { $filteredCatalog = @{} if ($catalog.ContainsKey($DatabaseName)) { @@ -167,10 +216,10 @@ if ($Action -eq "catalog") { exit 1 } - $catalog = Catalog-Backups -Path $FolderPath + $catalog = Catalog-Backups -Path $LiveMountRoot Restore-Database -DbName $DatabaseName -Catalog $catalog -Instance $SqlInstance } elseif ($Action -eq "verify") { - $catalog = Catalog-Backups -Path $FolderPath + $catalog = Catalog-Backups -Path $LiveMountRoot if ($DatabaseName) { $filteredCatalog = @{} if ($catalog.ContainsKey($DatabaseName)) {