如何用SSIS包从SharePoint 365的"S & P"文档库下载全量文件
我来帮你搞定这个SharePoint Online文档库批量下载的问题!你之前用网上的代码失败,大概率是没处理好带特殊字符的库名(比如你的"S & P")或者递归遍历的逻辑,下面给你两种经过验证的实现方案,分别对应SSIS脚本任务(C#)和执行进程任务(PowerShell):
方案一:SSIS脚本任务(C#实现)
这个方案用CSOM直接连接SharePoint Online,递归遍历所有文件夹并下载文件,能很好处理带特殊字符的库名。
准备工作
在SSIS脚本任务的项目中,右键点击项目 -> Manage NuGet Packages,搜索并安装Microsoft.SharePointOnline.CSOM包(版本选最新稳定版即可)。
完整C#代码
using System; using System.IO; using Microsoft.SharePoint.Client; using System.Security; public void Main() { // 替换为你的SPO站点URL string siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"; // 文档库名称直接使用带特殊字符的名称即可 string libraryName = "S & P"; // 替换为本地/服务器的目标路径 string localPath = @"C:\SP_Downloads"; // 替换为你的SPO账户和密码 string userName = "youruser@yourtenant.onmicrosoft.com"; string password = "yourpassword"; // 转换密码为安全字符串 SecureString securePassword = new SecureString(); foreach (char c in password) { securePassword.AppendChar(c); } try { using (ClientContext ctx = new ClientContext(siteUrl)) { ctx.Credentials = new SharePointOnlineCredentials(userName, securePassword); // 获取目标文档库 List library = ctx.Web.Lists.GetByTitle(libraryName); ctx.Load(library); ctx.ExecuteQuery(); // 获取库的根文件夹,加载子文件夹和文件 Folder rootFolder = library.RootFolder; ctx.Load(rootFolder); ctx.Load(rootFolder.Folders); ctx.Load(rootFolder.Files); ctx.ExecuteQuery(); // 创建本地根目录 if (!Directory.Exists(localPath)) { Directory.CreateDirectory(localPath); } // 下载根文件夹文件 + 递归遍历子文件夹 DownloadFilesFromFolder(rootFolder, localPath, ctx); TraverseFolders(rootFolder.Folders, localPath, ctx); Dts.TaskResult = (int)ScriptResults.Success; } } catch (Exception ex) { // 抛出错误信息到SSIS日志 Dts.Events.FireError(0, "SP Download Task", $"{ex.Message}\n{ex.StackTrace}", string.Empty, 0); Dts.TaskResult = (int)ScriptResults.Failure; } } // 递归遍历所有子文件夹 private void TraverseFolders(FolderCollection folders, string parentLocalPath, ClientContext ctx) { foreach (Folder folder in folders) { ctx.Load(folder); ctx.Load(folder.Folders); ctx.Load(folder.Files); ctx.ExecuteQuery(); // 创建对应的本地子文件夹 string localFolderPath = Path.Combine(parentLocalPath, folder.Name); if (!Directory.Exists(localFolderPath)) { Directory.CreateDirectory(localFolderPath); } // 下载当前文件夹文件 + 继续递归子文件夹 DownloadFilesFromFolder(folder, localFolderPath, ctx); TraverseFolders(folder.Folders, localFolderPath, ctx); } } // 下载单个文件夹内的所有文件 private void DownloadFilesFromFolder(Folder folder, string localPath, ClientContext ctx) { foreach (File file in folder.Files) { ctx.Load(file); ctx.ExecuteQuery(); // 获取文件二进制流并保存到本地 FileInformation fileInfo = File.OpenBinaryDirect(ctx, file.ServerRelativeUrl); string localFilePath = Path.Combine(localPath, file.Name); using (FileStream fs = new FileStream(localFilePath, FileMode.Create)) { fileInfo.Stream.CopyTo(fs); } } } // SSIS脚本任务结果枚举 enum ScriptResults { Success = 0, Failure = 1 }
注意事项
- 推荐使用Azure AD应用权限代替用户名密码(更安全,避免密码过期),如果需要可以告诉我,我再补充应用权限的代码
- 确保SSIS执行账户对目标本地/服务器路径有读写权限
- 库名要和SharePoint上的名称完全一致(包括大小写、特殊字符)
方案二:执行进程任务(PowerShell脚本实现)
这个方案用PnP PowerShell模块,语法更简洁,适合喜欢用脚本的场景。
完整PowerShell脚本
param( [string]$SiteUrl = "https://yourtenant.sharepoint.com/sites/yoursite", [string]$LibraryName = "S & P", [string]$LocalPath = "C:\SP_Downloads", [string]$UserName = "youruser@yourtenant.onmicrosoft.com", [string]$Password = "yourpassword" ) # 检查并安装PnP PowerShell模块(首次运行需要) if (-not (Get-Module -ListAvailable -Name PnP.PowerShell)) { Install-Module -Name PnP.PowerShell -Force -AllowClobber -Scope CurrentUser } Import-Module PnP.PowerShell # 转换密码为安全字符串 $SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force $Credentials = New-Object System.Management.Automation.PSCredential ($UserName, $SecurePassword) # 连接到SharePoint Online Connect-PnPOnline -Url $SiteUrl -Credentials $Credentials # 创建本地根目录 if (-not (Test-Path $LocalPath)) { New-Item -ItemType Directory -Path $LocalPath | Out-Null } # 获取文档库根文件夹 $Library = Get-PnPList -Identity $LibraryName $RootFolder = Get-PnPFolder -Url $Library.RootFolder.ServerRelativeUrl # 递归下载文件夹的函数 function Download-Folder { param( [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder]$Folder, [Parameter(Mandatory=$true)] [string]$LocalFolderPath ) # 下载当前文件夹所有文件 Get-PnPFile -Folder $Folder -AsFile -Path $LocalFolderPath -Force | Out-Null # 获取所有子文件夹(跳过系统默认的Forms文件夹) $SubFolders = Get-PnPFolder -Folder $Folder | Where-Object { $_.Name -ne "Forms" } foreach ($SubFolder in $SubFolders) { $LocalSubFolderPath = Join-Path $LocalFolderPath $SubFolder.Name if (-not (Test-Path $LocalSubFolderPath)) { New-Item -ItemType Directory -Path $LocalSubFolderPath | Out-Null } # 递归下载子文件夹 Download-Folder -Folder $SubFolder -LocalFolderPath $LocalSubFolderPath } } # 启动下载 Download-Folder -Folder $RootFolder -LocalFolderPath $LocalPath # 断开连接 Disconnect-PnPOnline
SSIS执行进程任务配置
- 在SSIS包中添加执行进程任务
- 在任务编辑器的进程选项卡:
- 可执行文件:
powershell.exe - 参数:
-File "C:\Scripts\SP_Download.ps1" -SiteUrl "https://yourtenant.sharepoint.com/sites/yoursite" -LibraryName "S & P" -LocalPath "C:\SP_Downloads" -UserName "youruser@yourtenant.onmicrosoft.com" -Password "yourpassword"
(注意参数里的路径和字符串要加双引号)
- 可执行文件:
注意事项
- 执行SSIS的账户需要有安装PowerShell模块的权限,或者提前在服务器上安装好
PnP.PowerShell - 避免在脚本里硬编码密码,推荐用SSIS配置或者环境变量传递敏感信息
- 同样要确保执行账户有文档库读取权限和本地路径读写权限
常见错误排查
如果还是失败,先检查这几点:
- SPO站点URL是否正确,有没有拼写错误
- 账户是否能在浏览器正常访问并下载该文档库的文件
- 本地路径是否存在,执行账户是否有读写权限
- 库名是否和SharePoint上的完全一致(包括空格、特殊字符)
内容的提问来源于stack exchange,提问作者ankur jain
相关产品推荐
相关产品推荐

