我有一个powershell模块,它可以从多个变量中构建一个字符串,以便插入到sql server中。
$QueryInsert =
"
insert into dbo.Table
(
data
)
values
(
'$data'
)
"
Invoke-Sqlcmd -ServerInstance 'server_name' `
-Database db_name `
-Query $QueryInsert `
-QueryTimeout 20 `
-OutputSqlErrors $True `
-ConnectionTimeout 5 `
-ErrorAction Continue
这种方法的问题在于它不是特别安全,如果变量$ data包含任何单引号,则会失败。有办法防止这种情况吗?是否有一种方法可以使其保持安全?
答案 0 :(得分:4)
如果您有权访问数据库,则可以将查询编写为存储过程,然后使用PowerShell调用存储过程。您可以以安全的方式将参数传递给存储过程,这样就不会像上面的代码一样通过字符串注入代码。
您可能需要查看this question以了解如何编写存储过程以及this one.
为了从PowerShell调用SPROC,您可以使用与此类似的代码。
$sql='NameOfSprocBeingCalled'
$sqlConnection = new-object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = $SqlConnectionString
$sqlConnection.Open()
$sqlCommand = new-object System.Data.SqlClient.SqlCommand
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandText= $sql
$sqlCommand.CommandType = [System.Data.CommandType]::StoredProcedure
$sqlCommand.Parameters.Add("@Param1",[system.data.SqlDbType]::VarChar).value =$Param1
$sqlCommand.Parameters.Add("@Param2",[system.data.SqlDbType]::VarChar).value = $EventType
$Datatable = New-Object System.Data.DataTable
$DataReader = $sqlCommand.ExecuteReader()
$Datatable.Load($DataReader)
$sqlConnection.Close()
您只需确保使用[System.Data.SqlDbType] ::
传递参数的正确类型这是一个包含以下类型的枚举:
# [enum]::GetValues([System.Data.SqlDbType])
BigInt
Binary
Bit
Char
DateTime
Decimal
Float
Image
Int
Money
NChar
NText
NVarChar
Real
UniqueIdentifier
SmallDateTime
SmallInt
SmallMoney
Text
Timestamp
TinyInt
VarBinary
VarChar
Variant
Xml
Udt
Structured
Date
Time
DateTime2