miércoles, 9 de febrero de 2011

Backup cubo SSAS con SQL Server Agent y nombre dinámico.

Hola a todos,

Hace tiempo que no escribo ningún post en este blog por razones que no vienen al cuento, pero hoy lo retomo con una nueva entrada que me parece interesante.

Ayer me surgió la necesidad de programar unas copias de seguridad tanto de una base de datos SQL Server (Transaccional) como de los cubos que están en el servidor de preproducción con el SQL Server Agent. No voy a enrollarme con esto porque información en Google hay muchísima pero si quiero detenerme en algo que a priori no parece sencillo. Hacer copias de seguridad de cubos con nombre dinámico, es decir, cubo_20110225.

Hacer un back de un cubo es bastante sencillo:

http://www.microsoft.com/latam/technet/productos/servers/sql/2005/bkupssas.mspx

Pero, ¿y si queremos que el nombre de nuestro backup incluya la fecha y no machaque el anterior?

Buscando en internet no vi nada que fuera intuitivo así que lo mejor es ponerse manos a la obra y a pesar de que no tengo ni pajolera idea de PowerShell vi un script que podía servir:

http://powershell.com/cs/media/p/47.aspx

Como en SQL Server Agent puedes crear un Step de un Job del tipo PowerShell pensé que iba por buen camino y haciendo modificaciones al código de forma intuitiva me quedo algo como lo que muestro a continuación y que funciona perfectamente.

Seguramente se puede hacer mejor y más elegante (ya digo que mis conocimientos de PowerShell son 0 patatero), pero para salir del paso puede servir.

$ServerInstance = "localhost"

$backupDestination = "D:\bkup\Automaticos\"

$logDir = ""

# Load Microsoft Analysis Services assembly, output error messages to null

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.AnalysisServices") | Out-Null

# Declare SSAS objects with strongly typed variables

[Microsoft.AnalysisServices.Server]$SSASserver = New-Object ([Microsoft.AnalysisServices.Server])

[Microsoft.AnalysisServices.BackupInfo]$serverBackup = New-Object ([Microsoft.AnalysisServices.BackupInfo])

# Connect to Analysis Server with specified instance

$SSASserver.Connect($ServerInstance)

# Set Backup destination to Analysis Server default if not supplied

# TIP: using PowerShell "equal" operator

if ($backupDestination -eq "")

{

#Write-Debug "Setting the Destination parameter to the BackupDir parameter"

$BackupDestination = $SSASserver.ServerProperties.Item("BackupDir").Value

}

# Test for existence of Backup Destination path

# TIP: using PowerShell ! operator is equivalent to "-not" operator, see below

if (!(test-path $backupDestination))

{

#Write-Host Destination path `"$backupDestination`" does not exists. Exiting script.

exit 1

}

else

{

#Write-Host Backup files will be written to `"$backupDestination`"

}

# Set Log directory to Analysis Server default if not applied

if ($logDir -eq "")

{

# Write-Debug "Setting the Log directory parameter to the LogDir parameter"

$logDir = $SSASserver.ServerProperties.Item("LogDir").Value

}

# Test for existence of Log directory path

if (!(test-path $logDir))

{

# Write-Debug "djfdaklfjalfjañskdlf"

#Write-Host Log directory `"$logDir`" does not exists. Exiting script.

exit 1

}

else

{

# Write-host Logs will be written to $logDir

}

# Test if Log directory and Backup destination paths end on "\" and add if missing

# TIP: using PowerShell "+=" operator to do a quick string append operation

if (-not $logDir.EndsWith("\"))

{

$logDir += "\"

}

if (-not $backupDestination.EndsWith("\"))

{

$backupDestination += "\"

}

# Create Log file name using Server instance

[string]$logFile = $logDir + "SSASBackup." + $serverInstance.Replace("\","_") + ".log"

# Write-Debug "Log file name is $logFile"

# Write-Debug "Creating database object and set options..."

$dbs = $SSASserver.Databases

$serverBackup.AllowOverwrite = 1

$serverBackup.ApplyCompression = 1

$serverBackup.BackupRemotePartitions = 1

# Create backup timestamp

# TIP: using PowerShell Get-Date to format a datetime string

[string]$backupTS = Get-Date -Format "yyyy-MM-ddTHHmm"

# Add message to backup Log file

# TIP: using PowerShell to output strings to a file

# Write-Debug "Backing up files on $serverInstance at $backupTS"

"Backing up files on $ServerInstance at $backupTS" | Out-File -filepath $LogFile -encoding oem -append

# Back up the SSAS databases

# TIP: using PowerShell foreach loop to enumerate a parent-child object

foreach ($db in $dbs)

{

$serverBackup.file = $backupDestination + $db.name + "." + $backupTS + ".abf"

# TIP: using mixed string literals and variable in a Write-Host command

# Write-Host Backing up $db.Name to $serverBackup.File

$db.Backup($serverBackup)

if ($?) {"Successfully backed up " + $db.Name + " to " + $serverBackup.File | Out-File -filepath $logFile -encoding oem -append}

else {"Failed to back up " + $db.Name + " to " + $serverBackup.File | Out-File -filepath $logFile -encoding oem -append}

}

# Disconnect from Analysis Server

$SSASserver.Disconnect()

# Clear out the old files and files backed up to the Log file

# Write-Host Clearing out old files from $BackupDestination

#[int]$retentionHours = $retentionDays * 24 * - 1

#"Deleting old backup files" | Out-File -filepath $logFile -encoding oem -append

# TIP: using PowerShell get-childitem (get child items for matching location) and pipe to

# where-object (selecting certain ones based on a condition)

#get-childitem ($backupDestination + "*.abf") | where-object {$_.LastWriteTime -le [System.DateTime]::Now.AddHours($RetentionHours)} | Out-File -filepath $logFile -encoding oem -append

#get-childitem ($backupDestination + "*.abf") | where-object {$_.LastWriteTime -le [System.DateTime]::Now.AddHours($RetentionHours)} | remove-item





Un saludo y espero que os sirva