SQL Server – Running A Script Or SQL On Multiple Instances/Databases With PowerShell – Level 100

Today, I received a really simple request. There was an UPDATE statement that had to be run on quite a few databases in multiple instances.  This was for a vendor software we use and the statement was sent to me by a Helpdesk professional who manages the product.

You need to have the SQLPS (older) or the SQLSERVER (newer) PowerShell module installed.

As this is the simplest of use-cases for PowerShell instead of the other methods, I am including the code that I used to quickly run that on a set of instances/databases.


$VerbosePreference = 'Continue'

[string] $query = "-- v10 ETL Licence 23Jun18 (1000)
                    UPDATE [VENDOR_SYS].[VENDOR_LIC_TABLE]
                    SET [VALUE] = '		<license>SomeReallyLongEncryptedString</license>'
                    WHERE [NAME] = 'License'
                    "

# -----------------------
# Format: InstanceName=DB
# -----------------------
[string[]] $servers = @('HOSTDEVVDRDB\SDETL01=VendorDB',
                'HOSTDEVVDRDB\ETL01=VendorDBMaster',
                'HOSTDEVVDRDB\ETL02=VRD_DWH',
                'HOSTDEVVDRDB\ETL03=VDR_DM',
                'HOSTUATVDRDB\ETL01=VendorDB',
                'HOSTUATVDRDB\ETL01=VendorDBMaster',
                'HOSTUATVDRDB\ETL02=VRD_DWH',
                'HOSTUATVDRDB\ETL03=VDR_DM',
                'HOSTMAIVDRDB\ETL01=VendorDB',
                'HOSTMAIVDRDB\ETL01=VendorDBMaster',
                'HOSTMAIVDRDB\ETL02=VRD_DWH',
                'HOSTMAIVDRDB\ETL03=VDR_DM',
                'HOSTPPDVDRDB\ETL01=VendorDB',
                'HOSTPPDVDRDB\ETL01=VendorDBMaster',
                'HOSTPPDVDRDB\ETL02=VRD_DWH',
                'HOSTPPDVDRDB\ETL03=VDR_DM',
                'HOSTPRDVDRDB\ETL01=VendorDB',
                'HOSTPRDVDRDB\ETL02=VRD_DWH')

