如何用PowerShell从批量.msg文件中提取收件人邮箱地址?
解决PowerShell提取.msg文件收件人邮箱地址的问题
看起来你已经走对了路子,只是没挖到Recipient COM对象里的具体属性而已!直接输出$msg.Recipients或者单个Recipient对象时,PowerShell会显示System._ComObject,这是因为它不知道你要访问这个COM对象的哪个具体属性。
问题根源
Outlook的Recipient对象是一个COM封装的实体,你需要明确访问它的Address属性,或者针对Exchange邮箱的特殊情况获取SMTP地址——因为有些内部收件人的Address会显示为EX类型的内部标识,不是真实邮箱。
修正后的完整代码
# 初始化Outlook COM对象 $outlook = New-Object -ComObject Outlook.Application $namespace = $outlook.GetNameSpace("MAPI") # 定义.msg文件路径(替换成你的实际路径) $msgPath = "C:\Your\Msg\Files\Path" # 收集结果的数组 $recipientList = @() # 遍历所有.msg文件 Get-ChildItem $msgPath -Filter *.msg | ForEach-Object { $msg = $outlook.Session.OpenSharedItem($_.FullName) # 遍历当前邮件的所有收件人 foreach ($recipient in $msg.Recipients) { # 获取收件人姓名 $recipientName = $recipient.Name # 获取收件人邮箱地址(处理两种情况:普通SMTP和Exchange内部地址) if ($recipient.AddressEntry.AddressUserType -eq 0) { # olExchangeUserAddressEntry = 0 $recipientEmail = $recipient.AddressEntry.GetExchangeUser().PrimarySmtpAddress } else { $recipientEmail = $recipient.Address } # 将结果添加到数组 $recipientList += [PSCustomObject]@{ FileName = $_.Name RecipientName = $recipientName RecipientEmail = $recipientEmail RecipientType = switch ($recipient.Type) { 1 { "收件人" } 2 { "抄送" } 3 { "密送" } default { "未知" } } } } # 释放当前邮件的COM对象,避免内存泄漏 [System.Runtime.Interopservices.Marshal]::ReleaseComObject($msg) | Out-Null } # 输出结果(也可以导出为CSV:$recipientList | Export-Csv -Path "收件人列表.csv" -Encoding UTF8 -NoTypeInformation) $recipientList # 清理Outlook COM对象,关闭Outlook进程 $outlook.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers()
关键说明
- 访问具体属性:通过
$recipient.Name和$recipient.Address直接获取基础信息;针对Exchange环境,用AddressEntry.GetExchangeUser().PrimarySmtpAddress拿到真实的SMTP邮箱,避免显示内部EX标识。 - 区分收件人类型:通过
$recipient.Type可以判断是收件人、抄送还是密送,让结果更清晰。 - 清理COM对象:必须手动释放Outlook相关的COM对象,否则Outlook进程会一直留在后台占用资源。
如果还有问题,比如某些特殊邮箱(如邮件组)无法正确获取,可以再针对AddressUserType的其他值做扩展处理~
内容的提问来源于stack exchange,提问作者alnmod
相关产品推荐
相关产品推荐

