Hello everybody!
All right?
In this post I will demonstrate how to back up all SQL Server Agent jobs via command line (CLR C # or Powershell) and export the results to SQL scripts. You can choose to generate 1 script for each job or 1 single script with all jobs in your instance.
During the migration from SQL Server 2008 R2 to 2014 this script was especially useful since in the report server instance there were little more than 700 jobs and the task of manually saving each script was not feasible. Backing up / restoring the msdb database could be a solution (although I don't find it very recommended), but since these were different versions of SQL Server, we discarded this hypothesis.
Remember that before you can restore jobs in the new environment, you must have created logins on the new instance. If you do not know how to backup logins and their permissions, please visit the post. SQL Server - How to transfer logins between instances by backing up users, logins, and permissions.
Prerequisites
As prerequisites for using the Stored Procedure stpJob_Backup, you will also need to create the following objects:
Run ScriptPowerShell (Click here to access the post)
View source
Server.cs file source code
View source
Return class source code (Click here to access the post)
View source
CLR Procedure (C #) source code stpJob_Backup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
using System; using System.Data.SqlTypes; using Bibliotecas.Model; public partial class StoredProcedures { [Microsoft.SqlServer.Server.SqlProcedure] public static void stpJob_Backup(SqlString Ds_Servidor, SqlString Ds_Diretorio_Destino, SqlBoolean Fl_Arquivo_Unico) { try { var comando = @" $ServerNameList = """ + Ds_Servidor.Value + @""" [System.Reflection.Assembly]::LoadWithPartialName(""Microsoft.SqlServer.Smo"") | Out-Null $objSQLConnection = New-Object System.Data.SqlClient.SqlConnection foreach ($ServerName in $ServerNameList) { Try { $objSQLConnection.ConnectionString = ""Server=$ServerName;Integrated Security=SSPI;"" Write-Host ""Tentando se conectar na instância do servidor $ServerName..."" -NoNewline $objSQLConnection.Open() | Out-Null Write-Host ""Conectado."" $objSQLConnection.Close() } Catch { Write-Host -BackgroundColor Red -ForegroundColor White ""Falha"" $errText = $Error[0].ToString() if ($errText.Contains(""network-related"")) {Write-Host ""Erro de conexão à instância. Por favor, verifique o nome do servidor digitado, porta ou firewall.""} Write-Host $errText continue } $OutputFolder = """ + Ds_Diretorio_Destino.Value + @""" $DoesFolderExist = Test-Path $OutputFolder $null = if (!$DoesFolderExist){MKDIR ""$OutputFolder""} $srv = New-Object ""Microsoft.SqlServer.Management.Smo.Server"" $ServerName"; if (Fl_Arquivo_Unico.Value) { comando += @" $srv.JobServer.Jobs | foreach {$_.Script() + ""GO`r`n""} | out-file ""$OutputFolder\jobs.sql"""; } else { comando += @" $srv.JobServer.Jobs | foreach-object -process {out-file -filepath $(""$OutputFolder\"" + $($_.Name -replace '\\', '') + "".sql"") -inputobject $_.Script() }"; } comando += @" }"; var saida = Utils.ExecutaScriptPowerShell(comando); Retorno.Mensagem(saida); } catch (Exception e) { Retorno.Erro("Erro : " + e.Message); } } }; |
Examples of use
Now I will demonstrate how to use the Stored Procedure created to export the SQL script from all SQL Server Agent jobs. These are the current instance jobs.
Example 1:
In this example, I will demonstrate how to export the creation script for all instance jobs, being 1 sql file for each job.
1 2 3 4 |
EXEC CLR.dbo.stpJob_Backup @Ds_Servidor = N'VM-DBA', -- nvarchar(max) @Ds_Diretorio_Destino = N'C:\Temp\Jobs', -- nvarchar(max) @Fl_Arquivo_Unico = 0 -- bit |
Example 2:
In this example, I will demonstrate how to export the creation script of all instance jobs, being 1 sql file containing the script of all jobs.
1 2 3 4 |
EXEC CLR.dbo.stpJob_Backup @Ds_Servidor = N'VM-DBA', -- nvarchar(max) @Ds_Diretorio_Destino = N'C:\Temp\Jobs', -- nvarchar(max) @Fl_Arquivo_Unico = 1 -- bit |
Using PowerShell and OLE Automation Only
If you do not want to use CLR for this solution and only want to use PowerShell for the database, you can do so as well.
Prerequisites
As prerequisites for using the procedure below, we will need some file manipulation functions. For this, we will use OLE Automation to manipulate these files. To learn more about this, see the post. File Operations Using OLE Automation in SQL Server.
stpWrite_File_File
View source
fncFile_Exists_File
View source
stpApaga_File_File
View source
Stored Procedure stpExecuta_Script_Powershell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
CREATE PROCEDURE [dbo].[stpExecuta_Script_Powershell] @Ds_Script [varchar](MAX), @Fl_Apaga_Script [bit] = 1 AS BEGIN SET NOCOUNT ON DECLARE @QuebraLinha VARCHAR(10) = CHAR(13) + CHAR(10), @arquivo VARCHAR(MAX), @diretorio VARCHAR(MAX) = 'C:\Temp\', @scriptPS VARCHAR(MAX) = CAST(NEWID() AS VARCHAR(50)) + '.ps1', @caminho VARCHAR(MAX) SET @caminho = @diretorio + @scriptPS EXEC dbo.stpEscreve_Arquivo_FSO @String = @Ds_Script, -- varchar(max) @Ds_Arquivo = @caminho -- varchar(1501) SET @scriptPS = @diretorio + @scriptPS DECLARE @cmd VARCHAR(4000) SET @cmd = 'powershell -ExecutionPolicy Unrestricted -File "' + @scriptPS + '"' DECLARE @Retorno TABLE (Ds_Texto VARCHAR(MAX)) INSERT INTO @Retorno EXEC master.dbo.xp_cmdshell @cmd -- Apaga o script gerado IF (@Fl_Apaga_Script = 1) BEGIN EXEC dbo.stpApaga_Arquivo_FSO @strArquivo = @scriptPS -- varchar(1000) END SELECT * FROM @Retorno END |
Example of use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
DECLARE @Script VARCHAR(MAX) = ' $ServerNameList = "VM-DBA" $OutputFolder = "C:\Teste\Jobs\" $DoesFolderExist = Test-Path $OutputFolder $null = if (!$DoesFolderExist){MKDIR "$OutputFolder"} [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null $objSQLConnection = New-Object System.Data.SqlClient.SqlConnection foreach ($ServerName in $ServerNameList) { Try { $objSQLConnection.ConnectionString = "Server=$ServerName;Integrated Security=SSPI;" Write-Host "Tentando se conectar na instância do servidor $ServerName..." -NoNewline $objSQLConnection.Open() | Out-Null Write-Host "Conectado." $objSQLConnection.Close() } Catch { Write-Host -BackgroundColor Red -ForegroundColor White "Falha" $errText = $Error[0].ToString() if ($errText.Contains("network-related")) {Write-Host "Erro de conexão à instância. Por favor, verifique o nome do servidor digitado, porta ou firewall."} Write-Host $errText continue } $srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $ServerName # Arquivo único com todos os jobs # $srv.JobServer.Jobs | foreach {$_.Script() + "GO`r`n"} | out-file "$OutputFolder\jobs.sql" # Um arquivo por job $srv.JobServer.Jobs | foreach-object -process {out-file -filepath $("$OutputFolder\" + $($_.Name -replace "\\", "") + ".sql") -inputobject $_.Script() } }' EXEC dbo.stpExecuta_Script_Powershell @Ds_Script = @Script, -- varchar(max) @Fl_Apaga_Script = 0 -- bit |
Using PowerShell Only
If you only want to use PowerShell script manually, follow the full script below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# Nome da sua máquina $ServerNameList = "VM-DBA" # Diretório para salvar os scripts $OutputFolder = "C:\Jobs\" $DoesFolderExist = Test-Path $OutputFolder $null = if (!$DoesFolderExist){MKDIR "$OutputFolder"} [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null $objSQLConnection = New-Object System.Data.SqlClient.SqlConnection foreach ($ServerName in $ServerNameList) { Try { $objSQLConnection.ConnectionString = "Server=$ServerName;Integrated Security=SSPI;" Write-Host "Tentando se conectar na instância do servidor $ServerName..." -NoNewline $objSQLConnection.Open() | Out-Null Write-Host "Conectado." $objSQLConnection.Close() } Catch { Write-Host -BackgroundColor Red -ForegroundColor White "Falha" $errText = $Error[0].ToString() if ($errText.Contains("network-related")) {Write-Host "Erro de conexão à instância. Por favor, verifique o nome do servidor digitado, porta ou firewall."} Write-Host $errText continue } $srv = New-Object "Microsoft.SqlServer.Management.Smo.Server" $ServerName # Arquivo único com todos os jobs # $srv.JobServer.Jobs | foreach {$_.Script() + "GO`r`n"} | out-file "$OutputFolder\jobs.sql" # Um arquivo por job $srv.JobServer.Jobs | foreach-object -process {out-file -filepath $("$OutputFolder\" + $($_.Name -replace "\\", "") + ".sql") -inputobject $_.Script() } } |
That's it, guys.
A big hug and until next time.
SQL Server - How to backup all SQL Agent jobs via command line (CLR C # or Powershell) backup restore sql server agent jobs command line
SQL Server - How to backup all SQL Agent jobs via command line (CLR C # or Powershell) backup restore sql server agent jobs command line
Post wonder !!! Great for use to store reverse create users and their grants too! 🙂
Thanks for the feedback, Herica. Soon we will have a user and permissions reverse post saving to sql scripts to assist with migrations 🙂
What an amazing post !!!
You have to teach Power Shell to the blog owner: http://rafaelsodre.com.br/blog