How do you run a SQL Server query from PowerShell?

PowershellSql

Powershell Problem Overview


Is there a way to execute an arbitrary query on a SQL Server using Powershell on my local machine?

Powershell Solutions


Solution 1 - Powershell

For others who need to do this with just stock .NET and PowerShell (no additional SQL tools installed) here is the function that I use:

function Invoke-SQL {
    param(
        [string] $dataSource = ".\SQLEXPRESS",
        [string] $database = "MasterData",
        [string] $sqlCommand = $(throw "Please specify a query.")
      )

    $connectionString = "Data Source=$dataSource; " +
            "Integrated Security=SSPI; " +
            "Initial Catalog=$database"

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $connection.Open()
    
    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null
    
    $connection.Close()
    $dataSet.Tables

}

I have been using this so long I don't know who wrote which parts. This was distilled from others' examples, but simplified to be clear and just what is needed without extra dependencies or features.

I use and share this often enough that I have turned this into a script module on GitHub so that you can now go to your modules directory and execute git clone https://github.com/ChrisMagnuson/InvokeSQL and from that point forward invoke-sql will automatically be loaded when you go to use it (assuming your using PowerShell v3 or later).

Solution 2 - Powershell

You can use the Invoke-Sqlcmd cmdlet

Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"

http://technet.microsoft.com/en-us/library/cc281720.aspx

Solution 3 - Powershell

This function will return the results of a query as an array of powershell objects so you can use them in filters and access columns easily:

function sql($sqlText, $database = "master", $server = ".")
{
    $connection = new-object System.Data.SqlClient.SQLConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database");
    $cmd = new-object System.Data.SqlClient.SqlCommand($sqlText, $connection);
    
    $connection.Open();
    $reader = $cmd.ExecuteReader()
    
    $results = @()
    while ($reader.Read())
    {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++)
        {
            $row[$reader.GetName($i)] = $reader.GetValue($i)
        }
        $results += new-object psobject -property $row            
    }
    $connection.Close();
    
    $results
}

Solution 4 - Powershell

Here's an example I found on this blog.

$cn2 = new-object system.data.SqlClient.SQLConnection("Data Source=machine1;Integrated Security=SSPI;Initial Catalog=master");
$cmd = new-object system.data.sqlclient.sqlcommand("dbcc freeproccache", $cn2);
$cn2.Open();
if ($cmd.ExecuteNonQuery() -ne -1)
{
    echo "Failed";
}
$cn2.Close();

Presumably you could substitute a different TSQL statement where it says dbcc freeproccache.

Solution 5 - Powershell

If you want to do it on your local machine instead of in the context of SQL server then I would use the following. It is what we use at my company.

$ServerName = "_ServerName_"
$DatabaseName = "_DatabaseName_"
$Query = "SELECT * FROM Table WHERE Column = ''"

#Timeout parameters
$QueryTimeout = 120
$ConnectionTimeout = 30

#Action of connecting to the Database and executing the query and returning results if there were any.
$conn=New-Object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$DatabaseName,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables

Just fill in the $ServerName, $DatabaseName and the $Query variables and you should be good to go.

I am not sure how we originally found this out, but there is something very similar [here][1].

[1]: http://social.technet.microsoft.com/Forums/windowsserver/en-US/e580a1e1-f116-4fc5-9344-bebf4489dc75/running-sql-query-with-powershell-on-remote-server/ "here"

Solution 6 - Powershell

There isn't a built-in "PowerShell" way of running a SQL query. If you have the SQL Server tools installed, you'll get an Invoke-SqlCmd cmdlet.

Because PowerShell is built on .NET, you can use the ADO.NET API to run your queries.

Solution 7 - Powershell

Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3

Solution 8 - Powershell

To avoid SQL Injection with varchar parameters you could use

function sqlExecuteRead($connectionString, $sqlCommand, $pars) {

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $connection.Open()
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand, $connection)

    if ($pars -and $pars.Keys) {
        foreach($key in $pars.keys) {
            # avoid injection in varchar parameters
            $par = $command.Parameters.Add("@$key", [system.data.SqlDbType]::VarChar, 512);
            $par.Value = $pars[$key];
        }
    }

    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataset) | Out-Null
    $connection.Close()
    return $dataset.tables[0].rows

}

$connectionString = "connectionstringHere"
$sql = "select top 10 Message, TimeStamp, Level from dbo.log " +
    "where Message = @MSG and Level like @LEVEL"
$pars = @{
    MSG = 'this is a test from powershell'
    LEVEL = 'aaa%'
};
sqlExecuteRead $connectionString $sql $pars

Solution 9 - Powershell

You can even format string and pass parameters as you want.

case "ADDSQLSERVERUSER":
    //0 = coprorateName;
    //1 = user password
    //2 = servername
    command = @"$sqlQuery = Use JazzUWS_'{0}' 
                Create login UWSUser_'{0}' with password='{1}';
                Create user UWSUser_'{0}' for login UWSUser_'{0}';
                Grant Execute to UWSUser_'{0}';

                Use ReportSvrUWS_'{0}' 
                Create user UWSUser_'{0}' for login UWSUser_'{0}';
                Grant Execute to UWSUser_'{0}';

                Invoke-Sqlcmd -Query $sqlQuery -ServerInstance '{2}'";
    break;

C# Code for remote execution(you can organize your way)

        string script = PowershellDictionary.GetPowershellCommand("ADDSQLSERVERUSER");
        script = String.Format(script, this.CorporateName, password, this.SQLServerName)
        PowerShellExecution.RunScriptRemote(_credentials.Server, _credentials.Username, _credentials.Password, new List<string> { script });

Solution 10 - Powershell

You could use the best SQL Server module around: DBATOOLS. You would also benefit from running a query to multiple sql instances.

Install-Module dbatools -Scope CurrentUser

$sql = 'SQL1','SQL1\INSTANCE1','SQL2'
$query = "SELECT 'This query would run on all SQL instances'"

Invoke-DbaQuery -SqlInstance $sqlinstances -Query $query -AppendServerInstance

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTigger78View Question on Stackoverflow
Solution 1 - PowershellChris MagnusonView Answer on Stackoverflow
Solution 2 - PowershellmanojldsView Answer on Stackoverflow
Solution 3 - PowershellmcobrienView Answer on Stackoverflow
Solution 4 - PowershelldmcView Answer on Stackoverflow
Solution 5 - PowershellAdamView Answer on Stackoverflow
Solution 6 - PowershellAaron JensenView Answer on Stackoverflow
Solution 7 - PowershellVisheView Answer on Stackoverflow
Solution 8 - PowershellPieroView Answer on Stackoverflow
Solution 9 - PowershellMajedurView Answer on Stackoverflow
Solution 10 - PowershellPollusBView Answer on Stackoverflow