Gibt es eine Möglichkeit, eine beliebige Abfrage auf einem SQL Server mit Powershell auf meinem lokalen Computer auszuführen?
Gibt es eine Möglichkeit, eine beliebige Abfrage auf einem SQL Server mit Powershell auf meinem lokalen Computer auszuführen?
Antworten:
Für andere, die dies nur mit Standard-.net und PowerShell tun müssen (keine zusätzlichen SQL-Tools installiert), ist hier die Funktion, die ich verwende:
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
}
Ich benutze dies so lange, dass ich nicht weiß, wer welche Teile geschrieben hat, aber dies wurde aus den Beispielen anderer herausgearbeitet, aber vereinfacht, um klar zu sein und genau das, was ohne zusätzliche Abhängigkeiten oder Funktionen benötigt wird.
Ich benutze und teile dies oft genug, so dass ich es in ein Skriptmodul auf GitHub verwandelt habe, so dass Sie jetzt in Ihr Modulverzeichnis gehen und es ausführen können. git clone https://github.com/ChrisMagnuson/InvokeSQL
Von diesem Punkt an wird invoke-sql automatisch geladen, wenn Sie es verwenden (vorausgesetzt Sie verwenden Powershell v3 oder höher.
$connection.dispose()
usw. Ich weiß nicht, ob es einen Unterschied macht
Sie können das Invoke-Sqlcmd
Cmdlet verwenden
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
Import-Module "sqlps" -DisableNameChecking
Hier ist ein Beispiel, das ich in diesem Blog gefunden habe .
$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();
Vermutlich könnten Sie eine andere TSQL-Anweisung ersetzen, in der es heißt dbcc freeproccache
.
ExecuteNonQuery()
bei Erfolg null zurückgegeben. Die Bedingung, die ich verwende, ist : if ($cmd.ExecuteNonQuery() -ne 0)
.
Diese Funktion gibt die Ergebnisse einer Abfrage als Array von Powershell-Objekten zurück, sodass Sie sie problemlos in Filtern verwenden und auf Spalten zugreifen können:
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
}
DataTable
(siehe Adams Antwort )?
Wenn Sie dies auf Ihrem lokalen Computer anstatt im Kontext von SQL Server tun möchten, würde ich Folgendes verwenden. Es ist das, was wir in meiner Firma verwenden.
$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
Geben Sie einfach $ ServerName , $ DatabaseName und $ Query ein Variablen und Sie sollten gut zu gehen.
Ich bin nicht sicher , wie wir ursprünglich diesen herausgefunden, aber es ist etwas sehr ähnliche hier .
Es gibt keine integrierte "PowerShell" -Methode zum Ausführen einer SQL-Abfrage. Wenn Sie die SQL Server-Tools installiert haben , erhalten Sie ein Cmdlet Invoke- SqlCmd.
Da PowerShell auf .NET basiert, können Sie Ihre Abfragen mithilfe der ADO.NET-API ausführen.
Um SQL Injection mit varchar-Parametern zu vermeiden, können Sie verwenden
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 = "..."
$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