มีวิธีการดำเนินการสอบถามโดยพลการบน SQL Server โดยใช้ Powershell บนเครื่องของฉันหรือไม่?
มีวิธีการดำเนินการสอบถามโดยพลการบน SQL Server โดยใช้ Powershell บนเครื่องของฉันหรือไม่?
คำตอบ:
สำหรับคนอื่น ๆ ที่ต้องการทำสิ่งนี้ด้วยหุ้น. net และ PowerShell (ไม่ได้ติดตั้งเครื่องมือ SQL เพิ่มเติม) นี่คือฟังก์ชันที่ฉันใช้:
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
}
ฉันใช้มันมานานแล้วฉันไม่รู้ว่าใครเป็นคนเขียนส่วนใด แต่สิ่งนี้กลั่นจากตัวอย่างของคนอื่น แต่ทำให้เข้าใจง่ายและสิ่งที่ต้องการโดยไม่มีการพึ่งพาหรือคุณลักษณะพิเศษเพิ่มเติม
ฉันใช้และแบ่งปันสิ่งนี้บ่อยพอที่จะทำให้สิ่งนี้กลายเป็นโมดูลสคริปต์บนGitHubเพื่อให้คุณสามารถไปที่ไดเรกทอรีโมดูลของคุณและดำเนินการgit clone https://github.com/ChrisMagnuson/InvokeSQL
และจากจุดนั้นไปข้างหน้า invoke-sql จะถูกโหลดโดยอัตโนมัติเมื่อคุณใช้งาน (สมมติว่า การใช้ powershell v3 ของคุณหรือใหม่กว่า)
$connection.dispose()
เป็นต้นฉันไม่รู้ว่ามันสร้างความแตกต่างหรือไม่
คุณสามารถใช้Invoke-Sqlcmd
cmdlet
Invoke-Sqlcmd -Query "SELECT GETDATE() AS TimeOfQuery;" -ServerInstance "MyComputer\MyInstance"
Import-Module "sqlps" -DisableNameChecking
นี่คือตัวอย่างที่ฉันพบในบล็อกนี้
$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();
สมมุติคุณสามารถทดแทนคำสั่ง TSQL dbcc freeproccache
ที่แตกต่างกันที่จะกล่าวว่า
ExecuteNonQuery()
if ($cmd.ExecuteNonQuery() -ne 0)
ฟังก์ชันนี้จะส่งคืนผลลัพธ์ของแบบสอบถามเป็นอาร์เรย์ของวัตถุ PowerShell เพื่อให้คุณสามารถใช้พวกมันในตัวกรองและคอลัมน์เข้าถึงได้อย่างง่ายดาย:
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
(ดูคำตอบของอดัม )
หากคุณต้องการที่จะทำบนเครื่องท้องถิ่นของคุณแทนในบริบทของเซิร์ฟเวอร์ SQL แล้วฉันจะใช้ต่อไปนี้ นี่คือสิ่งที่เราใช้ใน บริษัท ของฉัน
$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
เพียงแค่กรอก$ ServerName , $ DatabaseNameและตัวแปร$ Queryและคุณควรจะดี
ผมไม่แน่ใจว่าวิธีการที่เราพบในขั้นต้นนี้ออก แต่มีบางสิ่งบางอย่างที่คล้ายกันมากที่นี่
Invoke-Sqlcmd -Query "sp_who" -ServerInstance . -QueryTimeout 3
ไม่มี "PowerShell" ในตัวในการเรียกใช้แบบสอบถาม SQL หากคุณติดตั้งเครื่องมือ SQL Serverคุณจะได้รับInvoke-SqlCmd cmdlet
เนื่องจาก PowerShell สร้างบน. NET คุณสามารถใช้ADO.NET APIเพื่อเรียกใช้คิวรีของคุณ
เพื่อหลีกเลี่ยง SQL Injection ด้วยพารามิเตอร์ varchar คุณสามารถใช้
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