Use SQL PS module
This commit is contained in:
120
backup.ps1
120
backup.ps1
@@ -9,11 +9,36 @@ param(
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
#
|
||||
# backup.ps1
|
||||
#
|
||||
# TODO: Parallelize backups for multiple DBs in the instance
|
||||
# TODO: Use PowerShell SQL module instead of sqlcmd
|
||||
|
||||
# Import SQL Server PowerShell module
|
||||
try {
|
||||
# Try to import the newer SqlServer module first
|
||||
if (Get-Module -ListAvailable -Name SqlServer) {
|
||||
Import-Module SqlServer -ErrorAction Stop
|
||||
Write-Host "INFO: SqlServer PowerShell module loaded successfully."
|
||||
}
|
||||
# Fall back to older SQLPS module if available
|
||||
elseif (Get-Module -ListAvailable -Name SQLPS) {
|
||||
Import-Module SQLPS -ErrorAction Stop
|
||||
Write-Host "INFO: SQLPS PowerShell module loaded successfully."
|
||||
}
|
||||
else {
|
||||
throw "No SQL Server PowerShell module found"
|
||||
}
|
||||
|
||||
# Verify Invoke-Sqlcmd is available
|
||||
if (-not (Get-Command Invoke-Sqlcmd -ErrorAction SilentlyContinue)) {
|
||||
throw "Invoke-Sqlcmd command not available"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "ERROR: Failed to import SQL Server PowerShell module. Please install it using: Install-Module -Name SqlServer -AllowClobber"
|
||||
Write-Host "ERROR: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$instanceName = $SqlInstance.Split('\')[1]
|
||||
|
||||
@@ -158,16 +183,89 @@ if ((Get-Date).DayOfWeek -eq $fullBackupDay) {
|
||||
|
||||
$query = "EXECUTE [dbo].[DatabaseBackup] @Databases = 'ALL_DATABASES', @Directory = '$directory', @BackupType = '$backupType', @Verify = 'N', @CleanupTime = $cleanupTime, @CheckSum = 'Y', @LogToTable = 'Y'"
|
||||
Write-Log "Executing backup type: $backupType"
|
||||
Write-Log "SQL Query: $query"
|
||||
|
||||
$sqlcmdOutput = & sqlcmd -S $SqlInstance -Q $query 2>&1
|
||||
$sqlcmdExitCode = $LASTEXITCODE
|
||||
|
||||
if ($sqlcmdExitCode -eq 0) {
|
||||
foreach ($line in $sqlcmdOutput) {
|
||||
Write-Log $line
|
||||
try {
|
||||
# Execute the backup using PowerShell SQL module with better error handling
|
||||
# Capture verbose output from Ola H scripts
|
||||
$infoMessages = @()
|
||||
|
||||
# Create event handlers to capture SQL Server messages
|
||||
$connection = New-Object System.Data.SqlClient.SqlConnection
|
||||
$connection.ConnectionString = "Server=$SqlInstance;Integrated Security=true;Connection Timeout=30"
|
||||
|
||||
# Event handler for informational messages (PRINT statements)
|
||||
$connection.add_InfoMessage({
|
||||
param($sqlSender, $e)
|
||||
$message = $e.Message
|
||||
if ($message -and $message.Trim() -ne "") {
|
||||
$script:infoMessages += $message
|
||||
Write-Log "SQL INFO: $message"
|
||||
}
|
||||
})
|
||||
|
||||
try {
|
||||
$connection.Open()
|
||||
|
||||
$command = New-Object System.Data.SqlClient.SqlCommand
|
||||
$command.Connection = $connection
|
||||
$command.CommandText = $query
|
||||
$command.CommandTimeout = 0 # No timeout for backup operations
|
||||
|
||||
Write-Log "Executing SQL command with message capture..."
|
||||
|
||||
# Execute and capture any result sets
|
||||
$reader = $command.ExecuteReader()
|
||||
|
||||
# Process any result sets
|
||||
while ($reader.Read()) {
|
||||
$rowData = @()
|
||||
for ($i = 0; $i -lt $reader.FieldCount; $i++) {
|
||||
$rowData += "$($reader.GetName($i)): $($reader.GetValue($i))"
|
||||
}
|
||||
if ($rowData.Count -gt 0) {
|
||||
Write-Log "SQL RESULT: $($rowData -join ', ')"
|
||||
}
|
||||
}
|
||||
|
||||
$reader.Close()
|
||||
}
|
||||
Write-Log "$backupType Backup execution completed."
|
||||
} else {
|
||||
Write-Log "ERROR: Backup execution failed. Exit code: $sqlcmdExitCode. Output: $sqlcmdOutput"
|
||||
finally {
|
||||
if ($connection.State -eq [System.Data.ConnectionState]::Open) {
|
||||
$connection.Close()
|
||||
}
|
||||
$connection.Dispose()
|
||||
}
|
||||
|
||||
Write-Log "$backupType Backup execution completed successfully."
|
||||
Write-Log "Total informational messages captured: $($infoMessages.Count)"
|
||||
}
|
||||
catch {
|
||||
Write-Log "ERROR: Backup execution failed with exception: $($_.Exception.Message)"
|
||||
|
||||
# Log additional SQL Server error details if available
|
||||
if ($_.Exception.InnerException) {
|
||||
Write-Log "ERROR: Inner Exception: $($_.Exception.InnerException.Message)"
|
||||
}
|
||||
|
||||
# Check for SQL Server specific errors
|
||||
if ($_.Exception -is [System.Data.SqlClient.SqlException]) {
|
||||
Write-Log "ERROR: SQL Server Error Details:"
|
||||
foreach ($sqlError in $_.Exception.Errors) {
|
||||
Write-Log "ERROR: Severity: $($sqlError.Class), State: $($sqlError.State), Number: $($sqlError.Number)"
|
||||
Write-Log "ERROR: Message: $($sqlError.Message)"
|
||||
if ($sqlError.Procedure) {
|
||||
Write-Log "ERROR: Procedure: $($sqlError.Procedure), Line: $($sqlError.LineNumber)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Clean up connection if it exists
|
||||
if ($connection -and $connection.State -eq [System.Data.ConnectionState]::Open) {
|
||||
$connection.Close()
|
||||
$connection.Dispose()
|
||||
}
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user