Powershell Script to execute a SQL script on all the databases in a server

avatar

I was recently working on an issue in the production environment. We have an application which is a combination of an SQL database and a .net application. So, most of the fixes we do will either be in the form of code or just a SQL script that will fix the metadata in the database. For the issue that we identified recently, we had to alter a SQL view to fix the issue. The tricky part here is that I have to execute the script on around 700 databases in a production environment. If it was a single database it shouldn't be a challenging task.

I initially thought of having the SQL view in a cursor script to loop through all the databases and execute it. But unfortunately, it is not possible to run DDL statements like that using a cursor script. Scripts with GO command cannot be used inside cursor. After researching a bit and looking for alternative solutions, I finalized that the Powershell script should be an easy way to execute the script looping through all the databases.

First I had to make sure if it was possible for me to use PowerShell script for this task as I was not sure what type of restrictions they would have implemented in the production environment. If there was no permission to run scripts from Powershell, it would have been a tough task. But luckily PowerShell had permissions to execute SQL commands. I wrote the below script to complete the task. I'm going to split the script into three parts and traverse you through the script.

Declaring the parameters for the connection string

image.png

In order to open a connection, we will need the following parameter values:

  • DB Host Instance (This can be with port)
  • Database Name
  • Database User Name
  • Database User Password
  • Script Path

These are the values that are required to prepare a connection string. You can give these values based on your server details. Invocation path refers to the path from which the PowerShell script is executed. You can also give a direct path to your SQL script if in your case, the script is going to be in a different location.

Get a db connection

image.png

In this part of the code, we are going to establish a connection to the database with the connection string that we created in the previous code block. I'm using a try catch block to handle exceptions in the code. So, we create a dataSet and write a query to get all the databases from the server.

SELECT [name] FROM [$dbName].dbo.sysdatabases WHERE dbid > 4

In the above code, we can also use the master database directly instead to get all the databases. We have to give dbid as greater than 4 because the first 4 databases are always system databases. As a next step, we initiate a data adapter and pass the query to it. We then fill the values we get to the dataSet. At the end of this code, the dataSet will have the list of all the databases from the server.

Traverse through each database

image.png

This is the part where we actually execute the script. In this part of the code, we use foreach command to loop through the dataSet that we created and run the SQL script against each database one by one. Just to see which database is currently being performed, I have used an echo statement before and after the query execution.

invoke-expression  "SQLCMD /S '$dbHostInstance' /U '$dbUsername' /P '$dbUserPassword' /l 60             /d '$($row[0])' /i '$ScriptPath' /v DB = '''$($row[0])'''" -ErrorVariable err2 -ErrorAction             Stop

This part of the code then executes the provided SQL script on all the databases one by one. This is a little time-consuming process and if you have more databases in the server this can take a while. But in the log, you will be able to see which database is currently being processed.

That's all and it is as simple as that. If you like my content, upvote, follow, and share. You can also share your thoughts in the comments section.

Carbon was used to create Code Screenshots


If you find this article interesting, please vote, share and follow! Also, please share your thoughts in the comments section.




0
0
0.000
4 comments
avatar

Thank you for this contribution to the Gitplait community. This post is well done, clear and the processes are quite easy to follow. We find this useful, and we will feature this post in today's Gitplait-elite.

Again, thank you!

0
0
0.000
avatar

Thank you so much for the nice words. My pleasure. 🙂

0
0
0.000
avatar

Wow, great one. And how much time it took to come up with this solution. 700 database means 700 companies are using your software, nice

0
0
0.000
avatar

Yes it took me like 3 to 4 hours. I gave the task to one of my team mates and she was struggling a bit. Then I wanted to do it by myself because I rarely work on Powershell Scripts. So, it was interesting.

Yes we have 700+ live clients but the software is pretty old like 15 years old stuff. We are just running with that. It definitely needs an update to modern technology.

0
0
0.000