- Date: 4 Sep 2005
- Versions Affected: SQL Backup 3.2
The following Visual Basic script can be run on a SQL Server to replicate a database to another server as a read-only copy and periodically update the copy by restoring the logs of the source database to the target server.
For simplicity, it assumes the following:
- You are logged in with a Windows domain account that has sysadmin access to both servers
- You have created a share on one of these servers that you and the account that SQLSERVERAGENT uses has full rights to it
- The SQLSERVERAGENT service is running on both servers
- The SQL Backup software is installed on both servers, including the extended stored procedure
- The database does not already exist on the target server
To install the script, copy and paste it into Notepad and save it as logship.vbs. Then you can run it either by double-clicking it or running it from the command prompt using cscript.exe. It will accept an instance name of a SQL Server if the database being shipped is not on the default instance:
cscript logship.vbs SECONDINSTANCE
'Script to ship a database on the local server to another server for SQL Backup
'This requires a WINNT logon that has access to both servers + a common share.
'$VER: 1.1 - fixed instance support (pass -I to SQL Backup), added multiple file/filegroup/log support
If MsgBox("This will initialize log shipping (replication)"&vbCrLf&_
"for a database on the local server to another server."&vbCrLf &_
"Please ensure that you are logged in using an account that has admin access to both servers."&vbCrLf &_
"You will also need a share that is accessible by the SQL Server agent account,"&vbCrLf &_
"the SQL Server account, and the logged in user account.", vbOKCancel, "SQL Backup Log Shipping")=2 Then WScript.Quit
Dim obDMO
Dim chosenDatabase
Dim bDatabaseNameOK
Dim obShell
Dim obLocalServer
Dim obDestServer
Dim obDatabase
Dim bDaily
Dim iInterval
Dim iCompression
Dim iEraseFiles
Dim strEmailError
Dim strBackupCommand
Dim strEncryptPassword
Dim strLocalServerName
Dim strDestServerName
'Get the local server name
Set obShell=CreateObject("Wscript.Shell")
Set obEnv=obShell.Environment("PROCESS")
strLocalServerName=obEnv("COMPUTERNAME")
'You can specify an instance name as an argument...
If WScript.Arguments.Count>0 Then strLocalServerName=strLocalServerName &"\"&WScript.Arguments(0)
chosenDatabase=InputBox("Enter the name of the local database that you want to ship.", "Choose database")
Set obLocalServer=CreateObject("SQLDMO.SQLServer")
obLocalServer.LoginTimeout = 10
' Windows NT security
obLocalServer.LoginSecure = True
obLocalServer.Connect strLocalServerName
'Let script warn user if the database doesn't exist
Set obDataBase=Nothing
ON ERROR RESUME NEXT
Set obDataBase=obLocalServer.Databases(chosenDatabase)
ON ERROR GOTO 0
If obDataBase Is Nothing Then
obShell.Popup "The database does not exist on the local server or you do not have rights to it.", 10, "Cannot create job",16
WScript.Quit
End If
'Check the recovery model. Do not allow log shipping unless it is the Full model
If Not obDataBase.DBOption.RecoveryModel=2 Then
obShell.Popup "The logs cannot be shipped unless the recovery model for "&chosenDatabase&" is ""Full Recovery"".", 10, "Cannot create job",16
WScript.Quit
End If
'Let user enter the destination server name
strDestServerName=InputBox("Enter the name of the SQL Server to ship the logs to" &vbCrLf &_
"for example SERVER or SERVER\INSTANCE","Enter destination server")
Set obDestServer=Nothing
ON ERROR RESUME NEXT
Set obDestServer=CreateObject("SQLDMO.SQLServer")
obDestServer.LoginTimeout = 10
' Windows NT security
obDestServer.LoginSecure = True
obDestServer.Connect strDestServerName
ON ERROR GOTO 0
If obDestServer Is Nothing Then
obShell.Popup "The server does not exist or you do not have rights to it.", 10, "Cannot create job",16
WScript.Quit
End If
iInterval=InputBox("Specify the interval, in minutes, that you want the log shipping to occur." _
,"Log shipping interval")
If Not IsNumeric(iInterval) Then
obShell.Popup "You must enter a log shipping interval!", 10, "Cannot create job",16
WScript.Quit
End If
Dim strCopyTo
strCopyTo=InputBox("Enter the UNC path to copy the log backups to" &vbCrLf &_
"ie. \\TargetServer\Share\"&chosenDataBase&"\logship"&vbCrLf &_
"Do NOT use a trailing slash!", "Choose log shipping share")
If Not LEN(strCopyTo)>0 Then
obShell.Popup "You must enter a share to copy the log files to!", 10, "Cannot create job",16
WScript.Quit
End If
iCompression=InputBox("Enter compression level: 1=fast, 2=slow, 3=slowest (1, 2, or 3)","Compression")
If Not (iCompression="1" Or iCompression="2" Or iCompression="3") Then
obShell.Popup "Compression must be 1, 2, or 3", 10, "Cannot create job",16
WScript.Quit
End If
iEraseFiles=InputBox("To erase backup old files after the backup completes," &_
"Enter the number of days that you would like to retain old backups" &vbCrLf &_
"Leave this blank to keep all backup files.","Delete old backups")
If LEN(iEraseFiles)>0 AND IsNumeric(iEraseFiles)=False Then
obShell.Popup iEraseFiles&" is not a valid number.", 10, "Cannot create job",16
WScript.Quit
End If
strEmailError=InputBox("Enter an email address to send error reports" &vbCrLf&"Leave this blank if you do not want error reports.","Email errors")
strEncryptPassword=InputBox("Enter a password for encryption:" &vbCrLf&"Leave blank to disable encryption."&vbCrLf&"Note that the password will be visible in the job.","Encryption")
'Verify Settings
Dim strSettings
strSettings="SQL Agent job settings:"&vbCrLf &_
"Perform a log backup of "&chosenDataBase&" every "&iInterval&" minutes "&vbCrLf &" with compression "&iCompression&vbCrLf &_
"Copy these log files (ship) to "&strDestServerName&" via share "&strCopyTo&vbCrLf
If LEN(iEraseFiles)>0 Then strSettings=strSettings & "Erase previous backups older than "&iEraseFiles&" days."&vbCrLf
If LEN(strEmailError)>0 Then strSettings=strSettings&"Email error reports to "&strEmailError&"."&vbCrLf
If LEN(strEncryptPassword)>0 Then strSettings=strSettings&"Encrypt these backups."&vbCrLf
If MsgBox(strSettings,33, "Verify settings...")=2 Then WScript.Quit
'connect to share and add a 'complete' subfolder
Dim obFileSys
Set obFileSys=CreateObject("Scripting.FileSystemObject")
If Not obFileSys.FolderExists(strCopyTo&"\complete") Then obFileSys.CreateFolder(strCopyTo&"\complete")
'Do a full backup of source db to share
Dim strResult, backupCmd
backupCmd="EXEC master..sqlbackup '-SQL ""BACKUP DATABASE ["&chosenDataBase&"] To DISK=''"&strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb'' WITH INIT"
If LEN(strEncryptPassword)>0 Then strBackupCommand=backupCmd&" WITH PASSWORD=''"&strEncryptPassword&"''"
backupCmd=backupCmd & """ -E"
'If this server is an instance, we need to know so we can pass -I to SQL Backup
If InStr(1, strLocalServerName, "\", 1)>0 Then
backupCmd=backupCmd&" -I "&SPLIT(strLocalServerName, "\", -1, 1)(1)
End If
backupCmd=backupCmd&"'"
MsgBox "We will now do a full backup of "&chosenDatabase&_
", create a new database named """&chosenDatabase&""" on """&strDestServerName&""""&vbCrLf &_
" and restore the database to it.", 0, "Ready to backup/restore"
strResult=""
Dim obQryResult, i
Set obQryResult=obLocalServer.ExecuteWithResults(CStr(backupCmd))
For i=1 To obQryResult.Rows
strResult=strResult & obQryResult.GetColumnString(i, 1)&vbCrLf
Next
MsgBox "Backup result: "&vbCrLf&strResult
'Restore our backup to a new database
backupCmd="EXEC master..sqlbackup '-SQL ""RESTORE DATABASE ["&chosenDataBase&"] From DISK=''"&strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb''"&_
" WITH STANDBY=''"&obDestServer.Databases("model").PrimaryFilePath&chosenDatabase&"_UNDO.DAT'',"
For Each fg In obDatabase.FileGroups
For Each fgfile In fg.DBFiles
backupCmd=backupCmd&" MOVE ''"&fgfile.Name&"'' TO ''"&obDestServer.Databases("model").PrimaryFilePath &fgfile.Name&".MDF'',"
Next
Next
For Each lf In obDatabase.TransactionLog.LogFiles
backupCmd=backupCmd&" MOVE ''"&lf.Name&"'' TO ''"&obDestServer.Databases("model").PrimaryFilePath &lf.Name&".LDF'',"
Next
backupCmd=LEFT(backupCmd, LEN(backupCmd)-1) 'Lop off trailing comma
If LEN(strEncryptPassword)>0 Then strBackupCommand=backupCmd&", PASSWORD=''"&strEncryptPassword&"''"
backupCmd=backupCmd & """ -E"
'If this server is an instance, we need to know so we can pass -I to SQL Backup
If InStr(1, strDestServerName, "\", 1)>0 Then
backupCmd=backupCmd&" -I "&SPLIT(strDestServerName, "\", -1, 1)(1)
End If
backupCmd=backupCmd&"'"
Set obQryResult=obDestServer.ExecuteWithResults(CStr(backupCmd))
strResult=""
For i=1 To obQryResult.Rows
strResult=strResult & obQryResult.GetColumnString(i, 1)&vbCrLf
Next
MsgBox "Restore result: "&vbCrLf&strResult
obFileSys.DeleteFile(strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb")
'Create the log shipping job --
CreateJob False, chosenDatabase, iInterval
'Create the log restoring job
CreateJob True, chosenDatabase, iInterval
obDestServer.Disconnect
obLocalServer.Disconnect
Set obFileSys=Nothing
Private Function CreateJob(bRestore, strDatabaseName, iInterval)
' create and initialize the Job object
Dim SQLJob
Dim obJobStep
Dim obServer
If bRestore=True Then Set obServer=obDestServer
If bRestore=False Then Set obServer=obLocalServer
Set SQLJob=CreateObject("SQLDMO.Job")
SQLJob.Name = "SQL Backup log shipping "&strDatabaseName
SQLJob.Description = "SQL Backup log shipping "&strDatabasename
' add to the Jobs collection
obServer.JobServer.Jobs.Add SQLJob
Set obJobStep=CreateObject("SQLDMO.JobStep")
If bRestore=False Then obJobStep.Name = "Step 1: Log backup with copy"
If bRestore=True Then obJobStep.Name= "Step 1: Log restore with move"
obJobStep.StepId = 1
obJobStep.SubSystem = "TSQL"
If bRestore=False Then obJobStep.DatabaseName = strDatabaseName
If bRestore=True Then obJobStep.DatabaseName = "master"
'Construct the backup command
strBackupCommand="DECLARE @success int" &vbCrLf &_
"DECLARE @datestamp varchar(30)" &vbCrLf &_
"DECLARE @backupcmd varchar(512)" &vbCrLf &_
"SET @datestamp = left(replace(replace(replace(convert(varchar(30), getdate(), 120), '-', ''), ' ', ''), ':', ''), 12)" &vbCrLf
If bRestore=False Then
strBackupCommand=strBackupCommand &_
"SET @backupcmd = '-SQL ""BACKUP LOG ["&strDatabaseName&"] TO DISK=''<AUTO>'''+" &vbCrLf &_
"' WITH COMPRESSION="&iCompression&", NAME=''Database "&strDatabaseName&", (log) '+@datestamp +"&vbCrLf &_
"''', DESCRIPTION=''Database "&strDatabaseName&", (log) '+@datestamp+''', COPYTO=''"&strCopyTo&"''"
End If
If bRestore=True Then
strBackupCommand=strBackupCommand &_
"SET @backupcmd = '-SQL ""RESTORE LOG ["&strDatabaseName&"] FROM DISK=''"&strCopyTo&"\*.sqb'''+" &vbCrLf &_
"' WITH MOVETO=''"&strCopyTo&"\complete'', STANDBY=''"&obServer.Databases("model").PrimaryFilePath&chosenDatabase&"_UNDO.DAT''"
End If
If LEN(strEmailError)>0 Then strBackupCommand=strBackupCommand&", MAILTO_ONERROR=''"&strEmailError&"''"
If LEN(strEncryptPassword)>0 Then strBackupCommand=strBackupCommand&", PASSWORD=''"&strEncryptPassword&"''"
If LEN(iEraseFiles)>0 AND bRestore=False Then strBackupCommand=strBackupCommand &", ERASEFILES="&iEraseFiles
strBackupCommand=strBackupCommand & """ -E"
'Specify Instance, if necessary
If bRestore=True Then
If InStr(1, strDestServerName, "\", 1)>0 Then strBackupCommand=strBackupCommand&" -I "&SPLIT(strDestServerName, "\", -1, 1)(1)
End If
If bRestore=False Then
If InStr(1, strLocalServerName, "\", 1)>0 Then strBackupCommand=strBackupCommand&" -I "&SPLIT(strLocalServerName, "\", -1, 1)(1)
End If
strBackupCommand=strBackupCommand &"'"&vbCrLf &"EXEC @success=master..sqlbackup @backupcmd" &vbCrLf &_
"IF @success=0" &vbCrLf &_
"BEGIN" &vbCrLf &_
"RAISERROR('Backup failed for database "&strDatabaseName&"', 16,1)" &vbCrLf &_
"END"
obJobStep.Command = strBackupCommand
obJobStep.OnFailAction = 2 'Quit with failure
'Add the job step to the job
SQLJob.JobSteps.Add obJobStep
SQLJob.ApplyToTargetServer(obServer.Name)
'Schedule this job
' a new JobSchedule for daily backup
Dim SQLSchedule
Set SQLSchedule=CreateObject("SQLDMO.JobSchedule")
SQLSchedule.Name = "Log shipping for "&strDatabaseName
SQLSchedule.Schedule.FrequencyType = 4 'Daily
SQLSchedule.Schedule.FrequencyInterval = 1 'Every day
SQLSchedule.Schedule.FrequencySubDay = 4 'Evaluate interval in minutes
SQLSchedule.Schedule.FrequencySubDayInterval = cLng(iInterval) 'number of minutes
SQLSchedule.Schedule.ActiveStartDate = 20050816 'arbitrary; not important
If bRestore=False Then SQLSchedule.Schedule.ActiveStartTimeOfDay = "000100"
'Make sure we stagger backups and restores...
If bRestore=True Then
Dim iHalfInterval
iHalfInterval=iInterval/2
If iHalfInterval>10 Then iHalfInterval="0"&iHalfInterval
SQLSchedule.Schedule.ActiveStartTimeOfDay = "00"&iHalfInterval&"00"
End If
' this schedule has no end time or end date (they might be omitted)
SQLSchedule.Schedule.ActiveEndDate = SQLDMO_NOENDDATE
SQLSchedule.Schedule.ActiveEndTimeOfDay = SQLDMO_NOENDTIME
' add the schedule to the Job
SQLJob.BeginAlter
SQLJob.JobSchedules.Add SQLSchedule
SQLJob.DoAlter
End Function
MsgBox "Log shipping initialized successfully", 64, "Success!"
'Clean up
Set obDataBase=Nothing
Set obService=Nothing
Set objWMIService=Nothing
Set SQLSchedule=Nothing
Set obJob=Nothing
Set SQLServer=Nothing
Set obJobStep=Nothing
Set obShell=Nothing
- Date: 4 Sep 2005
- Versions Affected: SQL Backup 3.2
The following Visual Basic script can be run on a SQL Server to replicate a database to another server as a read-only copy and periodically update the copy by restoring the logs of the source database to the target server.For simplicity, it assumes the following:
- You are logged in with a Windows domain account that has sysadmin access to both servers
- You have created a share on one of these servers that you and the account that SQLSERVERAGENT uses has full rights to it
- The SQLSERVERAGENT service is running on both servers
- The SQL Backup software is installed on both servers, including the extended stored procedure
- The database does not already exist on the target server
To install the script, copy and paste it into Notepad and save it as logship.vbs. Then you can run it either by double-clicking it or running it from the command prompt using cscript.exe. It will accept an instance name of a SQL Server if the database being shipped is not on the default instance: cscript logship.vbs SECONDINSTANCE'Script to ship a database on the local server to another server for SQL Backup 'This requires a WINNT logon that has access to both servers + a common share. '$VER: 1.1 - fixed instance support (pass -I to SQL Backup), added multiple file/filegroup/log support If MsgBox("This will initialize log shipping (replication)"&vbCrLf&_ "for a database on the local server to another server."&vbCrLf &_ "Please ensure that you are logged in using an account that has admin access to both servers."&vbCrLf &_ "You will also need a share that is accessible by the SQL Server agent account,"&vbCrLf &_ "the SQL Server account, and the logged in user account.", vbOKCancel, "SQL Backup Log Shipping")=2 Then WScript.Quit Dim obDMO Dim chosenDatabase Dim bDatabaseNameOK Dim obShell Dim obLocalServer Dim obDestServer Dim obDatabase Dim bDaily Dim iInterval Dim iCompression Dim iEraseFiles Dim strEmailError Dim strBackupCommand Dim strEncryptPassword Dim strLocalServerName Dim strDestServerName 'Get the local server name Set obShell=CreateObject("Wscript.Shell") Set obEnv=obShell.Environment("PROCESS") strLocalServerName=obEnv("COMPUTERNAME") 'You can specify an instance name as an argument... If WScript.Arguments.Count>0 Then strLocalServerName=strLocalServerName &"\"&WScript.Arguments(0) chosenDatabase=InputBox("Enter the name of the local database that you want to ship.", "Choose database") Set obLocalServer=CreateObject("SQLDMO.SQLServer") obLocalServer.LoginTimeout = 10 ' Windows NT security obLocalServer.LoginSecure = True obLocalServer.Connect strLocalServerName 'Let script warn user if the database doesn't exist Set obDataBase=Nothing ON ERROR RESUME NEXT Set obDataBase=obLocalServer.Databases(chosenDatabase) ON ERROR GOTO 0 If obDataBase Is Nothing Then obShell.Popup "The database does not exist on the local server or you do not have rights to it.", 10, "Cannot create job",16 WScript.Quit End If 'Check the recovery model. Do not allow log shipping unless it is the Full model If Not obDataBase.DBOption.RecoveryModel=2 Then obShell.Popup "The logs cannot be shipped unless the recovery model for "&chosenDatabase&" is ""Full Recovery"".", 10, "Cannot create job",16 WScript.Quit End If 'Let user enter the destination server name strDestServerName=InputBox("Enter the name of the SQL Server to ship the logs to" &vbCrLf &_ "for example SERVER or SERVER\INSTANCE","Enter destination server") Set obDestServer=Nothing ON ERROR RESUME NEXT Set obDestServer=CreateObject("SQLDMO.SQLServer") obDestServer.LoginTimeout = 10 ' Windows NT security obDestServer.LoginSecure = True obDestServer.Connect strDestServerName ON ERROR GOTO 0 If obDestServer Is Nothing Then obShell.Popup "The server does not exist or you do not have rights to it.", 10, "Cannot create job",16 WScript.Quit End If iInterval=InputBox("Specify the interval, in minutes, that you want the log shipping to occur." _ ,"Log shipping interval") If Not IsNumeric(iInterval) Then obShell.Popup "You must enter a log shipping interval!", 10, "Cannot create job",16 WScript.Quit End If Dim strCopyTo strCopyTo=InputBox("Enter the UNC path to copy the log backups to" &vbCrLf &_ "ie. \\TargetServer\Share\"&chosenDataBase&"\logship"&vbCrLf &_ "Do NOT use a trailing slash!", "Choose log shipping share") If Not LEN(strCopyTo)>0 Then obShell.Popup "You must enter a share to copy the log files to!", 10, "Cannot create job",16 WScript.Quit End If iCompression=InputBox("Enter compression level: 1=fast, 2=slow, 3=slowest (1, 2, or 3)","Compression") If Not (iCompression="1" Or iCompression="2" Or iCompression="3") Then obShell.Popup "Compression must be 1, 2, or 3", 10, "Cannot create job",16 WScript.Quit End If iEraseFiles=InputBox("To erase backup old files after the backup completes," &_ "Enter the number of days that you would like to retain old backups" &vbCrLf &_ "Leave this blank to keep all backup files.","Delete old backups") If LEN(iEraseFiles)>0 AND IsNumeric(iEraseFiles)=False Then obShell.Popup iEraseFiles&" is not a valid number.", 10, "Cannot create job",16 WScript.Quit End If strEmailError=InputBox("Enter an email address to send error reports" &vbCrLf&"Leave this blank if you do not want error reports.","Email errors") strEncryptPassword=InputBox("Enter a password for encryption:" &vbCrLf&"Leave blank to disable encryption."&vbCrLf&"Note that the password will be visible in the job.","Encryption") 'Verify Settings Dim strSettings strSettings="SQL Agent job settings:"&vbCrLf &_ "Perform a log backup of "&chosenDataBase&" every "&iInterval&" minutes "&vbCrLf &" with compression "&iCompression&vbCrLf &_ "Copy these log files (ship) to "&strDestServerName&" via share "&strCopyTo&vbCrLf If LEN(iEraseFiles)>0 Then strSettings=strSettings & "Erase previous backups older than "&iEraseFiles&" days."&vbCrLf If LEN(strEmailError)>0 Then strSettings=strSettings&"Email error reports to "&strEmailError&"."&vbCrLf If LEN(strEncryptPassword)>0 Then strSettings=strSettings&"Encrypt these backups."&vbCrLf If MsgBox(strSettings,33, "Verify settings...")=2 Then WScript.Quit 'connect to share and add a 'complete' subfolder Dim obFileSys Set obFileSys=CreateObject("Scripting.FileSystemObject") If Not obFileSys.FolderExists(strCopyTo&"\complete") Then obFileSys.CreateFolder(strCopyTo&"\complete") 'Do a full backup of source db to share Dim strResult, backupCmd backupCmd="EXEC master..sqlbackup '-SQL ""BACKUP DATABASE ["&chosenDataBase&"] To DISK=''"&strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb'' WITH INIT" If LEN(strEncryptPassword)>0 Then strBackupCommand=backupCmd&" WITH PASSWORD=''"&strEncryptPassword&"''" backupCmd=backupCmd & """ -E" 'If this server is an instance, we need to know so we can pass -I to SQL Backup If InStr(1, strLocalServerName, "\", 1)>0 Then backupCmd=backupCmd&" -I "&SPLIT(strLocalServerName, "\", -1, 1)(1) End If backupCmd=backupCmd&"'" MsgBox "We will now do a full backup of "&chosenDatabase&_ ", create a new database named """&chosenDatabase&""" on """&strDestServerName&""""&vbCrLf &_ " and restore the database to it.", 0, "Ready to backup/restore" strResult="" Dim obQryResult, i Set obQryResult=obLocalServer.ExecuteWithResults(CStr(backupCmd)) For i=1 To obQryResult.Rows strResult=strResult & obQryResult.GetColumnString(i, 1)&vbCrLf Next MsgBox "Backup result: "&vbCrLf&strResult 'Restore our backup to a new database backupCmd="EXEC master..sqlbackup '-SQL ""RESTORE DATABASE ["&chosenDataBase&"] From DISK=''"&strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb''"&_ " WITH STANDBY=''"&obDestServer.Databases("model").PrimaryFilePath&chosenDatabase&"_UNDO.DAT''," For Each fg In obDatabase.FileGroups For Each fgfile In fg.DBFiles backupCmd=backupCmd&" MOVE ''"&fgfile.Name&"'' TO ''"&obDestServer.Databases("model").PrimaryFilePath &fgfile.Name&".MDF''," Next Next For Each lf In obDatabase.TransactionLog.LogFiles backupCmd=backupCmd&" MOVE ''"&lf.Name&"'' TO ''"&obDestServer.Databases("model").PrimaryFilePath &lf.Name&".LDF''," Next backupCmd=LEFT(backupCmd, LEN(backupCmd)-1) 'Lop off trailing comma If LEN(strEncryptPassword)>0 Then strBackupCommand=backupCmd&", PASSWORD=''"&strEncryptPassword&"''" backupCmd=backupCmd & """ -E" 'If this server is an instance, we need to know so we can pass -I to SQL Backup If InStr(1, strDestServerName, "\", 1)>0 Then backupCmd=backupCmd&" -I "&SPLIT(strDestServerName, "\", -1, 1)(1) End If backupCmd=backupCmd&"'" Set obQryResult=obDestServer.ExecuteWithResults(CStr(backupCmd)) strResult="" For i=1 To obQryResult.Rows strResult=strResult & obQryResult.GetColumnString(i, 1)&vbCrLf Next MsgBox "Restore result: "&vbCrLf&strResult obFileSys.DeleteFile(strCopyTo&"\"&chosenDatabase&"_INIT_Log_Ship.sqb") 'Create the log shipping job -- CreateJob False, chosenDatabase, iInterval 'Create the log restoring job CreateJob True, chosenDatabase, iInterval obDestServer.Disconnect obLocalServer.Disconnect Set obFileSys=Nothing Private Function CreateJob(bRestore, strDatabaseName, iInterval) ' create and initialize the Job object Dim SQLJob Dim obJobStep Dim obServer If bRestore=True Then Set obServer=obDestServer If bRestore=False Then Set obServer=obLocalServer Set SQLJob=CreateObject("SQLDMO.Job") SQLJob.Name = "SQL Backup log shipping "&strDatabaseName SQLJob.Description = "SQL Backup log shipping "&strDatabasename ' add to the Jobs collection obServer.JobServer.Jobs.Add SQLJob Set obJobStep=CreateObject("SQLDMO.JobStep") If bRestore=False Then obJobStep.Name = "Step 1: Log backup with copy" If bRestore=True Then obJobStep.Name= "Step 1: Log restore with move" obJobStep.StepId = 1 obJobStep.SubSystem = "TSQL" If bRestore=False Then obJobStep.DatabaseName = strDatabaseName If bRestore=True Then obJobStep.DatabaseName = "master" 'Construct the backup command strBackupCommand="DECLARE @success int" &vbCrLf &_ "DECLARE @datestamp varchar(30)" &vbCrLf &_ "DECLARE @backupcmd varchar(512)" &vbCrLf &_ "SET @datestamp = left(replace(replace(replace(convert(varchar(30), getdate(), 120), '-', ''), ' ', ''), ':', ''), 12)" &vbCrLf If bRestore=False Then strBackupCommand=strBackupCommand &_ "SET @backupcmd = '-SQL ""BACKUP LOG ["&strDatabaseName&"] TO DISK=''<AUTO>'''+" &vbCrLf &_ "' WITH COMPRESSION="&iCompression&", NAME=''Database "&strDatabaseName&", (log) '+@datestamp +"&vbCrLf &_ "''', DESCRIPTION=''Database "&strDatabaseName&", (log) '+@datestamp+''', COPYTO=''"&strCopyTo&"''" End If If bRestore=True Then strBackupCommand=strBackupCommand &_ "SET @backupcmd = '-SQL ""RESTORE LOG ["&strDatabaseName&"] FROM DISK=''"&strCopyTo&"\*.sqb'''+" &vbCrLf &_ "' WITH MOVETO=''"&strCopyTo&"\complete'', STANDBY=''"&obServer.Databases("model").PrimaryFilePath&chosenDatabase&"_UNDO.DAT''" End If If LEN(strEmailError)>0 Then strBackupCommand=strBackupCommand&", MAILTO_ONERROR=''"&strEmailError&"''" If LEN(strEncryptPassword)>0 Then strBackupCommand=strBackupCommand&", PASSWORD=''"&strEncryptPassword&"''" If LEN(iEraseFiles)>0 AND bRestore=False Then strBackupCommand=strBackupCommand &", ERASEFILES="&iEraseFiles strBackupCommand=strBackupCommand & """ -E" 'Specify Instance, if necessary If bRestore=True Then If InStr(1, strDestServerName, "\", 1)>0 Then strBackupCommand=strBackupCommand&" -I "&SPLIT(strDestServerName, "\", -1, 1)(1) End If If bRestore=False Then If InStr(1, strLocalServerName, "\", 1)>0 Then strBackupCommand=strBackupCommand&" -I "&SPLIT(strLocalServerName, "\", -1, 1)(1) End If strBackupCommand=strBackupCommand &"'"&vbCrLf &"EXEC @success=master..sqlbackup @backupcmd" &vbCrLf &_ "IF @success=0" &vbCrLf &_ "BEGIN" &vbCrLf &_ "RAISERROR('Backup failed for database "&strDatabaseName&"', 16,1)" &vbCrLf &_ "END" obJobStep.Command = strBackupCommand obJobStep.OnFailAction = 2 'Quit with failure 'Add the job step to the job SQLJob.JobSteps.Add obJobStep SQLJob.ApplyToTargetServer(obServer.Name) 'Schedule this job ' a new JobSchedule for daily backup Dim SQLSchedule Set SQLSchedule=CreateObject("SQLDMO.JobSchedule") SQLSchedule.Name = "Log shipping for "&strDatabaseName SQLSchedule.Schedule.FrequencyType = 4 'Daily SQLSchedule.Schedule.FrequencyInterval = 1 'Every day SQLSchedule.Schedule.FrequencySubDay = 4 'Evaluate interval in minutes SQLSchedule.Schedule.FrequencySubDayInterval = cLng(iInterval) 'number of minutes SQLSchedule.Schedule.ActiveStartDate = 20050816 'arbitrary; not important If bRestore=False Then SQLSchedule.Schedule.ActiveStartTimeOfDay = "000100" 'Make sure we stagger backups and restores... If bRestore=True Then Dim iHalfInterval iHalfInterval=iInterval/2 If iHalfInterval>10 Then iHalfInterval="0"&iHalfInterval SQLSchedule.Schedule.ActiveStartTimeOfDay = "00"&iHalfInterval&"00" End If ' this schedule has no end time or end date (they might be omitted) SQLSchedule.Schedule.ActiveEndDate = SQLDMO_NOENDDATE SQLSchedule.Schedule.ActiveEndTimeOfDay = SQLDMO_NOENDTIME ' add the schedule to the Job SQLJob.BeginAlter SQLJob.JobSchedules.Add SQLSchedule SQLJob.DoAlter End Function MsgBox "Log shipping initialized successfully", 64, "Success!" 'Clean up Set obDataBase=Nothing Set obService=Nothing Set objWMIService=Nothing Set SQLSchedule=Nothing Set obJob=Nothing Set SQLServer=Nothing Set obJobStep=Nothing Set obShell=Nothing