PowerShell共享邮箱CSV附件保存与邮件移动代码修复
PowerShell 操作Outlook共享邮箱自动化脚本修正
原代码核心问题
- 第一层
foreach循环未定义单邮件循环变量,全程直接调用$fldr.Items集合本身,所有属性读取、操作都作用在整个邮件集合而非单封邮件上 - 发件人判断逻辑未放入
if分支块,仅写了判断表达式未做流程控制 - 目标文件夹
$DestFolder直接赋值为字符串路径,Outlook COM对象的Move方法要求传入MAPIFolder类型的实例,字符串路径无法被识别,导致移动失败 - 附件保存前未校验目标目录是否存在,会触发文件写入报错
- 邮件移动逻辑写在附件遍历循环内部,每遍历一个附件就会触发一次移动操作,导致重复操作报错
- CSV附件判断逻辑不严谨,仅用
Contains("CSV")会误匹配文件名任意位置带CSV字符的非CSV文件 - 正向遍历邮件集合时执行移动操作会修改集合本身,导致索引错乱、漏处理邮件
修正后完整代码
# 初始化Outlook COM对象 $outlook = New-Object -ComObject Outlook.Application $mapi = $outlook.GetNamespace("MAPI") # 弹窗选择需要处理的共享邮箱收件箱 $fldr = $mapi.PickFolder() # 读取收件箱下的目标子文件夹01.Reports $destFolder = $fldr.Folders["01.Reports"] # 附件命名计数器 $i = 1 # 本地附件存储根目录,请替换为实际路径 $saveRootPath = "C:\Your\Actual\Storage\Path\02.Daily Files" # 指定需要匹配的2个发件人显示名,请替换为实际名称 $targetSenders = @("Name1", "Name2") # 倒序遍历邮件,避免移动邮件导致集合索引错乱、漏处理 for ($mailIndex = $fldr.Items.Count; $mailIndex -ge 1; $mailIndex--) { $mail = $fldr.Items.Item($mailIndex) # 校验当前邮件发件人是否在目标列表内 if ($targetSenders -contains $mail.Sender.Name) { # 按邮件接收时间生成层级存储路径 $year = $mail.ReceivedTime.ToString("yyyy") $month = $mail.ReceivedTime.ToString("MM") $fdate = $mail.ReceivedTime.ToString("yyyy.MM.dd") $fpath = Join-Path $saveRootPath "$year\$year.$month\$fdate" # 自动创建不存在的存储目录 if (-not (Test-Path $fpath)) { New-Item -ItemType Directory -Path $fpath -Force | Out-Null } # 遍历邮件附件筛选CSV文件保存 foreach ($attach in $mail.Attachments) { $fileExt = [System.IO.Path]::GetExtension($attach.FileName) if ($fileExt -eq ".csv") { $saveFullName = Join-Path $fpath "00$i $($attach.FileName)" $attach.SaveAsFile($saveFullName) $i++ } } # 所有附件处理完成后移动邮件到目标文件夹 $mail.Move($destFolder) } }
使用说明
- 运行前替换
$saveRootPath为实际的本地文件存储根目录,替换$targetSenders数组内的两个值为实际需要匹配的发件人显示名 - 运行脚本时需保证Outlook处于启动状态,且当前账号已拥有目标共享邮箱的访问权限,弹出文件夹选择窗口时选中对应共享邮箱的收件箱即可
- 脚本会自动按照邮件接收时间的年、月、日创建层级存储目录,无需手动提前创建文件夹
- 脚本从最新邮件开始倒序处理,处理完成的邮件会直接移动到收件箱下的
01.Reports子文件夹,不会重复处理
内容的提问来源于stack exchange,提问作者europeanuser
相关产品推荐
相关产品推荐

