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

PowerShell 7并行ForEach-Object循环中无法存储AD对象至变量的问题

解决PowerShell并行获取AD LastLogon时的"invalid enumeration context"错误

问题根源

这个错误的核心原因是:你通过$using:DCs传递的ADDomainController对象,其内部的AD连接上下文并非线程安全。在并行线程中复用这些对象时,会导致AD服务器返回枚举上下文无效的错误。另外,直接在并行循环中反复复用同一个DC对象查询,也容易触发这类连接上下文冲突。

修复方案

核心修改点

  • 不要传递ADDomainController对象,改为传递DC的名称字符串,让每个并行线程创建独立的AD连接上下文。
  • 优化查询逻辑,增加错误处理,避免单个DC查询失败中断整个用户的处理流程。

修改后的代码

$users = Get-ADUser -Filter "[filter]"
# 提取DC名称字符串,而非传递ADDomainController对象
$DCNames = (Get-ADDomainController -Filter * | Where-Object { $_.Site -in $using:sites }).Name

$users | ForEach-Object -ThrottleLimit 2 -Parallel {    
    $dcList = $using:DCNames
    $currentUser = $_

    # 遍历所有DC查询该用户的LastLogon
    $lastLogonRecords = foreach ($dcName in $dcList) {
        try {
            $lastLogonAD = Get-ADUser -Identity $currentUser -Properties LastLogon -Server $dcName -ErrorAction Stop | 
                          Select-Object -ExpandProperty LastLogon
            
            # 过滤掉未登录的记录(LastLogon值为0)
            if ($lastLogonAD -ne 0) {
                [PSCustomObject]@{
                    UserName   = $currentUser.SamAccountName
                    DC         = $dcName
                    LastLogon  = [datetime]::FromFileTimeUTC($lastLogonAD)
                }
            }
        }
        catch {
            Write-Warning "用户 $($currentUser.SamAccountName) 查询DC $dcName 失败: $_"
            continue
        }
    }

    # 输出该用户的最新LastLogon记录(因为LastLogon不跨DC同步,需取最大值)
    $lastLogonRecords | Sort-Object LastLogon -Descending | Select-Object -First 1
}

额外说明

  1. LastLogon属性特性:该属性是DC本地存储的,不会同步到其他域控制器,所以通常需要查询所有DC后取最大值作为用户的实际最后登录时间,代码中已包含此逻辑。
  2. ThrottleLimit调整:可以根据AD服务器的负载情况调整该值,避免过高的并行请求对AD造成压力。
  3. 错误处理:通过try/catch捕获单个DC的查询错误,确保其他DC的查询不受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:01:23