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

Powershell下载SharePoint文件时如何跳过foreach循环错误与超时并记录日志

SPO下载脚本异常兼容优化方案

核心调整逻辑

  • 缩小异常捕获范围:原脚本将整个函数逻辑包裹在同一个try/catch中,任意节点报错都会直接跳出函数逻辑。修改后将单个文件下载、单个子文件夹递归的逻辑单独做异常捕获,单个资源出错不影响剩余任务执行。
  • 缩短请求超时时间:给SharePoint CSOM上下文设置更短的超时阈值,避免异常场景下长时间无响应。
  • 新增错误日志落盘:所有异常对应的文件/文件夹路径、错误信息、发生时间都会自动写入指定TXT日志文件,方便后续排查。

完整修改后代码

Function Download-SPOFolder()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )

    #Create Local Folder, if it doesn't exist
    $FolderName = ($SourceFolder.ServerRelativeURL) -replace "/","\\"
    $LocalFolder = Join-Path $TargetFolder $FolderName
    If (!(Test-Path -Path $LocalFolder)) {
            New-Item -ItemType Directory -Path $LocalFolder | Out-Null
    }

    #Get all Files from the folder
    Try {
        $FilesColl = $SourceFolder.Files
        $Ctx.Load($FilesColl)
        $Ctx.ExecuteQuery()
    }
    Catch {
        $logMsg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | 无法获取文件夹文件列表 | 路径:$($SourceFolder.ServerRelativeURL) | 错误:$($_.Exception.Message)"
        Add-Content -Path $ErrorLogPath -Value $logMsg
        Write-Host -f Red $logMsg
    }

    #Iterate through each file and download
    Foreach($File in $FilesColl)
    {
        $TargetFile = Join-Path $LocalFolder $File.Name
        Try {
            #Download the file
            $FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
            $WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
            $FileInfo.Stream.CopyTo($WriteStream)
            $WriteStream.Close()
            $WriteStream.Dispose()
            write-host -f Green "Downloaded File:"$TargetFile
        }
        Catch {
            $logMsg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | 文件下载失败 | 源路径:$($File.ServerRelativeURL) | 目标路径:$TargetFile | 错误:$($_.Exception.Message)"
            Add-Content -Path $ErrorLogPath -Value $logMsg
            Write-Host -f Red $logMsg
            # 清理残留流
            if($WriteStream) { $WriteStream.Dispose() }
            # 跳过当前文件继续执行
            Continue
        }
    }

    #Process Sub Folders
    Try {
        $SubFolders = $SourceFolder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
    }
    Catch {
        $logMsg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | 无法获取子文件夹列表 | 路径:$($SourceFolder.ServerRelativeURL) | 错误:$($_.Exception.Message)"
        Add-Content -Path $ErrorLogPath -Value $logMsg
        Write-Host -f Red $logMsg
        Return
    }
    
    Foreach($Folder in $SubFolders)
    {
        If($Folder.Name -ne "Forms")
        {
            Try {
                #Call the function recursively
                Download-SPOFolder -SiteURL $SiteURL -SourceFolder $Folder -TargetFolder $TargetFolder
            }
            Catch {
                $logMsg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | 子文件夹处理失败 | 路径:$($Folder.ServerRelativeURL) | 错误:$($_.Exception.Message)"
                Add-Content -Path $ErrorLogPath -Value $logMsg
                Write-Host -f Red $logMsg
                Continue
            }
        }
    }
}

#Set parameter values
$orgName="myOrgName"
$admin="myUsrName"
$SiteURL="myUrl"
$FolderRelativeUrl="myFolderUrl"
$TargetFolder="C:\\Temp"
# 错误日志存储路径,可自行修改
$ErrorLogPath = "C:\Temp\SPODownloadErrors.txt"

# 初始化错误日志目录和文件
$logDir = Split-Path $ErrorLogPath -Parent
if(-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir | Out-Null
}
if(-not (Test-Path $ErrorLogPath)) {
    New-Item -ItemType File -Path $ErrorLogPath | Out-Null
}

#Setup Credentials to connect
$cred  = Get-Credential -UserName $admin -Message GlobalAdminLogin
Connect-SPOService -Url https://$orgName-admin.sharepoint.com -Credential $cred
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)

#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
# 设置请求超时时间为10秒,单位为毫秒,可根据网络情况调整
$Ctx.RequestTimeout = 10 * 1000

#Get the Web
$Web = $Ctx.Web
$Ctx.Load($Web)
$Ctx.ExecuteQuery()
$Web.ServerRelativeUrl+$FolderRelativeUrl

#Get the Folder
$SourceFolder = $Web.GetFolderByServerRelativeUrl($Web.ServerRelativeUrl+$FolderRelativeUrl)
$Ctx.Load($SourceFolder)
$Ctx.ExecuteQuery()

#Call the function to download Folder
Download-SPOFolder -SiteURL $SiteURL -SourceFolder $SourceFolder -TargetFolder $TargetFolder

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:15:02