foreach($server in $servers)
{
    $instance = ($server -split '=')[0]
    $db = ($server -split '=')[1]

    Write-Verbose ("Running against instance [{0}] & DB [{1}]" -f $instance, $db)

    Invoke-Sqlcmd `
            -ServerInstance $instance `
            -Database $db `
            -Query $query  #'SELECT @@SERVERNAME'

}

This is the output:

Output:
VERBOSE: Running against instance [HOSTDEVVDRDB\ETL01] & DB [VendorDB]
VERBOSE: Running against instance [HOSTDEVVDRDB\ETL01] & DB [VendorDBMaster]
VERBOSE: Running against instance [HOSTDEVVDRDB\ETL02] & DB [VRD_DWH]
VERBOSE: Running against instance [HOSTDEVVDRDB\ETL03] & DB [VDR_DM]
VERBOSE: Running against instance [HOSTUATVDRDB\ETL01] & DB [VendorDB]
VERBOSE: Running against instance [HOSTUATVDRDB\ETL01] & DB [VendorDBMaster]
VERBOSE: Running against instance [HOSTUATVDRDB\ETL02] & DB [VRD_DWH]
VERBOSE: Running against instance [HOSTUATVDRDB\ETL03] & DB [VDR_DM]
VERBOSE: Running against instance [HOSTMAIVDRDB\ETL01] & DB [VendorDB]
VERBOSE: Running against instance [HOSTMAIVDRDB\ETL01] & DB [VendorDBMaster]
VERBOSE: Running against instance [HOSTMAIVDRDB\ETL02] & DB [VRD_DWH]
VERBOSE: Running against instance [HOSTMAIVDRDB\ETL03] & DB [VDR_DM]
VERBOSE: Running against instance [HOSTPPDVDRDB\ETL01] & DB [VendorDB]
VERBOSE: Running against instance [HOSTPPDVDRDB\ETL01] & DB [VendorDBMaster]
VERBOSE: Running against instance [HOSTPPDVDRDB\ETL02] & DB [VRD_DWH]
VERBOSE: Running against instance [HOSTPPDVDRDB\ETL03] & DB [VDR_DM]
VERBOSE: Running against instance [HOSTPRDVDRDB\ETL01] & DB [VendorDB]
VERBOSE: Running against instance [HOSTPRDVDRDB\ETL02] & DB [VRD_DWH]

That took only a few minutes to code but the next time around, you and me can use this template and replace the SQL/instance list to run something else and get it done in seconds!

Advertisement

12 thoughts on “SQL Server – Running A Script Or SQL On Multiple Instances/Databases With PowerShell – Level 100

  1. Hi ,

    I am Trying to execute SP for Multiple remote server/Instance(Default),But no luck for me it’s throwing below error , is any way we can FIX ? and I need to get SP output with Server name wise

    VERBOSE: Running against instance [XXXXX] & DB []
    -ServerInstance : The term ‘-ServerInstance’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:19 char:13
    + -ServerInstance $instance ‘
    + ~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (-ServerInstance:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    -Query : The term ‘-Query’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:21 char:13
    + -Query $query #’SELECT @@SERVERNAME’
    + ~~~~~~
    + CategoryInfo : ObjectNotFound: (-Query:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    1. Hi Rajesh. Can you please check to see to make sure you have no spaces after the line continuation character “tilde”, also know as the back tick?

  2. Hi Jana,
    Scrript is helpfull & many script in your pages are good.
    But my requirement is to generate a csv file from invoke command and generate a html file and it has to send a mail to DBA Team.

    Could you please help me on this.

    1. Hi Sandeep.

      Thank you for your comments. Once you have the CSV file generated, you can ReportHTML module:
      https://www.powershellgallery.com/packages/ReportHTML/1.4.0.3
      to export to HTML. Examples of how to use this module are here: https://www.cryingcloud.com/blog/2016/08/04/powershellhtmlreportingpart1

      I use a module named Export-HTMLReport but that no longer appears to be online.

      Once you have the HTML file, you can simple use the native PowerShell command Send-MailMessage to attach the HTML file inline or as an attachment and mail it.

      1. Hi Jana,
        I have a requirement to connect to the Windows Machines i.e., connecting to xyz server(Jump Host). From there we have 18 machines which i have to connect to server to make the session active with the help of specific server’s credentials and collect the services(up / down) information with the power shell script.

        Could you please help me on this.

  3. Can we apply try catch rollback if query fail in one instance? So other databases in different instances to rollback any changes?

    1. Hi Stelios, you can enclose your full SQL in a begin/try/catch from this StackOverflow example and execute the complete SQL

      https://stackoverflow.com/questions/25146656/sql-try-catch-rollback-commit-preventing-erroneous-commit-after-rollback/25147092

      BEGIN TRY
      BEGIN TRAN
      PRINT ‘First Statement in the TRY block’
      INSERT INTO dbo.Account(AccountId, Name , Balance) VALUES(1, ‘Account1’, 10000)
      UPDATE dbo.Account SET Balance = Balance + CAST(‘TEN THOUSAND’ AS MONEY) WHERE AccountId = 1
      INSERT INTO dbo.Account(AccountId, Name , Balance) VALUES(2, ‘Account2’, 20000)
      PRINT ‘Last Statement in the TRY block’
      COMMIT TRAN
      END TRY
      BEGIN CATCH
      PRINT ‘In CATCH Block’
      IF(@@TRANCOUNT > 0)
      ROLLBACK TRAN;

      THROW; — raise error to the client
      END CATCH

    1. Hi Vic,

      Thank your for taking the time to provide feedback and referencing the MSSTips post. It will be helpful for the other readers visiting this page.

      Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s