Skip to content

Instantly share code, notes, and snippets.

@henkmeulekamp
Created September 16, 2012 16:08
Show Gist options
  • Save henkmeulekamp/3733004 to your computer and use it in GitHub Desktop.
Save henkmeulekamp/3733004 to your computer and use it in GitHub Desktop.
PowerShell script to restore TRN into Standby readonly SQL2008R2 database
-------------------
## henk meulekamp - 2012-09-14
## Script to restore transaction log (.TRN files) into office readonly copy
$logBackupFolder="D:\sshRoot"
$server = "smtpserver"
$toemail ="monitor email"
$fromemail ="sender email"
$nl = [Environment]::NewLine
##Variable for time duration - the amount of time you need to generate and restore LOG backups
$LookBackPeriod = [DateTime]::Now.AddHours(-12)
##Retrieve folders and files in the specified directory
foreach ($databaseName in (Get-ChildItem $logBackupFolder | Where { $_.PsIsContainer }) )
{
foreach ($logName in (Get-ChildItem $logBackupFolder\$databasename\Log | where {($_.CreationTime -ge $LookBackPeriod) -and ($_.Extension -eq ".trn")} | SELECT name))
{
$logBackupPath = [System.String]::Concat("'$logBackupFolder\",$databasename,"\Log\",$logName.Name,"'")
Try
{
$logBackupPathStandby = [System.String]::Concat("'D:\SQLServerfiles\MSSQL10_50.MSSQLSERVER\MSSQL\Backup\ROLLBACK_UNDO_",$databasename,".bak'")
$logFile = [System.String]::Concat("D:\Tools\sql\Log\",$logName.Name)
##write restore file
##first set db to offline and back to online, this will kick out all connections. We restore to readonly db, so this shouldnt be an issue
[System.String]::Concat("ALTER DATABASE ",$databaseName ," set offline with rollback immediate") | Out-File D:\Tools\sql\$databaseName.sql
"GO" | Out-File D:\Tools\sql\$databaseName.sql -append
"print cast(getdate() as varchar(50))" | Out-File D:\Tools\sql\$databaseName.sql -append
"GO" | Out-File D:\Tools\sql\$databaseName.sql -append
[System.String]::Concat("ALTER DATABASE ",$databaseName ," set online") | Out-File D:\Tools\sql\$databaseName.sql -append
"GO" | Out-File D:\Tools\sql\$databaseName.sql -append
$restoreSQL = "RESTORE LOG $databaseName FROM DISK=$logBackupPath WITH FILE = 1, STANDBY= $logBackupPathStandby, NOUNLOAD, STATS = 10" | Out-File D:\Tools\sql\$databaseName.sql -append
"GO" | Out-File D:\Tools\sql\$databaseName.sql -append
##this line will crash the process if file already exists.. meaning we already restored this trn
Get-Date | Out-File $logFile -noClobber -encoding "UTF8"
##invoke restore command and write output to logfile
write-host -foregroundcolor Green "starting restore process"
Invoke-Expression "sqlcmd.exe -Slocalhost -iD:\Tools\sql\$databaseName.sql" | Out-File $logFile
##show done
$logdone = [System.String]::Concat("Processed backup file: ", $logBackupPath)
$logdone
$logdone | Out-File $logFile -append
##Pause for 3 seconds; seems that the log file needs this?
write-host -foregroundcolor Green "Pause for 3 seconds before emailling logfile"
Start-Sleep -s 3
##import logfile content into body to be emailed
$body = "$(cat $logFile)"
##Email the report.
Send-MailMessage -smtpServer $server -to $toemail -from $fromemail -subject "Report DB Daily Office Import" -body $body
}
Catch [system.IO.IOException]
{
$log = [System.String]::Concat("We already did this file: ", $logBackupPath)
write-host -foregroundcolor Red $log
}
Catch
{
##send crash to monitoring
Send-MailMessage -smtpServer $server -to $toemail -from $fromemail -subject "FAILED - Report DB Daily Office Import" -body "Import script crashed"
}
##dont catch other exceptions, those need to break the script
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment