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

PowerShell脚本无法识别全部久未登录AD用户,求排查建议

排查AD清理脚本未识别全部离职用户的问题

我是MSP(托管服务提供商)员工,正在开发清理客户AD(活动目录)的脚本。很多客户不会主动告知员工离职信息,所以这个脚本用来保持AD整洁、消除安全隐患。当前测试版本脚本会把90天未登录的启用用户(排除管理员组)输出到文本文件,但现在发现无法识别所有应标记的用户——AD里确实存在已离职但仍启用的用户,求排查建议。

当前测试脚本

# Set the time threshold (in days) for inactive user accounts
$inactiveDays = 90

# Get the domain name from the environment variable
$domain = $env:USERDOMAIN

# Set the distinguished name (DN) of the Disabled Users OU
$disabledUsersOU = "OU=DisabledUsers,DC=$domain"  # Update this with actual OU path

# Get the current date and calculate the threshold date for inactive accounts
$thresholdDate = (Get-Date).AddDays(-$inactiveDays)

# Get inactive users based on the last logon date, excluding users in the Administrators group
$inactiveUsers = Get-ADUser -Filter {
    LastLogonDate -lt $thresholdDate -and
    Enabled -eq $true -and
    MemberOf -notlike "*CN=Administrators,*"
} -Properties LastLogonDate

# Path to text file
$filePath = "C:\testCleanup\inactives.txt"

# Check if the folder exists, create it if not
if (-not (Test-Path "C:\testCleanup" -PathType Container)) {
    New-Item -ItemType Directory -Path "C:\testCleanup"
}

# Prints DistinguishedName to file
foreach ($user in $inactiveUsers) {
    $user.DistinguishedName | Out-File -FilePath $filePath -Append
}

# Display a message indicating that the operation is complete
Write-Host "DistinguishedNames of inactive users (excluding Administrators) printed to $filePath"

排查建议

1. 修正LastLogonDate的局限性

LastLogonDate是AD跨DC复制后的属性,存在同步延迟,且无法反映用户在所有DC上的最新登录时间。如果用户在某台DC登录后未同步到脚本执行的DC,就会被漏判。建议遍历所有DC获取LastLogon属性(非复制属性,仅存储在用户登录的DC上),取最大值判断:

$inactiveDays = 90
$thresholdDate = (Get-Date).AddDays(-$inactiveDays)
$allDCs = Get-ADDomainController -Filter *
$inactiveUsers = @()
$adminGroup = Get-ADGroup "Administrators"

foreach ($dc in $allDCs) {
    # 获取当前DC上的启用用户,排除直接/间接属于管理员组的用户
    $usersOnDC = Get-ADUser -Filter { Enabled -eq $true } -Properties LastLogon, MemberOf -Server $dc.Name | Where-Object {
        -not (Get-ADPrincipalGroupMembership $_ | Where-Object { $_.DistinguishedName -eq $adminGroup.DistinguishedName })
    }
    foreach ($user in $usersOnDC) {
        if ($user.LastLogon -eq 0) {
            # 从未登录过的用户,直接判定为符合条件
            if (-not ($inactiveUsers | Where-Object { $_.SamAccountName -eq $user.SamAccountName })) {
                $inactiveUsers += $user
            }
        } else {
            $lastLogonTime = [DateTime]::FromFileTime($user.LastLogon)
            if ($lastLogonTime -lt $thresholdDate) {
                if (-not ($inactiveUsers | Where-Object { $_.SamAccountName -eq $user.SamAccountName })) {
                    $inactiveUsers += $user
                }
            }
        }
    }
}

2. 修复管理员组过滤的漏洞

原脚本的MemberOf -notlike "*CN=Administrators,*"仅能排除直接属于管理员组的用户,无法识别通过嵌套组加入管理员组的用户。改用Get-ADPrincipalGroupMembership检查用户的所有组(包括嵌套):

$adminGroup = Get-ADGroup "Administrators"
$inactiveUsers = Get-ADUser -Filter { LastLogonDate -lt $thresholdDate -and Enabled -eq $true } -Properties LastLogonDate | Where-Object {
    -not (Get-ADPrincipalGroupMembership $_ | Where-Object { $_.DistinguishedName -eq $adminGroup.DistinguishedName })
}

3. 补充其他判断维度

除了登录时间,可结合LastPasswordSet属性辅助判断——如果用户密码超过90天未修改且未登录,大概率是离职用户:

$inactiveUsers = Get-ADUser -Filter { 
    LastLogonDate -lt $thresholdDate -and 
    Enabled -eq $true -and
    LastPasswordSet -lt $thresholdDate
} -Properties LastLogonDate, LastPasswordSet | Where-Object {
    -not (Get-ADPrincipalGroupMembership $_ | Where-Object { $_.DistinguishedName -eq $adminGroup.DistinguishedName })
}

4. 验证脚本执行权限

确保运行脚本的账号拥有读取所有AD用户属性的权限,部分客户可能对特定OU设置了权限限制,导致脚本无法读取该OU下用户的登录属性。

5. 手动校验目标用户属性

找到一个已知的漏判用户,执行以下命令查看其属性,确认是否符合脚本过滤条件:

Get-ADUser <用户名> -Properties LastLogonDate, LastLogon, Enabled, MemberOf, LastPasswordSet

重点检查:

  • Enabled是否为True
  • LastLogonDate/LastLogon是否早于90天前
  • 是否属于管理员组(包括嵌套)

6. 检查域时间同步

确保域内所有DC的时间同步正常,时间偏差会导致thresholdDate计算不准确,进而误判用户的活跃状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:17:13