PowerShell调用SmtpClient通过SendGrid发邮件部分机器运行失败
你遇到的An attempt was made to access a socket in a way forbidden by its access permissions错误属于Windows系统错误码10013,本质是系统层面禁止了当前PowerShell进程的套接字出站请求,结合“同设备C#代码可正常运行”的排查结果,可排除网络、端口、防火墙的通用限制,可能成因和对应解决方法如下:
成因1:Windows Defender应用控制策略限制了PowerShell的网络权限
Windows Defender的应用控制规则、Exploit保护策略会针对不同进程设置独立的权限规则,C#编译后的可执行程序和PowerShell的进程规则是分开配置的,可能仅限制了PowerShell的出站套接字访问权限。
解决方法:- 打开Windows安全中心→应用和浏览器控制→漏洞利用保护→程序设置
- 找到64位PowerShell路径
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe和32位路径C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe,分别点击编辑 - 取消勾选“仅允许经审核的应用创建套接字连接”选项,保存后重启PowerShell测试
- 若仍无效可运行
secpol.msc打开本地安全策略,查看应用程序控制策略→AppLocker下是否有限制PowerShell网络访问的规则,删除对应规则即可。
成因2:PowerShell加载的.NET Framework配置存在网络限制
独立C#程序使用自身exe目录下的.config配置文件,而PowerShell会默认加载自身的配置文件powershell.exe.config和系统级machine.config,如果配置文件中存在错误的代理设置、套接字限制规则,会导致网络请求被拦截。
解决方法:- 进入
C:\Windows\System32\WindowsPowerShell\v1.0\目录,查看是否存在powershell.exe.config文件,若存在可先重命名为其他名称临时测试脚本是否恢复正常 - 在脚本开头添加以下代码强制重置.NET网络协议配置:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls13 [System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()- 运行命令
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select-Object ProxyServer, ProxyEnable检查是否存在无效代理配置,若有可以手动关闭代理。
- 进入
成因3:PowerShell进程运行的完整性级别不足
如果PowerShell是以低完整性级别启动的,系统会默认禁止其创建出站套接字连接,而你运行C#代码时使用了更高权限的上下文,就会出现两边执行结果不一致的情况。
解决方法:右键点击PowerShell快捷方式,选择“以管理员身份运行”后再执行脚本测试,如果运行正常,后续可以在PowerShell快捷方式属性→高级中勾选“以管理员身份运行”,默认使用高权限启动。成因4:系统端口排除范围与SMTP端口冲突
部分Windows设备会因为安装虚拟化软件、VPN工具等修改TCP端口排除范围,如果SendGrid使用的SMTP端口刚好在排除范围内,就会导致PowerShell无法绑定端口发起请求。
解决方法:- 以管理员身份运行PowerShell,执行命令
netsh int ipv4 show excludedportrange protocol=tcp查看端口排除范围,确认你测试的587、465、25、2525端口是否在排除列表中 - 如果端口在排除列表中,执行命令
netsh int ipv4 set dynamicport tcp start=10000 num=50000调整动态端口范围,重启设备后再测试。
- 以管理员身份运行PowerShell,执行命令
内容的提问来源于stack exchange,提问作者wrenchMonkey

