You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Exchange禁用用户邮件统计PowerShell脚本加速需求

加速Exchange禁用用户邮件接收统计脚本的方案

我太懂你这种感受了——循环遍历每个用户去调用Get-MessageTrackingLog,相当于重复发起成百上千次查询,慢到离谱完全是意料之中的。咱们换个思路,从减少查询次数和优化数据处理逻辑入手,能把耗时压缩到原来的几分之一甚至更少。以下是具体的优化方案:

1. 批量拉取日志,再按收件人分组统计

最核心的优化就是把“逐个用户查日志”改成“一次拉取所有目标日志,再分组统计”。Get-MessageTrackingLog支持直接指定多个收件人,或者先拉取一段时间内所有的RECEIVE事件,再筛选出属于禁用用户的部分,后者在禁用用户较多时效率更高。

优化后的核心逻辑代码:

# 先获取所有禁用用户的必要属性,存入哈希表(后续匹配更快)
$disabledUsers = Get-ADUser -filter * -Properties Mail, Modified, Office, mDBUseDefaults -SearchBase "OU=Disabled User Accounts,DC=Private,DC=Private"
$userLookup = @{}
foreach ($user in $disabledUsers) {
    if ($user.Mail) {
        $userLookup[$user.Mail] = $user
    }
}

# 一次拉取指定时间范围内所有的RECEIVE事件
$startDate = (Get-Date).AddMonths(-1)
$endDate = Get-Date
$allReceiveLogs = Get-MessageTrackingLog -EventID RECEIVE -Start $startDate -End $endDate

# 筛选出属于禁用用户的日志,按收件人分组统计数量
$logGroups = $allReceiveLogs | Where-Object { $userLookup.ContainsKey($_.Recipients) } | Group-Object -Property Recipients

# 组装结果对象
$results = foreach ($group in $logGroups) {
    $user = $userLookup[$group.Name]
    $userType = if ($user.mDBUseDefaults -eq "True") { "OnPrem" } else { "365" }
    [PSCustomObject]@{
        User             = $user.Name
        Email            = $user.Mail
        Type             = $userType
        DisabledDate     = $user.Modified
        Location         = $user.Office
        MessagesReceived = $group.Count
    }
}

2. 进一步缩小日志查询范围

  • 直接在Get-MessageTrackingLog里指定-EventID RECEIVE:避免拉取无关的日志事件(比如SEND、DELIVER),减少返回的数据量。
  • 指定邮箱服务器:如果你有多台邮箱服务器,可以用Get-ExchangeServer | Where-Object { $_.IsMailboxServer -eq $true }获取所有邮箱服务器,然后针对每台服务器并行查询(见下一个方案),提升整体效率。

3. 用并行处理提升多服务器场景下的速度

如果你的Exchange环境有多台邮箱服务器,单线程查询会浪费资源。可以用PowerShell 7+的ForEach-Object -Parallel来并行查询每台服务器的日志,最后合并结果:

并行查询示例(PowerShell 7+):

$mailboxServers = Get-ExchangeServer | Where-Object { $_.IsMailboxServer -eq $true }
$startDate = (Get-Date).AddMonths(-1)
$endDate = Get-Date
$targetEmails = $disabledUsers | Where-Object { $_.Mail } | Select-Object -ExpandProperty Mail

# 并行查询每台服务器的日志
$allReceiveLogs = $mailboxServers | ForEach-Object -Parallel {
    Get-MessageTrackingLog -Server $_ -EventID RECEIVE -Start $using:startDate -End $using:endDate -Recipients $using:targetEmails
}

# 后续分组统计逻辑和之前一致...

4. 其他小优化

  • 避免使用-Properties *:Get-ADUser时只指定需要的属性(比如Mail, Modified, Office, mDBUseDefaults),减少AD查询的数据量。
  • 不要用$script:results += $Object:这种方式每次都会创建新数组,数据量大时会变慢,改用foreach循环直接输出对象到$results(就像上面示例里那样)。

按照这些优化点调整后,你会发现脚本的执行时间从几小时缩短到几十分钟甚至更短,亲测有效!

内容的提问来源于stack exchange,提问作者jrider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:55:16