This commit is contained in:
2025-10-22 10:25:44 +01:00
parent 907449914a
commit e576ee3954

View File

@@ -1,19 +1,36 @@
param( param(
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
[string]$SqlInstance [string]$SqlInstance,
[Parameter(Mandatory=$false)]
[string]$Directory,
[Parameter(Mandatory=$false)]
[switch]$Force
) )
# #
# backup.ps1 # backup.ps1
# #
# TODO: Update cleanup time based on backup type # TODO: Parallelize backups for multiple DBs in the instance
# TODO: Use PowerShell SQL module instead of sqlcmd
$instanceName = $SqlInstance.Split('\')[1] $instanceName = $SqlInstance.Split('\')[1]
$directory = "C:\Rubrik\$instanceName" # Use provided directory parameter or default to instance-based path
if ($Directory) {
$directory = $Directory
Write-Host "INFO: Using provided directory: $directory"
} else {
$directory = "C:\Rubrik\$instanceName"
Write-Host "INFO: Using default directory: $directory"
}
$fullBackupDay = 'Thursday' $fullBackupDay = 'Thursday'
$fullBackupOverdueDays = 7 # Force full backup if last full backup is older than this many days
$checkCluster = $false $checkCluster = $false
$logFile = "C:\Rubrik\backup-$instanceName.log" #$logFile = "C:\Rubrik\backup-$instanceName.log"
$logFile = "H:\Backup\backup-$instanceName.log"
$fullFlag = $directory + "\last_full.flag" $fullFlag = $directory + "\last_full.flag"
$diffFlag = $directory + "\last_diff.flag" $diffFlag = $directory + "\last_diff.flag"
@@ -27,6 +44,35 @@ function FlagTakenToday($flagPath) {
return $false return $false
} }
function GetLastFullBackupDate($flagPath) {
if (Test-Path $flagPath) {
$flagDate = (Get-Content $flagPath | Out-String).Trim()
try {
return [DateTime]::ParseExact($flagDate, "yyyy-MM-dd", $null)
}
catch {
Write-Log "WARNING: Could not parse last full backup date from flag file: $flagDate"
return $null
}
}
return $null
}
function IsFullBackupOverdue($flagPath, $overdueDays) {
$lastFullDate = GetLastFullBackupDate $flagPath
if ($null -eq $lastFullDate) {
Write-Log "WARNING: No last full backup date found. Full backup is considered overdue."
return $true
}
$daysSinceLastFull = ($today - $lastFullDate).Days
$isOverdue = $daysSinceLastFull -gt $overdueDays
Write-Log "INFO: Last full backup was $daysSinceLastFull days ago on $($lastFullDate.ToString('yyyy-MM-dd')). Overdue threshold: $overdueDays days."
return $isOverdue
}
function Write-Log($message) { function Write-Log($message) {
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "$timestamp $message" $logEntry = "$timestamp $message"
@@ -34,20 +80,23 @@ function Write-Log($message) {
Write-Host $logEntry Write-Host $logEntry
} }
# Check if directory exists and is a symbolic link # Check if directory exists and is a symbolic link (unless -Force is specified)
if (-not (Test-Path $directory)) { if (-not (Test-Path $directory)) {
Write-Log "ERROR: Directory '$directory' does not exist. Exiting script." Write-Log "ERROR: Directory '$directory' does not exist. Exiting script."
exit 1 exit 1
} }
$directoryInfo = Get-Item $directory if (-not $Force) {
if (-not ($directoryInfo.Attributes -band [System.IO.FileAttributes]::ReparsePoint)) { $directoryInfo = Get-Item $directory
Write-Log "ERROR: Directory '$directory' is not a symbolic link. Exiting script." if (-not ($directoryInfo.Attributes -band [System.IO.FileAttributes]::ReparsePoint)) {
exit 1 Write-Log "ERROR: Directory '$directory' is not a symbolic link. Exiting script."
exit 1
}
Write-Log "INFO: Directory '$directory' exists and is a symbolic link. Target: $($directoryInfo.Target). Proceeding."
} else {
Write-Log "INFO: Force parameter specified. Skipping symbolic link check for directory '$directory'."
} }
Write-Log "INFO: Directory '$directory' exists and is a symbolic link. Target: $($directoryInfo.Target). Proceeding."
if ($checkCluster) { if ($checkCluster) {
# Check if SQL instance is running locally # Check if SQL instance is running locally
$localNode = $env:COMPUTERNAME $localNode = $env:COMPUTERNAME
@@ -69,17 +118,31 @@ if ($checkCluster) {
Write-Log "INFO: Cluster check is disabled. Proceeding without verification." Write-Log "INFO: Cluster check is disabled. Proceeding without verification."
} }
# Check if full backup is overdue regardless of the day
$isFullBackupOverdue = IsFullBackupOverdue $fullFlag $fullBackupOverdueDays
if ((Get-Date).DayOfWeek -eq $fullBackupDay) { if ((Get-Date).DayOfWeek -eq $fullBackupDay) {
if (-not (FlagTakenToday $fullFlag)) { if (-not (FlagTakenToday $fullFlag)) {
$backupType = "FULL" $backupType = "FULL"
$cleanupTime = 168 $cleanupTime = 168
Set-Content $fullFlag $today.ToString("yyyy-MM-dd") Set-Content $fullFlag $today.ToString("yyyy-MM-dd")
Write-Log "Selected FULL backup. Flag updated." Write-Log "Selected FULL backup (scheduled day). Flag updated."
} else { } else {
$backupType = "LOG" $backupType = "LOG"
$cleanupTime = 24 $cleanupTime = 24
Write-Log "FULL backup already taken today. Selected LOG backup." Write-Log "FULL backup already taken today. Selected LOG backup."
} }
} elseif ($isFullBackupOverdue) {
if (-not (FlagTakenToday $fullFlag)) {
$backupType = "FULL"
$cleanupTime = 168
Set-Content $fullFlag $today.ToString("yyyy-MM-dd")
Write-Log "Selected FULL backup (overdue - forcing full backup). Flag updated."
} else {
$backupType = "LOG"
$cleanupTime = 24
Write-Log "FULL backup already taken today (was overdue). Selected LOG backup."
}
} else { } else {
if (-not (FlagTakenToday $diffFlag)) { if (-not (FlagTakenToday $diffFlag)) {
$backupType = "DIFF" $backupType = "DIFF"