PowerShell导出Outlook本地PST联系人过慢问题及优化求助
问题
在Windows 10搭配Office 365环境下,我用PowerShell脚本导出本地PST文件中的Outlook联系人到.csv文件,脚本如下:
$Outlook = New-Object -comobject Outlook.Application $Contacts = $Outlook.session.GetDefaultFolder(10).items $count = $Contacts.Count $PSDefaultParameterValues['Out-File:Encoding'] = "utf8" $Contacts | Select * | Export-Csv -Encoding UTF8 -NoTypeInformation "$outfile"
导出约3100个联系人耗时15分钟,有没有办法大幅提速,或者其他导出方式?
更新:我尝试用Table对象(PowerShell环境,无筛选),但没拿到有效联系人数据,示例代码如下:
$Folder = $Outlook.session.GetDefaultFolder(10) $Table = $Folder.GetTable() while ( $row = $Table.GetNextRow() ) { $row }
只输出一堆无用内容:
Application Class Session Parent ----------- ----- ------- ------ Microsoft.Office.Interop.Outlook.ApplicationClass 121 System.__ComObject System.__ComObject Microsoft.Office.Interop.Outlook.ApplicationClass 121 System.__ComObject System.__ComObject ... etc.
解决方案
一、优化原脚本提速
原脚本慢的核心原因是Select *会加载联系人对象的所有属性,大量冗余属性会拖慢处理速度,而且COM对象的属性访问本身存在开销。只选择你需要的属性,能大幅压缩耗时:
$Outlook = New-Object -comobject Outlook.Application $ContactsFolder = $Outlook.Session.GetDefaultFolder(10) # 只指定需要导出的属性,比如姓名、邮箱、常用电话等 $requiredProps = @("FullName", "Email1Address", "BusinessTelephoneNumber", "MobileTelephoneNumber") $Contacts = $ContactsFolder.Items | Select-Object $requiredProps $outfile = "C:\Your\Target\Path\Contacts.csv" $Contacts | Export-Csv -Encoding UTF8 -NoTypeInformation -Path $outfile
- 仅加载必要属性,避免遍历冗余字段,能把处理时间压缩到数分钟甚至更短。
- 不要提前调用
$Contacts.Count,这个操作会强制Outlook预加载所有联系人对象,直接遍历Items集合反而更快。
二、正确使用GetTable获取数据
你之前用GetTable没拿到有效数据,是因为没指定要获取的属性,且需要通过Row.Item()方法读取具体字段值。GetTable是Outlook对象模型中效率最高的批量数据读取方式,适合大量联系人场景:
$Outlook = New-Object -comobject Outlook.Application $Folder = $Outlook.Session.GetDefaultFolder(10) # 指定要获取的属性对应的MAPI标签 $mapiProps = @( "http://schemas.microsoft.com/mapi/proptag/0x3001001E", # 显示名称 "http://schemas.microsoft.com/mapi/proptag/0x39FE001E", # 邮箱地址 "http://schemas.microsoft.com/mapi/proptag/0x00F9001E", # 商务电话 "http://schemas.microsoft.com/mapi/proptag/0x00FA001E" # 移动电话 ) $Table = $Folder.GetTable("", [Microsoft.Office.Interop.Outlook.OlTableContents]::olUserItems) # 清空默认列,添加需要的属性列 $Table.Columns.RemoveAll() foreach ($prop in $mapiProps) { $Table.Columns.Add($prop) } # 收集联系人数据 $contactsData = @() while ($Row = $Table.GetNextRow()) { $contactObj = [PSCustomObject]@{ FullName = $Row.Item($mapiProps[0]) Email1Address = $Row.Item($mapiProps[1]) BusinessTelephoneNumber = $Row.Item($mapiProps[2]) MobileTelephoneNumber = $Row.Item($mapiProps[3]) } $contactsData += $contactObj } $outfile = "C:\Your\Target\Path\Contacts.csv" $contactsData | Export-Csv -Encoding UTF8 -NoTypeInformation -Path $outfile
- GetTable直接从Outlook存储中读取数据,不需要加载完整的Contact对象,速度比遍历Items集合快数倍。
- 必须明确指定要获取的属性(用MAPI属性标签),否则默认返回的是对象元数据,而非联系人实际信息。
三、原生导出方式(无需脚本)
如果不想写代码,可以用Outlook自带的导出功能,原生实现效率同样很高:
- 打开Outlook,进入目标联系人文件夹
- 点击「文件」→「打开和导出」→「导入/导出」
- 选择「导出到文件」→「逗号分隔值」→ 选择要导出的联系人文件夹 → 指定保存路径
- 按照向导完成导出即可
内容的提问来源于stack exchange,提问作者mivk
相关产品推荐
相关产品推荐

