使用invoke-sqlcmd可连SQL Server,MSOLEDBSQL却报预登录失败
Azure VM连接本地SQL Server:MSOLEDBSQL驱动预登录失败(错误17830)
问题场景
从Azure虚拟机连接本地部署的SQL Server 2012 SP4(新版本SQL Server也存在相同问题),1433端口已开放,使用Invoke-Sqlcmd可正常连接,但通过MSOLEDBSQL驱动连接时,触发**“客户端无法建立连接,因预登录失败”**错误。查看SQL Server的system_health日志,发现错误记录:
SniProvider OSError SniConsumerError State 7 NULL 17830 105
成功的Invoke-Sqlcmd连接代码
$ConnectionString = "Server=$server;Database=master;User Id=$user;Password=$password;Encrypt=True;TrustServerCertificate=True;" Invoke-Sqlcmd -ConnectionString $ConnectionString -Query "select @@servername"
报错的MSOLEDBSQL连接代码
$Client_type='MSOLEDBSQL' $ConnectionString = "Provider=$Client_type;Server=$server;Database=master;UID=$user;PWD=$password;Encrypt=yes;Trust Server Certificate=true;" $SQLquery = "select @@servername as servername" $conn = New-Object System.Data.OleDb.OleDbConnection $conn.ConnectionString = $ConnectionString $comm = New-Object System.Data.OleDb.OleDbCommand($SQLquery,$conn) $conn.Open() $adapter = New-Object System.Data.OleDb.OleDbDataAdapter $comm $dataset = New-Object System.Data.DataSet $adapter.Fill($dataSet) $conn.Close() $table = $dataset.Tables[0] $table
排查与解决建议
- 统一连接字符串参数格式:将MSOLEDBSQL连接字符串中的
Trust Server Certificate=true改为TrustServerCertificate=True,和Invoke-Sqlcmd的参数格式保持一致,避免驱动解析差异 - 升级MSOLEDBSQL驱动:确保Azure VM上安装的是最新版的MSOLEDBSQL驱动,旧版本可能存在TLS协议兼容问题,无法适配Azure网络环境的加密要求
- 启用SQL Server端TLS 1.2:Azure VM默认强制使用TLS 1.2及以上版本,而SQL Server 2012默认未开启TLS 1.2,需通过修改注册表启用:
- 打开注册表编辑器,定位到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client,创建EnabledDWORD值并设为1 - 同路径下创建
DisabledByDefaultDWORD值并设为0 - 对
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server执行相同操作,重启SQL Server服务
- 打开注册表编辑器,定位到
- 强制使用TCP协议:在连接字符串的Server参数前添加
tcp:前缀,例如tcp:$server,1433,避免驱动尝试使用命名管道等不兼容的协议 - 检查SNI配置:错误17830与SQL Server网络接口(SNI)相关,确认本地SQL Server是否启用了SNI,且Azure VM的网络安全组未限制除1433外的其他必要端口(SNI可能用到的临时端口)
内容的提问来源于stack exchange,提问作者mbourgon
相关产品推荐
相关产品推荐

