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

如何在PnP PowerShell 7中从CSV批量/并行上传文件到SharePoint

批量优化PnP PowerShell上传SharePoint文件的速度

问题描述

我正在寻求一种使用PnP PowerShell批量上传文件到SharePoint的解决方案。目前我编写了如下代码,通过逐行读取CSV文件来上传文件,但上传速度较慢,一小时仅能上传3000个文件。我希望通过批处理实现一小时至少上传7000-8000个文件,以下是我的代码:

Get-ChildItem -Path $CSVPath -Filter '*.csv' | Foreach-Object {
    #Import CSV
    $CSVData = import-csv $_

    # Built Url & Connect to PnP
    
    Connect-PnPOnline -Url $sharePointUrl 
    
    $CSVData | Foreach-Object {
      
        $Row = $_
Add-PnPFile -Path $Row.SourcePath -Folder $InsertorUpdateAt -Values $MetadataValue
}
}

核心优化方案

1. 消除重复连接开销

原代码在每个CSV文件循环内重复调用Connect-PnPOnline,连接握手过程会消耗大量时间。将连接逻辑移到所有循环外部,仅建立一次连接。

2. 启用并行处理

单线程逐行上传是速度瓶颈核心,通过多线程并行处理可成倍提升效率。根据PowerShell版本选择方案:

  • PowerShell 7+:使用ForEach-Object -Parallel原生并行特性,性能更优
  • PowerShell 5.x:使用Start-Job实现多作业并行

3. 预加载所有CSV数据

提前读取所有CSV文件内容到内存,避免循环中重复执行文件IO操作,减少磁盘读取开销。

4. 关闭冗余功能

在Connect-PnPOnline中添加-NoTelemetry参数,禁用遥测数据上报,减少额外网络请求。

优化后代码示例

PowerShell 7+ 推荐版本

# 仅建立一次SharePoint连接
Connect-PnPOnline -Url $sharePointUrl -NoTelemetry

# 一次性读取所有CSV文件数据到内存
$allUploadTasks = Get-ChildItem -Path $CSVPath -Filter '*.csv' | ForEach-Object {
    Import-Csv $_.FullName
}

# 并行上传文件,ThrottleLimit控制并发数(建议10-20,根据服务器负载调整)
$allUploadTasks | ForEach-Object -Parallel {
    # 在并行线程中获取共享连接上下文
    $context = Get-PnPContext
    $context.Load($context.Web)
    $context.ExecuteQuery()

    # 执行文件上传
    Add-PnPFile -Path $_.SourcePath -Folder $using:InsertorUpdateAt -Values $using:MetadataValue -Connection $context
} -ThrottleLimit 15

PowerShell 5.x 兼容版本

# 建立主连接(可选,作业内会独立建立连接)
Connect-PnPOnline -Url $sharePointUrl -NoTelemetry

# 预加载所有CSV上传任务
$allUploadTasks = Get-ChildItem -Path $CSVPath -Filter '*.csv' | ForEach-Object {
    Import-Csv $_.FullName
}

# 定义上传作业脚本块
$uploadJobScript = {
    param($sourcePath, $targetFolder, $metadata, $siteUrl)
    
    # 每个作业独立建立连接
    Connect-PnPOnline -Url $siteUrl -NoTelemetry
    Add-PnPFile -Path $sourcePath -Folder $targetFolder -Values $metadata
}

# 控制并发作业数量,避免触发SharePoint限流
$maxConcurrentJobs = 15
$currentRunningJobs = 0

foreach ($task in $allUploadTasks) {
    # 等待有作业完成后再启动新作业
    while ($currentRunningJobs -ge $maxConcurrentJobs) {
        $completedJobs = Get-Job -State Completed
        if ($completedJobs) {
            Receive-Job $completedJobs
            Remove-Job $completedJobs
            $currentRunningJobs -= $completedJobs.Count
        }
        Start-Sleep -Milliseconds 500
    }

    # 启动新上传作业
    Start-Job -ScriptBlock $uploadJobScript -ArgumentList $task.SourcePath, $InsertorUpdateAt, $MetadataValue, $sharePointUrl | Out-Null
    $currentRunningJobs++
}

# 等待所有剩余作业完成
while ($currentRunningJobs -gt 0) {
    $completedJobs = Get-Job -State Completed
    if ($completedJobs) {
        Receive-Job $completedJobs
        Remove-Job $completedJobs
        $currentRunningJobs -= $completedJobs.Count
    }
    Start-Sleep -Milliseconds 500
}

注意事项

  • 并发数需根据SharePoint服务器性能和带宽调整,过高可能触发请求限流(建议从10开始测试,逐步提升)
  • 确保源文件路径在所有并行线程/作业中可访问(本地文件无问题,网络共享需确认权限)
  • 上传大文件时,适当降低并发数,避免带宽饱和影响上传效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:36:36