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

PowerShell连接SharePoint Online(SPO)欧洲节点与雷德蒙德节点的差异及文件上传失败问题排查

SharePoint Online PowerShell上传脚本跨节点连接失败的诊断与解决

我来帮你拆解这个问题的核心原因,并给出几个可落地的解决方案:

问题根源定位

从你用cURL排查出来的差异可以明确,问题出在ALPN(应用层协议协商)阶段:

  • 美国雷德蒙德节点(13.107.136.9)支持HTTP/2(h2),客户端和服务器能顺利协商出可用协议,连接正常建立
  • 欧洲阿姆斯特丹节点(40.108.195.25)在ALPN协商时没有同意任何协议,导致后续连接被重置

你使用的SharePoint CSOM客户端(基于2016版本的组件),其依赖的.NET运行时在处理某些SPO节点的ALPN配置时存在兼容性问题,无法协商出合适的传输协议,最终触发了"The underlying connection was closed"错误。

可行解决方案

1. 强制客户端使用HTTP/1.1协议

直接绕过HTTP/2的协商问题,强制CSOM使用HTTP/1.1。在你的脚本初始化ClientContext的代码段后,添加以下配置:

# 强制禁用HTTP/2,使用HTTP/1.1
[System.AppContext]::SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", $false)
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

或者更针对性地修改ClientContext的请求配置:

$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$Ctx.Credentials = $Credentials
# 替换默认请求执行器,强制使用HTTP/1.1
$webRequestExecutor = New-Object Microsoft.SharePoint.Client.HttpWebRequestExecutor($Ctx, $url)
$webRequestExecutor.WebRequest.ProtocolVersion = [System.Net.HttpVersion]::Version11
$Ctx.WebRequestExecutorFactory = New-Object Microsoft.SharePoint.Client.SimpleWebRequestExecutorFactory($webRequestExecutor)

2. 更新CSOM组件到最新版本

你当前使用的是SharePoint 2016版本的CSOM(路径指向16\ISAPI),这个版本相对老旧,对现代SPO节点的协议支持不完善。建议替换为最新的SharePoint Online专用CSOM包,新版本修复了很多跨区域节点的兼容性问题。

下载后,将脚本中的Add-Type路径指向新的dll文件即可:

Add-Type -Path "C:\Path\To\New\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Path\To\New\Microsoft.SharePoint.Client.Runtime.dll"

3. 动态选择可用节点(替代hosts硬编码)

如果不想手动维护hosts文件,可以在脚本中添加自动检测逻辑,优先选择能正常连接的节点:

# 解析SPO域名的所有IP
$spoHost = [Uri]$url | Select-Object -ExpandProperty Host
$ipAddresses = [System.Net.Dns]::GetHostAddresses($spoHost) | Select-Object -ExpandProperty IPAddressToString

# 测试每个IP的连通性
$validIp = $null
foreach ($ip in $ipAddresses) {
    try {
        # 发送HEAD请求测试连接
        $testUri = "https://$ip"
        $response = Invoke-WebRequest -Uri $testUri -Method Head -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
        $validIp = $ip
        break
    }
    catch {
        Write-Host "跳过不可用IP: $ip" -ForegroundColor Yellow
        continue
    }
}

# 如果找到可用IP,临时修改hosts(需管理员权限)
if ($validIp) {
    $hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
    # 先删除旧的SPO条目
    (Get-Content $hostsPath) | Where-Object { $_ -notlike "*$spoHost*" } | Set-Content $hostsPath
    # 添加新的IP映射
    Add-Content $hostsPath "$validIp`t$spoHost" -Force
    Write-Host "已临时映射$spoHost到可用IP: $validIp" -ForegroundColor Green
}

注意:这个方法需要脚本以管理员权限运行,否则无法修改hosts文件。

为什么hosts硬编码有效?

硬编码美国节点IP后,客户端直接连接到支持HTTP/2的节点,跳过了DNS解析到欧洲节点的流程,自然避开了ALPN协商失败的问题,但这只是临时 workaround,长期来看还是需要从协议支持或CSOM版本入手彻底解决。

内容的提问来源于stack exchange,提问作者wowbagger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 13:47:36