使用 Windows 身份验证和模拟用户将 PowerShell 连接到 SQL 服务器

Connecting PowerShell to SQL Server using Windows authentication and impersonating user

我找到了很多关于如何通过 PowerShell 使用当前登录的用户 Windows 身份验证或使用 SQL 服务器帐户连接到 SQL 服务器的信息连接其他凭据。我想知道是否有办法连接 Windows 身份验证但冒充另一个 Windows 用户。

以下是我发现可以使用 Windows 身份验证或 SQL 服务器身份验证连接到 SQL 服务器数据库的方法:

Windows 使用 .Net 进行身份验证:

$Connection = New-Object System.Data.SqlClient.SQLConnection
$Connection.ConnectionString = "Data Source=$SQLServer;Integrated Security=$true;Initial Catalog=$Database"
$Connection.Open()

SQL 使用 .Net 的服务器身份验证:

$CredentialObject = New-Object System.Management.Automation.PSCredential -ArgumentList $SQLUsername,$SQLPassword
$CredentialObject.Password.MakeReadOnly()
$SQLCredential = New-Object System.Data.SqlClient.SqlCredential($CredentialObject.UserName,$CredentialObject.Password)

$Connection = New-Object System.Data.SqlClient.SQLConnection
$Connection.ConnectionString = "Data Source=$SQLServer;Initial Catalog=$Database"
$Connection.Credential = $SQLCredential

Windows 使用 SqlServer 模块进行身份验证:

Invoke-Sqlcmd -ServerInstance $SQLServer -Database $Database -Query "SELECT....."

SQL 服务器身份验证使用 SqlServer 模块:

Invoke-Sqlcmd -ServerInstance $SQLServer -Database $Database -Query "SELECT....." -Username $SQLUsername -Password $SQLPassword

我注意到 Invoke-Sqlcmd 存在 -Credential 标志,但 according to this post 也假定 SQL 服务器身份验证并且不能使用 Windows 身份验证。

如果我想使用 Windows 身份验证来模拟用户,还有其他可用的选项吗?

提前致谢

suggested post 在不同的用户上下文中似乎 运行 它是正确的,但由于某些原因它不适用于 SQL 查询,很可能是因为命令包含单个引号 '。当使用任何比 SELECT * FROM dbo.MyTable 更复杂的东西时,它不会正确地 运行,例如当你 运行 WHERE MyColumn LIKE '%filter%' 时。即使 运行 正确,它也不会产生任何输出,因为在 Start-Process 中不会告诉我什么失败了,如果有的话。我需要一种方法来捕获 StandardOutput 和 StandardError。

我找到的解决方案是 this post,它允许我使用 System.Diagnostics.ProcessStartInfo 捕获输出。但是,我还需要在不同的用户上下文中 运行 它,这可以通过 .UserName.Domain.Password 实现。最终代码如下所示:

$ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$ProcessStartInfo.CreateNoWindow = $true
$ProcessStartInfo.UseShellExecute = $false
$ProcessStartInfo.RedirectStandardOutput = $true
$ProcessStartInfo.RedirectStandardError = $true
$ProcessStartInfo.FileName = 'powershell.exe'
$ProcessStartInfo.Arguments = @("-Command",$MyCommand)
$ProcessStartInfo.UserName = $Username
$ProcessStartInfo.Domain = $Domain
$ProcessStartInfo.Password = $Password
$Process = New-Object System.Diagnostics.Process
$Process.StartInfo = $ProcessStartInfo
[void]$Process.Start()
$StandardOutput = $Process.StandardOutput.ReadToEnd()
$StandardError = $Process.StandardError.ReadToEnd()
$Process.WaitForExit()

if ($Process.ExitCode -eq 1) {

    throw $StandardError

}
else {

    Write-Output $StandardOutput

}

$MyCommand 是我需要 运行 的完整命令,如下所示:

$SQLCommand = $SQLCommand -replace "'","''"

$MyCommand = '
$Connection = New-Object System.Data.SqlClient.SQLConnection
$Connection.ConnectionString = ''Data Source=' + $SQLServer + ';Integrated Security=' + $true + ';Initial Catalog=' + $Database + '''

$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'

$SQLCommand 是我将 运行 对数据库的 SQL 查询,我对所有单引号执行 -replace 以向它们添加两个,因为这个查询有两个步骤被传递,首先是 $MyCommand 然后在实际过程中 运行s.

我完全知道这会带来许多不同的 SQL 注入问题,但这是我们已经接受的安全风险。您的里程可能会有所不同。