PowerShell 批量下载 SharePoint Online 文档

  前言

  最近接到一个活,批量下载文档,可能有人说,为什么不用OOB的功能,因为太多了,还有多种条件筛选

  正文

  1.先分享PowerShell 命令,如下图:

<#
.SYNOPSIS
PowerShell 7专用 - 批量下载SharePoint Online文档库所有文档
.DESCRIPTION
保留原文件夹结构,支持过滤文件类型,适配MFA登录,兼容大文件下载
#>

# -------------------------- 可配置变量(按需修改) --------------------------
$siteUrl = "https://linyus.sharepoint.com/sites/Develop"  # SPO站点地址
$libraryName = "Shared Documents"                                     # 要下载的文档库名称(如"文档库""SiteAssets")
$localSavePath = "C:\SPO_Downloads"                              # 本地保存根路径(自动创建)
$filterFileTypes = @("*")                                        # 过滤下载的文件类型(示例:@("docx","pdf","xlsx") 仅下载这三类)
$overwriteExisting = $true                                       # 是否覆盖本地已存在的文件(true=覆盖,false=跳过)

# -------------------------- 核心函数:递归下载文件夹+文件 --------------------------
function Download-PnPDocumentLibrary {
    param(
        [Parameter(Mandatory)]
        [string]$SiteUrl,
        [Parameter(Mandatory)]
        [string]$LibraryName,
        [Parameter(Mandatory)]
        [string]$LocalRootPath,
        [array]$FilterFileTypes = @("*"),
        [bool]$Overwrite = $true,
        [string]$FolderServerRelativeUrl = $null
    )

    # 初始化参数
    if (-not $FolderServerRelativeUrl) {
        # 获取文档库的服务器相对路径(首次执行)
        $library = Get-PnPList -Identity $LibraryName -Includes RootFolder
        $FolderServerRelativeUrl = $library.RootFolder.ServerRelativeUrl
        Write-Host "📂 文档库根路径: $FolderServerRelativeUrl" -ForegroundColor Cyan
    }

    # 创建本地对应文件夹
    $localFolderPath = $LocalRootPath + $FolderServerRelativeUrl.Replace("/", "\")
    if (-not (Test-Path $localFolderPath)) {
        New-Item -ItemType Directory -Path $localFolderPath -Force | Out-Null
        Write-Host "✅ 创建本地文件夹: $localFolderPath" -ForegroundColor Green
    }

    # 1. 获取当前文件夹下的文件
    $files = Get-PnPFileInFolder -Identity "Shared Documents" # -FolderSiteRelativeUrl $FolderServerRelativeUrl -ErrorAction SilentlyContinue
    foreach ($file in $files) {
        # 过滤文件类型
        $fileExt = $file.Name.Split(".")[-1].ToLower()
        if ($FilterFileTypes -ne "*" -and $fileExt -notin $FilterFileTypes) {
            Write-Host "ℹ️ 跳过非目标类型文件: $($file.Name)" -ForegroundColor Yellow
            continue
        }

        # 拼接本地文件路径
        $localFilePath = Join-Path -Path $localFolderPath -ChildPath $file.Name

        # 跳过已存在的文件(若不覆盖)
        if (-not $Overwrite -and (Test-Path $localFilePath)) {
            Write-Host "ℹ️ 本地已存在,跳过: $($file.Name)" -ForegroundColor Yellow
            continue
        }

        # 下载文件
        try {
            Write-Host "⬇️ 正在下载: $($file.Name)" -ForegroundColor Cyan
            Get-PnPFile -Url $file.ServerRelativeUrl -Path $localFolderPath -FileName $file.Name -AsFile -Force:$Overwrite -ErrorAction Stop
            Write-Host "✅ 下载完成: $localFilePath" -ForegroundColor Green
        }
        catch {
            Write-Host "❌ 下载失败: $($file.Name) - $($_.Exception.Message)" -ForegroundColor Red
        }
    }

    # 2. 递归下载子文件夹
    $subFolders = Get-PnPFolder -Url $FolderServerRelativeUrl -Includes Folders | Select-Object -ExpandProperty Folders
    foreach ($folder in $subFolders) {
        if ($folder.Name -notin @("Forms", "_cts")) {  # 跳过系统文件夹
            Write-Host "📁 进入子文件夹: $($folder.ServerRelativeUrl)" -ForegroundColor Blue
            Download-PnPDocumentLibrary -SiteUrl $SiteUrl -LibraryName $LibraryName -LocalRootPath $LocalRootPath `
                -FilterFileTypes $FilterFileTypes -Overwrite $Overwrite -FolderServerRelativeUrl $folder.ServerRelativeUrl
        }
    }
}

# -------------------------- 执行入口 --------------------------
# 1. 检查并安装PnP.PowerShell
if (-not (Get-Module -ListAvailable -Name PnP.PowerShell)) {
    Write-Host "🔧 正在安装PnP.PowerShell模块..." -ForegroundColor Cyan
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction SilentlyContinue
    Install-Module -Name PnP.PowerShell -Force -AllowClobber -Scope CurrentUser -ErrorAction Stop
}
Import-Module PnP.PowerShell -DisableNameChecking -Force -ErrorAction Stop
Write-Host "✅ PnP.PowerShell模块加载成功`n" -ForegroundColor Green

# 2. 连接SPO站点
try {
    Write-Host "🔗 正在连接站点: $siteUrl" -ForegroundColor Cyan
    Connect-PnPOnline -Url $siteUrl -UseWebLogin -ErrorAction Stop
    Write-Host "✅ 站点连接成功`n" -ForegroundColor Green

    # 3. 检查文档库是否存在
    $library = Get-PnPList -Identity $libraryName -ErrorAction SilentlyContinue
    if (-not $library) {
        throw "文档库 '$libraryName' 不存在,请检查名称是否正确"
    }

    # 4. 创建本地保存根路径
    if (-not (Test-Path $localSavePath)) {
        New-Item -ItemType Directory -Path $localSavePath -Force | Out-Null
        Write-Host "📂 已创建本地保存路径: $localSavePath`n" -ForegroundColor Cyan
    }

    # 5. 开始批量下载
    Write-Host "🚀 开始批量下载文档库 '$libraryName' 的文件..." -ForegroundColor Green
    Download-PnPDocumentLibrary -SiteUrl $siteUrl -LibraryName $libraryName -LocalRootPath $localSavePath `
        -FilterFileTypes $filterFileTypes -Overwrite $overwriteExisting

    Write-Host "`n🎉 下载完成!所有文件已保存到: $localSavePath" -ForegroundColor Green
}
catch {
    Write-Host "`n❌ 执行出错: $($_.Exception.Message)" -ForegroundColor Red
    exit 1
}
finally {
    # 断开连接
    if (Get-PnPConnection) {
        Disconnect-PnPOnline -ErrorAction SilentlyContinue
        Write-Host "`n🔌 已断开SPO站点连接" -ForegroundColor Cyan
    }
}

  2.然后是执行成功的截图,如下图:

image

  3.再然后是下载成功的目录,如下图:

image

  结束语

  虽然用PowerShell,但是下载还是一个很漫长的过程

posted @ 2026-03-01 23:14  霖雨  阅读(113)  评论(0)    收藏  举报