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

PowerShell脚本提取Exchange Online邮箱全部附件失败寻求解决方案

提取Exchange Online邮箱指定类型附件的解决方案

问题背景

我不是PowerShell程序员/专家,缺乏脚本编写经验,现在需要解决一个问题:编写脚本提取Exchange Online邮箱的所有附件(仅图片、PDF、Word及Excel文件)。已经用Exchange Online管理模块连接了租户,写了一段脚本,执行无报错,能创建本地文件夹,但没提取到任何附件。另外不能使用Microsoft Purview合规门户的内容搜索功能,因为最终要把文件上传到SharePoint供数百位非技术用户访问,邮箱里有30多年的历史数据,求除内容搜索外的解决方案。

原脚本(无效)

#Scope to Mailbox
$Mailbox = "someemail@somedomain.com"

#Assign attachment location
$OutputFolder = "$env:USERPROFILE\Downloads\Mailbox Attachment Results"

#Create folder if doesn't exist
if (-not (Test-Path -Path $OutputFolder)) {
    New-Item -ItemType Directory -Path $OutputFolder | Out-Null
}

#Get attachments
$Attachments = Get-MailboxFolderStatistics -Identity $Mailbox -FolderScope All -IncludeOldestAndNewestItems | ForEach-Object {
    $Folder = $_.FolderPath.Replace("/", "\")
    $Permissions = Get-MailboxFolderPermission -Identity $Mailbox -User "Default" | Where-Object { $_.AccessRights -like "*CreateItems*" }
    if ($Permissions) {
        $Permissions | ForEach-Object {
            $FolderPermission = $_
            Get-MailboxFolderStatistics -Identity $Mailbox -FolderScope All -IncludeOldestAndNewestItems -Folder $_.FolderPath | Where-Object { $_.FolderPath -eq $FolderPermission.FolderPath } | ForEach-Object {
                $_.Folder.Attachments | ForEach-Object {
                    $Attachment = $_
                    $AttachmentPath = Join-Path -Path $OutputFolder -ChildPath ($Attachment.Name)
                    $Attachment.Content | ForEach-Object {
                        $_.Stream.Position = 0
                        $FileStream = [System.IO.File]::Create($AttachmentPath)
                        $_.Stream.CopyTo($FileStream)
                        $FileStream.Close()
                    }
                }
            }
        }
    }
}

原脚本问题分析

  • Get-MailboxFolderStatistics仅返回文件夹的统计信息(如项目数、大小),不包含邮件或附件的具体内容,所以无法通过它获取附件。
  • 权限判断逻辑完全错误:检查Default用户的CreateItems权限和提取附件无关,只要当前连接的账号有该邮箱的读取权限即可。
  • 重复调用Get-MailboxFolderStatistics属于无效操作,没有实际作用。

正确解决方案脚本

# 目标邮箱地址
$Mailbox = "someemail@somedomain.com"

# 附件保存路径
$OutputFolder = "$env:USERPROFILE\Downloads\Mailbox Attachment Results"

# 需要提取的附件扩展名(不区分大小写)
$AllowedExtensions = @(".jpg", ".jpeg", ".png", ".gif", ".pdf", ".docx", ".doc", ".xlsx", ".xls")

# 创建输出文件夹(不存在则创建)
if (-not (Test-Path -Path $OutputFolder)) {
    New-Item -ItemType Directory -Path $OutputFolder | Out-Null
}

# 获取邮箱所有文件夹的ID
$Folders = Get-EXOMailboxFolderStatistics -Identity $Mailbox -FolderScope All | Select-Object -ExpandProperty FolderId

# 遍历每个文件夹,获取邮件并提取附件
foreach ($FolderId in $Folders) {
    try {
        # 获取当前文件夹中的所有邮件(分批获取,避免超时)
        $Messages = Get-EXOMessage -Mailbox $Mailbox -FolderId $FolderId -PageSize 100 -All
        
        foreach ($Message in $Messages) {
            # 仅处理有附件的邮件
            if ($Message.HasAttachments) {
                foreach ($Attachment in $Message.Attachments) {
                    # 跳过内嵌附件(如邮件签名图片)
                    if (-not $Attachment.IsInline) {
                        # 检查附件扩展名是否在允许列表中(不区分大小写)
                        $FileExt = [System.IO.Path]::GetExtension($Attachment.Name).ToLower()
                        if ($AllowedExtensions -contains $FileExt) {
                            # 处理重复文件名:如果文件已存在,添加序号
                            $AttachmentPath = Join-Path -Path $OutputFolder -ChildPath $Attachment.Name
                            $Counter = 1
                            while (Test-Path -Path $AttachmentPath) {
                                $FileNameWithoutExt = [System.IO.Path]::GetFileNameWithoutExtension($Attachment.Name)
                                $AttachmentPath = Join-Path -Path $OutputFolder -ChildPath "$FileNameWithoutExt ($Counter)$FileExt"
                                $Counter++
                            }

                            # 保存附件到本地
                            $Attachment.Content | Set-Content -Path $AttachmentPath -Encoding Byte
                            Write-Host "已保存附件: $AttachmentPath"
                        }
                    }
                }
            }
        }
    }
    catch {
        Write-Warning "处理文件夹 $FolderId 时出错: $_"
        continue
    }
}

Write-Host "附件提取完成,所有文件已保存到: $OutputFolder"

注意事项

  • 权限要求:当前连接Exchange Online的账号需要拥有目标邮箱的Full Access权限,或者至少有Read and Manage权限。
  • 模块要求:确保已安装最新版的Exchange Online管理模块,可通过Install-Module -Name ExchangeOnlineManagement安装。
  • 大邮箱处理:脚本使用-PageSize 100分批获取邮件,避免因单次请求数据量过大导致超时;如果邮箱数据量极大,可考虑添加日期筛选(如-ReceivedAfter参数)分阶段提取。
  • 内嵌附件过滤:脚本跳过了内嵌附件(如邮件签名里的图片),如果需要提取这类附件,可删除if (-not $Attachment.IsInline)判断。
  • 重复文件处理:脚本会自动给重复文件名添加序号(如report.pdf→report (1).pdf),避免覆盖已有文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:14:52