如何在PS1脚本调用.exe前配置TLS解决连接意外关闭错误
问题根因
- 现有
Deploy.ps1PowerShell部署脚本运行时,会调用Microsoft.Legal.MatterCenter.CreateGroups.exe等预编译.NET工具完成SharePoint站点配置操作 - 执行到exe调用步骤时抛出连接错误:
The underlying connection was closed: An unexpected error occurred on a send.
堆栈跟踪定位错误触发点为System.Net.HttpWebRequest.GetResponse(),属于SharePoint客户端SDK发起HTTPS请求时连接被服务端强制关闭
- 已确认根因为进程未启用服务端要求的TLS协议版本,进程内标准修复代码为:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
- 常规提前在当前PowerShell控制台设置TLS配置的方案无效,原因是
Deploy.ps1自带权限提升逻辑,会启动独立的高权限PowerShell子进程执行后续逻辑,父进程的ServicePointManager配置不会自动继承到子进程,且被调用exe无源码无法修改内部逻辑。
可行修复方案
方案1:修改脚本提权逻辑,注入TLS初始化配置
该方案影响范围最小,仅对当前部署脚本生效,优先推荐使用:
- 定位到
Deploy.ps1中触发UAC提权、启动新高权限进程的代码段,通常为带-Verb RunAs参数的Start-Process命令 - 修改启动参数,让新高权限PowerShell进程在执行部署逻辑前,先完成TLS协议配置,示例代码如下:
# 定义需要提前执行的TLS配置命令 $tlsInit = "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12" # 获取当前脚本所在全路径 $deployScriptPath = Join-Path $PSScriptRoot "Deploy.ps1" # 启动高权限进程,先执行TLS配置再运行部署脚本 Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass -Command `"$tlsInit; & '$deployScriptPath'`"" -Verb RunAs
- 该配置会在新的高权限PowerShell进程初始化阶段完成TLS协议设置,后续该进程内调用的所有exe都会继承当前进程的安全协议配置,不会再触发TLS版本不匹配错误。
方案2:配置.NET全局注册表项,默认启用强TLS协议
如果不方便修改部署脚本内容,可以直接修改部署机器的.NET全局配置,所有基于.NET编写的程序都会默认读取该配置,无需单独在进程内设置:
- 以管理员身份打开PowerShell,执行以下两条命令配置注册表:
# 为64位.NET 4.0+程序启用强加密(支持TLS1.0/1.1/1.2) Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord -Force # 为32位.NET 4.0+程序启用强加密 Set-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord -Force
- 执行完成后重启机器即可生效,配置后所有.NET程序默认会兼容服务端要求的TLS版本,无需修改任何脚本或exe代码。
方案3:为单个exe添加配置文件指定TLS支持
如果不想修改系统全局配置,也可以针对每个被调用的exe单独添加运行时配置文件,.NET程序启动时会自动读取同目录下的同名配置文件加载参数:
- 进入目标exe所在目录,比如找到
Microsoft.Legal.MatterCenter.CreateGroups.exe的存放路径 - 新建和exe完全同名的
.config文件,即Microsoft.Legal.MatterCenter.CreateGroups.exe.config - 在文件中写入以下配置内容:
<configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> </runtime> </configuration>
- 对脚本调用的所有exe重复上述操作即可,配置仅对对应exe生效,不会影响其他程序。
注意事项
- 以上三个方案均不需要修改exe源码,满足限制要求
- 生产环境优先选择方案1,避免全局配置变更对其他业务程序造成未知影响
- 若使用方案2,建议在部署完成后根据实际需求评估是否保留注册表配置。
内容的提问来源于stack exchange,提问作者John John
相关产品推荐
相关产品推荐

