如何使用PowerShell下载托管Exchange服务器中的所有邮箱?
无需付费工具批量导出托管Exchange所有邮箱的方案
既然你手握所有邮箱的完全访问权限,又不想花钱买MailStore这类归档工具,下面这几个方案绝对能帮你绕开不配合的服务商,自己搞定批量导出。
方法1:Exchange Management Shell(EMS)远程导出(首推)
这是Exchange官方原生的最可靠批量导出方式,只要能远程连接到托管Exchange的PowerShell端点就行。
步骤1:远程连接到Exchange PowerShell
- 以管理员身份打开Windows PowerShell
- 输入命令并按提示填写管理员账户凭据:
$UserCredential = Get-Credential - 替换
<远程Exchange服务器地址>为实际的PowerShell访问地址(通常是https://你的Exchange域名/PowerShell/),执行连接命令:$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://<远程Exchange服务器地址>/PowerShell/ -Credential $UserCredential -Authentication Basic -AllowRedirection - 导入Exchange命令会话:
Import-PSSession $Session
步骤2:分配导出权限
默认管理员账户可能没有邮箱导入导出权限,先补上这个角色:
New-ManagementRoleAssignment -Role "Mailbox Import Export" -User <你的管理员账户名>
步骤3:批量导出所有邮箱到PST
先准备一个网络共享文件夹(比如你本地服务器的共享目录),必须确保Exchange的Exchange Trusted Subsystem组对这个文件夹有读写权限,否则导出会直接失败。
然后运行批量导出脚本:
# 获取所有邮箱(不限数量) $mailboxes = Get-Mailbox -ResultSize Unlimited # 循环导出每个邮箱到共享目录 foreach ($mailbox in $mailboxes) { # 替换为你的共享文件夹路径 $pstPath = "\\你的共享服务器\Exchange-PSTs\$($mailbox.Alias).pst" # 启动导出请求,设置100个坏项目容错(可根据实际调整) New-MailboxExportRequest -Mailbox $mailbox.Alias -FilePath $pstPath -BadItemLimit 100 }
查看进度&清理请求
- 查看所有导出请求状态:
Get-MailboxExportRequest - 查看单个邮箱的详细导出进度:
Get-MailboxExportRequestStatistics -Identity "<邮箱别名>\MailboxExport" - 导出完成后清理无用请求:
Get-MailboxExportRequest | Where-Object {$_.Status -eq "Completed"} | Remove-MailboxExportRequest
方法2:Exchange Web Services(EWS)脚本导出
如果托管服务商限制了PowerShell访问,但开启了EWS服务,你可以用EWS Managed API写脚本实现批量导出。
准备工作
- 安装微软官方提供的EWS Managed API
- 确认管理员账户仍拥有所有邮箱的完全访问权限
示例PowerShell脚本
# 加载EWS程序集(路径根据你安装的版本调整) Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll" # 配置基础参数 $ewsUrl = "https://<远程Exchange服务器>/EWS/Exchange.asmx" $credential = Get-Credential $localPstDir = "C:\本地PST存储目录\" # 确保磁盘空间足够 # 自动创建存储目录(如果不存在) if (-not (Test-Path $localPstDir)) { New-Item -Path $localPstDir -ItemType Directory | Out-Null } # 获取所有邮箱(如果EMS连不了,可手动替换为邮箱列表数组) $mailboxes = Get-Mailbox -ResultSize Unlimited foreach ($mailbox in $mailboxes) { try { # 初始化EWS服务并模拟目标邮箱 $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2016) $service.Credentials = $credential $service.Url = New-Object Uri($ewsUrl) $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $mailbox.PrimarySmtpAddress) # 绑定邮箱根目录并定义要导出的文件夹(按需调整) $rootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot) $targetFolders = @("Inbox", "Sent Items", "Deleted Items", "Calendar", "Contacts") # 创建PST文件并开始导出 $pstPath = Join-Path $localPstDir "$($mailbox.Alias).pst" $pstStore = New-Object Microsoft.Exchange.WebServices.Data.PstStore($pstPath) foreach ($folderName in $targetFolders) { $targetFolder = $rootFolder.FindFolders([Microsoft.Exchange.WebServices.Data.FolderView]::Unlimited) | Where-Object {$_.DisplayName -eq $folderName} if ($targetFolder) { Write-Host "正在导出 $($mailbox.Alias) 的 $folderName..." $targetFolder.CopyTo($pstStore.RootFolder) } } $pstStore.Dispose() Write-Host "$($mailbox.Alias) 导出完成!" } catch { Write-Error "$($mailbox.Alias) 导出失败:$_" } }
方法3:Outlook批量自动化导出(适合小批量)
如果上面两种方法都受限,你可以在本地安装Outlook,用PowerShell自动化添加所有邮箱并导出PST。不过这个方法速度较慢,更适合邮箱数量不多的场景。
示例脚本
# 初始化Outlook对象 $outlook = New-Object -ComObject Outlook.Application $namespace = $outlook.GetNamespace("MAPI") # 邮箱列表(可从CSV导入,或手动填写) $mailboxes = @("user1@domain.com", "user2@domain.com", "user3@domain.com") foreach ($mailbox in $mailboxes) { try { # 添加共享邮箱到Outlook $recipient = $namespace.CreateRecipient($mailbox) $recipient.Resolve() $sharedMailbox = $namespace.GetSharedDefaultFolder($recipient, [Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox).Parent # 创建并绑定PST文件 $pstPath = "C:\Outlook-PSTs\$($mailbox.Split('@')[0]).pst" $namespace.AddStore($pstPath) $pstFolder = $namespace.Session.Folders | Where-Object {$_.Store.FilePath -eq $pstPath} # 复制所有文件夹到PST foreach ($folder in $sharedMailbox.Folders) { $folder.CopyTo($pstFolder) } # 移除PST存储并清理 $namespace.RemoveStore($pstFolder) Write-Host "$mailbox 导出完成!" } catch { Write-Error "$mailbox 导出失败:$_" } } # 释放Outlook COM对象,避免内存泄漏 [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null
注意事项
- 确保Outlook已登录管理员账户,且有权限访问所有目标邮箱
- 导出过程中不要关闭Outlook
- 大邮箱可能需要较长时间,建议后台运行并保持网络稳定
内容的提问来源于stack exchange,提问作者DrDamnit
相关产品推荐
相关产品推荐

