通过Active Directory条目将用户网络文件夹迁移至OneDrive(PowerShell/C#实现)
实现Active Directory指定OU用户文件夹迁移至OneDrive
一、PowerShell实现方案
前置要求
- 已安装Active Directory模块(通过RSAT工具安装)
- 运行脚本的账号需同时具备:AD读取权限、文件服务器文件夹读写权限、OneDrive站点读写权限
- 提前确认用户的OneDrive目标路径
UsersOne-Drive\UserFileServerFolder已存在(可通过OneDrive批量配置工具预创建)
脚本代码及说明
# 导入AD模块 Import-Module ActiveDirectory # 替换为实际目标OU的LDAP路径 $targetOU = "OU=Sales,DC=contoso,DC=com" # 替换为文件服务器共享文件夹的前缀路径 $sourcePathPrefix = "\\FileServer\UsersFolders" # 替换为OneDrive的目标路径前缀 $targetPathPrefix = "\\contoso-my.sharepoint.com\personal\contoso_com\UsersOne-Drive\UserFileServerFolder" # 获取目标OU下的所有用户 $users = Get-ADUser -Filter * -SearchBase $targetOU foreach ($user in $users) { $username = $user.SamAccountName $sourceFolder = Join-Path -Path $sourcePathPrefix -ChildPath $username $targetFolder = Join-Path -Path $targetPathPrefix -ChildPath $username # 检查源文件夹是否存在 if (Test-Path $sourceFolder) { # 目标文件夹不存在则创建 if (-not (Test-Path $targetFolder)) { New-Item -ItemType Directory -Path $targetFolder | Out-Null } # 移动文件夹全部内容(如需保留原文件夹,先改用Copy-Item,确认后再删除原文件夹) Move-Item -Path "$sourceFolder\*" -Destination $targetFolder -Force -Recurse # 可选:迁移完成后删除原文件夹(测试通过后再启用) # Remove-Item -Path $sourceFolder -Recurse -Force Write-Host "用户 $username 的文件夹迁移完成" } else { Write-Warning "用户 $username 的源文件夹不存在:$sourceFolder" } }
实操注意
- 先针对单个用户测试脚本,验证路径和权限是否正常
- 大体积文件夹建议分批次迁移,避免占用过多系统资源
- 若需备份原数据,先执行
Copy-Item完成复制,确认无误后再删除原文件夹
二、C#实现方案
前置要求
- 引用依赖:
System.DirectoryServices.AccountManagement(操作AD)、System.IO(文件操作)、Microsoft.SharePoint.Client(操作OneDrive,需安装SharePoint CSOM NuGet包) - 账号权限要求同PowerShell方案
核心代码示例
using System; using System.DirectoryServices.AccountManagement; using System.IO; using Microsoft.SharePoint.Client; class OneDriveFolderMigration { static void Main(string[] args) { // 替换为实际目标OU路径 string targetOU = "OU=Sales,DC=contoso,DC=com"; string sourcePathPrefix = @"\\FileServer\UsersFolders"; // 替换为OneDrive站点的实际URL string oneDriveSiteUrl = @"https://contoso-my.sharepoint.com/personal/john_doe_contoso_com"; string targetFolderRelativePath = @"UsersOne-Drive\UserFileServerFolder"; // 连接AD查询目标OU下的用户 using (PrincipalContext adContext = new PrincipalContext(ContextType.Domain, null, targetOU)) { UserPrincipal userFilter = new UserPrincipal(adContext); using (PrincipalSearcher searcher = new PrincipalSearcher(userFilter)) { foreach (UserPrincipal user in searcher.FindAll()) { string username = user.SamAccountName; string sourceFolder = Path.Combine(sourcePathPrefix, username); if (Directory.Exists(sourceFolder)) { // 连接OneDrive并处理文件上传 using (ClientContext spContext = new ClientContext(oneDriveSiteUrl)) { // 配置认证(建议用Azure AD应用权限,避免账号过期风险) // var securePassword = new System.Security.SecureString(); // foreach (char c in "password") securePassword.AppendChar(c); // spContext.Credentials = new SharePointOnlineCredentials("admin@contoso.com", securePassword); Web web = spContext.Web; spContext.Load(web); spContext.ExecuteQuery(); // 获取OneDrive上的目标父文件夹 Folder parentFolder = web.GetFolderByServerRelativeUrl(targetFolderRelativePath); spContext.Load(parentFolder); spContext.ExecuteQuery(); // 创建对应用户的目标文件夹 Folder userTargetFolder = parentFolder.Folders.Add(username); spContext.Load(userTargetFolder); spContext.ExecuteQuery(); // 递归上传源文件夹内的所有内容 UploadFolderContents(sourceFolder, userTargetFolder, spContext); Console.WriteLine($"用户 {username} 的文件夹迁移完成"); // 可选:迁移完成后删除原文件夹 // Directory.Delete(sourceFolder, true); } } else { Console.WriteLine($"警告:用户 {username} 的源文件夹不存在:{sourceFolder}"); } } } } } // 递归上传文件夹内容到OneDrive static void UploadFolderContents(string sourceDir, Folder targetFolder, ClientContext spContext) { // 上传当前目录下的所有文件 foreach (string filePath in Directory.GetFiles(sourceDir)) { string fileName = Path.GetFileName(filePath); FileCreationInformation fileInfo = new FileCreationInformation { Content = System.IO.File.ReadAllBytes(filePath), Url = fileName, Overwrite = true }; Microsoft.SharePoint.Client.File uploadedFile = targetFolder.Files.Add(fileInfo); spContext.Load(uploadedFile); spContext.ExecuteQuery(); } // 递归处理子文件夹 foreach (string subDir in Directory.GetDirectories(sourceDir)) { string subDirName = Path.GetFileName(subDir); Folder subFolder = targetFolder.Folders.Add(subDirName); spContext.Load(subFolder); spContext.ExecuteQuery(); UploadFolderContents(subDir, subFolder, spContext); } } }
实操注意
- 认证方式优先选择Azure AD应用权限,避免使用账号密码带来的安全和过期问题
- 若需上传超过100MB的大文件,需改用SharePoint的分块上传API,上述代码仅适用于小文件场景
- 需添加try-catch异常处理,应对网络中断、权限不足等意外情况
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

