应优先使用lastlogondate筛选已启用且180天未登录的域用户,排除服务账户和内置账户后,按通知→禁用→验证→删除四步法安全清理,并导出报告、启用ad回收站、固化入职/离职流程。
在 windows server 中批量清理长期未登录的域用户,核心是识别“已启用但长时间无活动”的账号,并安全执行禁用或删除。不能只看密码是否过期,也不能直接删——得结合登录时间、启用状态、账户类型和业务归属综合判断。
关键筛选条件:用 LastLogonDate 还是 LastLogonTimestamp?
优先使用 LastLogonDate(推荐),它是 PowerShell 封装后的易读属性,自动处理时区与空值;LastLogonTimestamp 虽同步延迟(最多14天),适合大范围初筛,但需手动转时间且对空值敏感。两者都需配合 Enabled -eq $true,排除已被禁用的账户。
- 查过去180天内从未登录的启用用户:
Get-ADUser -Filter {Enabled -eq $true} -Properties LastLogonDate,PasswordLastSet,Department | Where-Object {$_.LastLogonDate -lt (Get-Date).AddDays(-180) -or $_.LastLogonDate -eq $null} - 排除常见服务账户(如 svc_、sql_、adm_ 开头)和内置账户:
| Where-Object {$_.SamAccountName -notmatch "^svc_|^sql_|^adm_|^krbtgt|^Administrator$"}
安全清理四步法:通知 → 禁用 → 验证 → 删除
不建议一步到位删除。标准流程是先禁用并观察周期(如30天),确认无业务影响后再清理。
-
导出待处理名单(含关键信息):包括姓名、登录名、部门、最后登录时间、密码最后设置时间、启用状态
| Select-Object Name,SamAccountName,Department,@{N='LastLogon';E={$_.LastLogonDate}},@{N='PwdLastSet';E={$_.PasswordLastSet}},Enabled | Export-Csv C:\Reports\StaleUsers_$(Get-Date -Format 'yyyyMMdd').csv -NoTypeInformation -Encoding UTF8 -
批量禁用(带日志):
| ForEach-Object { Disable-ADAccount -Identity $_.SamAccountName -WhatIf } # 先试运行<br>Disable-ADAccount -Identity $_.SamAccountName; Write-EventLog -LogName Application -Source "AD-Cleanup" -EntryType Information -EventId 1001 -Message "Disabled stale user: $($_.SamAccountName)" - 清理前再确认:检查是否被锁定、是否在关键组(如 Domain Admins)、是否有邮箱或 Azure AD 同步依赖
排除干扰项:哪些用户不能动?
直接过滤掉以下类型,避免误操作:
- 操作系统为 Windows Server 的计算机账户(非用户):
Get-ADComputer -Filter {OperatingSystem -like "*Server*"} -Property Name,OperatingSystem - OU 在 “Domain Controllers” 或 “Service Accounts” 下的用户
- 密码永不过期且近期有登录的高权限账号(需单独审计):
Get-ADUser -Filter {PasswordNeverExpires -eq $true -and Enabled -eq $true} -Properties LastLogonDate | Where-Object {$_.LastLogonDate -gt (Get-Date).AddDays(-90)} - UPN 后缀不是公司主域名的(如 @guest.contoso.com),可能是外部协作账号
后续动作建议
清理不是终点。建议每月自动运行一次扫描脚本,将结果邮件发送给IT负责人;对连续两次进入清单的账户,触发自动禁用;所有操作必须开启 AD 回收站功能,确保可还原。另外,把清理逻辑固化进入职/离职流程——新用户默认90天未登录自动禁用,比事后补救更可靠。











