You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PowerShell中使用应用程序池标识通过SqlClient连接SQL Server?

解决PowerShell模拟应用池身份连接SQL Server时的匿名登录失败问题

问题背景

我们有多台部署了ASP.NET应用的服务器,这些应用使用域账户作为应用程序池标识,且已通过sp_who2确认应用能正常用该身份连接SQL Server。现在尝试用PowerShell自动实现相同的连接逻辑:获取应用的连接字符串(带Trusted_Connection=yes)和应用程序池标识,模拟该身份连接SQL,但执行脚本时出现Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'错误。受业务限制无法修改连接字符串,且只能用.NET Framework 4.8的System.Data.SqlClient实现连接。

错误原因

核心问题是Kerberos双跳限制:当使用Invoke-Command指定域账户凭据执行脚本时,该身份的令牌无法从目标服务器(第一跳)委派到SQL Server(第二跳),导致SQL连接只能使用匿名身份。而ASP.NET应用池直接运行在服务器上,属于单跳场景,因此能正常连接。

解决方案

无需通过Invoke-Command远程执行,直接在本地脚本中模拟应用池的域账户身份,再创建SQL连接——这种单跳场景不会触发双跳限制。

修改后的测试代码

$username = 'DOMAIN\AppPoolAccount'
$password = 'AppPoolPassword'        

$ConnStr = 'Data Source=MyServer;Trusted_Connection=yes;'
$query = 'Select system_user, @@servername DBHostName,(SELECT login_time FROM sys.sysprocesses where spid=1)SQLUptime, @@version SQLVersion;'

# 创建模拟用的凭据对象
$securePassword = ConvertTo-SecureString -AsPlainText $password -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $securePassword)

# 获取目标账户的Windows身份令牌并开始模拟
$windowsIdentity = New-Object System.Security.Principal.WindowsIdentity($credential.UserName, $credential.GetNetworkCredential().Password)
$impersonationContext = $windowsIdentity.Impersonate()

try {
    Write-Host "当前模拟身份: $($windowsIdentity.Name)"
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
    $SqlConnection.ConnectionString = $ConnStr

    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlCmd.CommandText = $query
    $SqlCmd.Connection = $SqlConnection 
    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
    $SqlAdapter.SelectCommand = $SqlCmd 
    $SqlConnection.Open()
    
    $DataSet = New-Object System.Data.DataSet
    $SqlAdapter.Fill($DataSet) 
    $DataSet.Tables | Format-List
}
Catch {
    $_
}
Finally {
    # 清理SQL连接资源
    if ($SqlConnection.State -eq 'Open') {
        $SqlConnection.Close()
    }
    $SqlConnection.Dispose()
    # 结束身份模拟
    $impersonationContext.Undo()
    $impersonationContext.Dispose()
}

补充说明

  1. 若需在远程服务器执行脚本,建议直接在远程服务器本地运行(比如通过任务计划),避免跨机器的双跳场景。
  2. 若必须使用Invoke-Command,需在域控制器配置约束委派:将运行脚本的账户(或远程服务器的计算机账户)配置为允许委派到SQL Server的服务主体名称(SPN),例如MSSQLSvc/MyServer:1433。

内容的提问来源于stack exchange,提问作者VWP.CS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 13:03:21