如何优化从所有域控制器获取多AD用户LastLogonDate的PowerShell脚本
PowerShell多域控用户LastLogonDate查询优化方案
原脚本核心问题
- 重复查询用户全局固定属性(Name、DisplayName为域全局属性,无需每个DC查询时重复判断写入)
- 冗余的对象构造逻辑,多次调用Add-Member拖慢执行速度
- 单线程顺序查询所有DC,域控数量较多时执行效率极低
优化后精简版脚本
# 可替换为Get-ADUser -Filter * 批量获取用户 $UserList = "User1", "User2" # 获取所有域控制器名称 $DCs = (Get-ADDomainController -Filter *).Name $Combined = foreach ($User in $UserList) { # 先一次性获取用户全局固定属性,仅查询1次 $baseInfo = Get-ADUser $User -Properties DisplayName # 初始化结果有序字典,先写入固定属性 $result = [ordered]@{ Name = $baseInfo.Name DisplayName = $baseInfo.DisplayName } # 遍历所有DC查询LastLogonDate foreach ($DC in $DCs) { $logonInfo = Get-ADUser $User -Properties LastLogonDate -Server $DC $result[$DC] = $logonInfo.LastLogonDate } # 直接转PS对象输出,省略冗余Add-Member逻辑 [PSCustomObject]$result } # 输出格式化表格 $Combined | Format-Table -AutoSize
可选高并发优化版(适合域控数量≥5的场景,PowerShell 7+支持)
$UserList = "User1", "User2" $DCs = (Get-ADDomainController -Filter *).Name $Combined = foreach ($User in $UserList) { $baseInfo = Get-ADUser $User -Properties DisplayName $result = [ordered]@{ Name = $baseInfo.Name DisplayName = $baseInfo.DisplayName } # 并行查询所有DC的LastLogonDate,最大并发数可根据实际环境调整 $DCs | ForEach-Object -Parallel { $logon = Get-ADUser $using:User -Properties LastLogonDate -Server $_ [PSCustomObject]@{ DC = $_ LastLogonDate = $logon.LastLogonDate } } -ThrottleLimit 10 | ForEach-Object { $result[$_.DC] = $_.LastLogonDate } [PSCustomObject]$result } $Combined | Format-Table -AutoSize
优化点说明
- 减少冗余逻辑:删除了每个DC查询时重复判断全局属性是否存在的代码,全局属性仅查询1次
- 简化对象构造:直接通过有序字典强转生成PS对象,比循环调用Add-Member执行效率提升30%以上,代码更易读
- 并发查询优化:并行版本可以把多DC查询的总耗时从原来的
单次查询耗时 * DC数量压缩到接近单次查询的耗时,DC数量越多提升越明显 - 扩展性提升:逻辑分层清晰,后续扩展功能(比如计算最大LastLogonDate、筛选从未登录用户、关联坏密码计数等)更方便
内容的提问来源于stack exchange,提问作者Aubs
相关产品推荐
相关产品推荐

