Recently I went through requirement of running SQL scripts on multiple databases on different servers. As the list of databases was different from script to script I decided to create universal solution, which will allow to easily prepare for deployment and can be simply reused at any time.
As a platform to execute scripts I went with PowerShell as that provides flexibility in case additional functionality will be required.
Whole solution contains 3 files:
- SqlExecutionInflow.csv – file contains list of databases and servers where particular database is located. It is simple CSV file with 2 columns
- SqlExecQuery.sql – contains SQL script which will be executed against all databases listed in SqlExecutionInflow.csv
- SqlExec.ps1 – main script which load SqlExecInflow.csv and executes query from SqlExecQuery.sql
All files have to be placed in same folder. As a result script will create transcript file with output from all executed commands.
And here are example files and script itself…
SqlExecInflow.csv
DBname,DBserver AdventureWorksDB,SQL-SERVER-01 Northwind,SQL-SERVER-01
SqlExecQuery.sql
SELECT @@VERSION
SqlExec.ps1
Import-Module SqlPs # Load Smo and referenced assemblies. [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.ConnectionInfo'); [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Management.Sdk.Sfc'); [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO'); # Requiered for SQL Server 2008 (SMO 10.0). [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMOExtended'); # Determine script location for PowerShell $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path $SqlExecInflowList = $ScriptDir + "\SqlExecInflow.csv" $SqlExecOutputLog = $ScriptDir + "\SqlExecOutput.log" $SqlExecQueryFile = $ScriptDir + "\SqlExecQuery.sql" $DatabaseListArray = @() $DatabaseListArray = Import-CSV $SqlExecInflowList Start-Transcript $SqlExecOutputLog foreach ($DatabaseItem in $DatabaseListArray) { $DatabaseName = $DatabaseItem.DBname $DatabaseServer = $DatabaseItem.DBserver Invoke-SqlCmd -InputFile $SqlExecQueryFile -ServerInstance $DatabaseServer -Database $DatabaseName -Verbose } Stop-Transcript