PowerShell读取.msg文件时Body属性为空的问题求助
读取.msg文件正文为空的解决方法
问题描述
我尝试通过PowerShell读取文件夹中.msg文件的正文内容来绕过工作环境权限限制,不管是在循环内每次创建Outlook COM对象,还是优化为循环外初始化,通过$outlook.CreateItemFromTemplate获取的邮件对象Body属性始终为空,但目标邮件确实存在正文。
初始代码
$output = "" ## get all the .msg files in the folder #Get-ChildItem "C:\Users\myfolder" -Filter *.msg | ##single test example for testing Get-ChildItem 'C:\Users\myfolder\Testemail.msg' | ForEach-Object{ $outlook = New-Object -comobject outlook.application $msg = $outlook.CreateItemFromTemplate($_.FullName) ##what have i even created write-host 'what is $msg anyway' $msg ##some trouble shooting things i saw in another thread, may be commented out #$msg | Select senderemailaddress,to,subject,Senton,body|ft -AutoSize $strCreateTime = $msg.ReceivedTime.ToString('yyyy-MM-dd hh:mm') $subject = $msg.Subject.ToString() write-host 'Body' $body = $msg.Body write-host $Body write-host 'After body' ## add the email stuff e.g. subject, bodys to a uber string tab delimited $output = $output + $strCreateTime+"`t"+$subject+"`t`n`r" Write-Host $output }
优化后代码
$output = "" ## get all the .msg files in the folder #Get-ChildItem "C:\Users\myfolder" -Filter *.msg | ##single test example for testing $outlook = New-Object -comobject outlook.application Get-ChildItem 'C:\Users\myfolder\Testemail.msg' | ForEach-Object{ $msg = $outlook.CreateItemFromTemplate($_.FullName) ##what have i even created write-host 'what is $msg anyway' $msg ##some trouble shooting things i saw in another thread, may be commented out #$msg | Select senderemailaddress,to,subject,Senton,body|ft -AutoSize $strCreateTime = $msg.ReceivedTime.ToString('yyyy-MM-dd hh:mm') $subject = $msg.Subject.ToString() write-host 'Body' $body = $msg.Body write-host $Body write-host 'After body' ## add the email stuff e.g. subject, bodys to a uber string tab delimited $output = $output + $strCreateTime+"`t"+$subject+"`t`n`r" Write-Host $output } $outlook.Quit() $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook)
输出结果
Body :
解决建议
- 检查邮件的HTML正文:很多邮件用HTML格式编写,此时
Body(纯文本正文)可能为空,但HTMLBody会有内容。修改代码同时读取两个属性,如需转纯文本可添加处理:$body = if ($msg.Body) { $msg.Body } else { $msg.HTMLBody } # 将HTML转为纯文本 $htmlDoc = New-Object -ComObject "HTMLFile" $htmlDoc.IHTMLDocument2_write($body) $plainBody = $htmlDoc.body.innerText write-host $plainBody - 清理残留的Outlook进程:未正确释放的Outlook COM对象可能导致读取异常,运行代码前先终止进程:
Get-Process outlook -ErrorAction SilentlyContinue | Stop-Process -Force Start-Sleep -Seconds 2 - 尝试使用Redemption库:Outlook原生COM对象受权限和格式限制较多,Redemption库(需提前安装)可更可靠读取.msg文件:
$rdosession = New-Object -ComObject Redemption.RDOSession $msg = $rdosession.GetMessageFromMsgFile('C:\Users\myfolder\Testemail.msg') write-host $msg.Body write-host $msg.HTMLBody $rdosession.Logoff() $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($rdosession) - 验证文件权限与完整性:确保当前用户对目标.msg文件有读取权限,手动用Outlook打开文件确认正文正常,排除文件损坏问题。
- 添加延迟加载属性:COM对象加载邮件内容可能存在延迟,创建
$msg后添加短暂延迟:$msg = $outlook.CreateItemFromTemplate($_.FullName) Start-Sleep -Milliseconds 500
内容的提问来源于stack exchange,提问作者fake fake
相关产品推荐
相关产品推荐

