Est-il possible d'exécuter une requête arbitraire sur un serveur SQL à l'aide de Powershell sur mon ordinateur local?
Pour les autres utilisateurs qui ont besoin de le faire avec les stocks .net et PowerShell (aucun outil SQL supplémentaire n'est installé), voici la fonction que j'utilise:
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
}
Je l'utilise depuis si longtemps que je ne sais pas qui a écrit quelles parties, mais cela a été extrait des exemples d'autres lecteurs, mais simplifié pour être clair et exactement ce qui est nécessaire sans dépendances ou fonctionnalités supplémentaires.
J'utilise et partage assez souvent ce que j'ai transformé en un module de script sur GitHub afin que vous puissiez maintenant aller dans votre répertoire de modules et exécuter git clone https://github.com/ChrisMagnuson/InvokeSQL
et à partir de là invoke-sql sera automatiquement chargé lorsque vous l'utiliserez (en supposant que vous utilisez powershell v3 ou une version ultérieure).
Vous pouvez utiliser l'applet de commande Invoke-Sqlcmd
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
Voici un exemple que j'ai trouvé sur ce 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();
Vous pouvez vraisemblablement substituer une autre instruction TSQL où il est écrit dbcc freeproccache
.
Cette fonction renverra les résultats d'une requête sous forme de tableau d'objets powershell afin que vous puissiez les utiliser dans des filtres et accéder facilement aux colonnes:
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
}
Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3
Il n'existe pas de méthode "PowerShell" intégrée permettant d'exécuter une requête SQL. Si vous avez le outils SQL Server installé , vous aurez une applet de commande Invoke-SqlCmd .
Etant donné que PowerShell est basé sur .NET, vous pouvez utiliser ADO.NET API pour exécuter vos requêtes.
Si vous voulez le faire sur votre machine locale au lieu de dans le contexte du serveur SQL, je voudrais utiliser ce qui suit. C'est ce que nous utilisons chez moi.
$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
Il suffit de renseigner les champs $ ServerName , $ DatabaseName et le $ Requête et vous devriez être prêt à partir.
Je ne suis pas sûr de savoir comment nous l'avons découvert, mais il y a quelque chose de très similaire ici .