0

On Azure, I am running multiple .sql files from a container in 100s of Azure SQL Databases via Powershell runbook.

I want Powershell to read the server name and the database name to run the scripts from my SQL Server table that looks like this:

Servername Databasename Status
Server-01 DB-01 Process
Server-01 DB-02 Skip
Server-02 DB-03 Process

In my current version of the Powershell script, it can read the files in the container and run them in a given server and database:

# Get the blob container
$blobs = Get-AzStorageContainer -Name $containerName  -Context $ctx | Get-AzStorageBlob 

# Download the blob content to localhost and execute each one 
foreach ($blob in $blobs)
    {
        $file = Get-AzStorageBlobContent -Container $containerName -Blob $blob.Name  -Destination "." -Context $ctx 
        Write-Output ("Processing file :" + $file.Name)
        $query = Get-Content -Path $file.Name
        Invoke-Sqlcmd -ServerInstance "Server-01.database.windows.net" -Database "DB-01" -Query $query -AccessToken $access_token
        Write-Output ("This file is executed :" + $file.Name) 
    }

I am looking for a method that will read the rows from the table and feed them into the -ServerInstance and -Database fields in the Invoke-Sqlcmd. Ideally it can filter out the Skip rows.

4
  • 1
    Is your intent to run the same script against each database in the SQL table with Status = 'Process'? Commented Nov 3, 2022 at 10:47
  • Where is this table of server names and database stored? Commented Nov 3, 2022 at 10:49
  • @DanGuzman Yes, same script in multiple databases in multiple servers where it says 'Process' Commented Nov 3, 2022 at 10:50
  • @Larnu The table is stored in another Azure SQL Database Commented Nov 3, 2022 at 10:51

1 Answer 1

2

One method is to load the database list into a DataTable and iterate over the list for each query. Change the $databaseListConnectionString in the example code below per your authentication method and set the connection AccessToken if/as needed.

# get database list
$databaseListConnectionString = "Data Source=YourServer;Initial Catalog=YourDatabase"
$databaseListQuery = "SELECT ServerName, DatabaseName FROM dbo.DatabaseList WHERE Status = 'Process';"
$dataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($databaseListQuery, $databaseListConnectionString)
$dataAdapter.SelectCommand.Connection.AccessToken = $access_token
$databaseList = New-Object System.Data.DataTable
[void]$dataAdapter.Fill($databaseList)

# Get the blob container
$blobs = Get-AzStorageContainer -Name $containerName  -Context $ctx | Get-AzStorageBlob 

# Download the blob content to localhost and execute each one 
foreach ($blob in $blobs) {
    {
        $file = Get-AzStorageBlobContent -Container $containerName -Blob $blob.Name  -Destination "." -Context $ctx 
        Write-Output ("Processing file :" + $file.Name)
        $query = Get-Content -Path $file.Name
        foreach($database in $databaseList.Rows) {
            Invoke-Sqlcmd -ServerInstance "$($database.ServerName)" -Database "$($database.DatabaseName)" -Query $query -AccessToken $access_token
            Write-Output ("This file is executed :" + $file.Name)
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Many thanks for the answer. I've been trying this method with my authentication method and failing. The SQL Server - Runbook connection is done via a Private endpoint and I am using an access token for my "Invoke-Sqlcmd" command. Is there a way I can follow a similar way for the "$databaseListConnectionString" here?
@Strayda, try adding this line after instantiating the new SqlDataAdapter: $dataAdapter.SelectCommand.Connection.AccessToken = $access_token. I think you can remove ;Integrated Security=SSPI from the connection string with the token.
You are a hero! Thank you very much!
Thanks for confirming. I'll edited my answer for your use case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.