Powershell 正在处理 Outlook 对象,运行 内存不足
Powershell proccessing Outlook objects, running out of memory
我创建了一个脚本来删除大邮箱中的重复项。
这个邮箱有很多重复项,因为我们确实将邮件存档导入到这些邮箱中。
为此,我想使用组对象 cmdlet 来收集所有重复项,而不是在每个组中只保留 1 个。
但是 运行 这行在包含 50k 个项目的文件夹上(我有包含 120k 个项目的文件夹的邮箱),产生错误 - “内存不足,无法继续执行程序。”
我不必将整个脚本带到这里。
我只尝试了下面代码中的那些行,几分钟后我收到了错误。
详情:
命令:
$user = 'user@domain.suffix'
$outlook = New-Object -com Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$mailbox = $namespace.Stores | ? {$_.displayname -like $user}
$global:mailboxRoot = $mailbox.GetRootFolder()
$bb = $mailboxRoot.Folders[1].Items | Group-Object -Property senton, subject
机器内存:32GB
错误输出同时:outlook 内存大约 520-550 MB
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Shell
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String AllowRemoteShellAccess GPO true
System.String IdleTimeout 7200000
System.String MaxConcurrentUsers 2147483647
System.String MaxShellRunTime 2147483647
System.String MaxProcessesPerShell 2147483647
System.String MaxMemoryPerShellMB 2147483647
System.String MaxShellsPerUser 2147483647
您收到的错误是由 Outlook 而非 powershell 生成的。 Outlook 的内存限制取决于安装的版本(2013、O365、2007 等)以及它是 32 位还是 64 位。提高内存使用率的一些方法是:
您遇到的一个问题是您将整个邮件项目(包括正文)存储在内存中。尝试选择仅您需要的属性。
然后在查询完成后将它们分组,只保存有重复项的组
出于某种原因,获取项目并将它们分组为一个管道似乎导致 outlook 的内存使用量激增 - 也许它一直
东西打开时间太长?
完成该邮箱的任务后,可能值得在开始新搜索之前关闭 Outlook。
# configure outlook mailbox connection
$user = 'username@domain.com'
$outlook = New-Object -com Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$mailbox = $namespace.Stores | ? {$_.displayname -like $user}
$mailboxRoot = $mailbox.GetRootFolder()
$StoreID = $mailboxRoot.StoreID
# search for items, only keep properties you need
$items = $mailboxRoot.Folders.Items | select -First 1000 -Property senton,subject,MessageClass,EntryID
# group found items, only keep duplicates
$grouped = $items|group SentOn,subject|? count -gt 1
# get all "EnterpriseVault" shortcuts in each group
$duplicates = $grouped | foreach { $_.Group | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"} }
# find duplicate messages via ID search (much faster)
foreach ($duplicate in $duplicates) {
$toDelete = $namespace.GetItemFromID($email.EntryID, $inboxFolderID)
$toDelete.delete()
}
# Close outlook process
$outlook.Quit()
Get-Process outlook | Stop-Process
也就是说,这种事情应该真的在电子邮件server-side上完成,而不是通过缓慢的 outlook 和缓慢的 mapi 连接。
由于我的目标是删除这些邮件,我担心(如果我错了请纠正我)从 $inbox 中找到重复邮件不会删除真正的邮件,只会删除带有几个属性的精简副本在 $inbox.
在这种情况下,我将不得不找到真正的消息而不是精简副本,然后将其删除。
考虑到包含 10 万个项目的文件夹,查找每封重复的邮件可能需要几分钟,如下所示:
$duplicates = $folder.Items | ?{$_.senton -eq $x.SentOn} | ?{$_.subject -eq $x.Subject}
if (($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}) -ne $null) {
if (($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}).count -gt 1) {
($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"})[-1].delete()
} else {
($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}).delete()
}
} else {
$duplicates[-1].delete()
}
这是我当前的代码,我发现从每个邮箱中删除大约 10-20k 个重复项可能需要 2 周的时间。更多。
此外,没有办法增加 outlook 可用的内存 - 如果这是 运行 内存不足的程序?
我可以为此分配 25-28 GB 的内存。
我创建了一个脚本来删除大邮箱中的重复项。
这个邮箱有很多重复项,因为我们确实将邮件存档导入到这些邮箱中。
为此,我想使用组对象 cmdlet 来收集所有重复项,而不是在每个组中只保留 1 个。
但是 运行 这行在包含 50k 个项目的文件夹上(我有包含 120k 个项目的文件夹的邮箱),产生错误 - “内存不足,无法继续执行程序。”
我不必将整个脚本带到这里。 我只尝试了下面代码中的那些行,几分钟后我收到了错误。
详情:
命令:
$user = 'user@domain.suffix'
$outlook = New-Object -com Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$mailbox = $namespace.Stores | ? {$_.displayname -like $user}
$global:mailboxRoot = $mailbox.GetRootFolder()
$bb = $mailboxRoot.Folders[1].Items | Group-Object -Property senton, subject
机器内存:32GB
错误输出同时:outlook 内存大约 520-550 MB
WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Shell
Type Name SourceOfValue Value
---- ---- ------------- -----
System.String AllowRemoteShellAccess GPO true
System.String IdleTimeout 7200000
System.String MaxConcurrentUsers 2147483647
System.String MaxShellRunTime 2147483647
System.String MaxProcessesPerShell 2147483647
System.String MaxMemoryPerShellMB 2147483647
System.String MaxShellsPerUser 2147483647
您收到的错误是由 Outlook 而非 powershell 生成的。 Outlook 的内存限制取决于安装的版本(2013、O365、2007 等)以及它是 32 位还是 64 位。提高内存使用率的一些方法是:
您遇到的一个问题是您将整个邮件项目(包括正文)存储在内存中。尝试选择仅您需要的属性。
然后在查询完成后将它们分组,只保存有重复项的组
出于某种原因,获取项目并将它们分组为一个管道似乎导致 outlook 的内存使用量激增 - 也许它一直 东西打开时间太长?
完成该邮箱的任务后,可能值得在开始新搜索之前关闭 Outlook。
# configure outlook mailbox connection
$user = 'username@domain.com'
$outlook = New-Object -com Outlook.Application
$namespace = $outlook.GetNamespace("MAPI")
$mailbox = $namespace.Stores | ? {$_.displayname -like $user}
$mailboxRoot = $mailbox.GetRootFolder()
$StoreID = $mailboxRoot.StoreID
# search for items, only keep properties you need
$items = $mailboxRoot.Folders.Items | select -First 1000 -Property senton,subject,MessageClass,EntryID
# group found items, only keep duplicates
$grouped = $items|group SentOn,subject|? count -gt 1
# get all "EnterpriseVault" shortcuts in each group
$duplicates = $grouped | foreach { $_.Group | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"} }
# find duplicate messages via ID search (much faster)
foreach ($duplicate in $duplicates) {
$toDelete = $namespace.GetItemFromID($email.EntryID, $inboxFolderID)
$toDelete.delete()
}
# Close outlook process
$outlook.Quit()
Get-Process outlook | Stop-Process
也就是说,这种事情应该真的在电子邮件server-side上完成,而不是通过缓慢的 outlook 和缓慢的 mapi 连接。
由于我的目标是删除这些邮件,我担心(如果我错了请纠正我)从 $inbox 中找到重复邮件不会删除真正的邮件,只会删除带有几个属性的精简副本在 $inbox.
在这种情况下,我将不得不找到真正的消息而不是精简副本,然后将其删除。 考虑到包含 10 万个项目的文件夹,查找每封重复的邮件可能需要几分钟,如下所示:
$duplicates = $folder.Items | ?{$_.senton -eq $x.SentOn} | ?{$_.subject -eq $x.Subject}
if (($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}) -ne $null) {
if (($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}).count -gt 1) {
($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"})[-1].delete()
} else {
($duplicates | ?{$_.MessageClass -EQ "IPM.Note.EnterpriseVault.Shortcut"}).delete()
}
} else {
$duplicates[-1].delete()
}
这是我当前的代码,我发现从每个邮箱中删除大约 10-20k 个重复项可能需要 2 周的时间。更多。
此外,没有办法增加 outlook 可用的内存 - 如果这是 运行 内存不足的程序? 我可以为此分配 25-28 GB 的内存。