PowerShell按枚举Properties属性分组获取用户最近登录时间
提取Windows安全日志中用户最新登录时间并分组
针对你需要从4624事件中按用户名分组、获取每个用户最后登录时间的需求,在PowerShell 7里可以通过转换自定义对象+分组筛选的方式轻松实现,具体步骤如下:
完整解决方案代码
# 设置时间范围:过去30天内的日志 $dateAfter = (Get-Date).AddDays(-30) $dateBefore = Get-Date # 获取目标安全日志事件(4624是登录成功事件) $winEvents = Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4624 StartTime = $dateAfter EndTime = $dateBefore } -ErrorAction SilentlyContinue # 将EventRecord对象转换为仅包含关键信息的自定义对象 $loginRecords = $winEvents | ForEach-Object { [PSCustomObject]@{ Username = $_.Properties[5].Value # 提取4624事件中的用户名属性 LastLogin = $_.TimeCreated } } # 按用户名分组,筛选每个用户的最新登录记录 $latestUserLogins = $loginRecords | Group-Object Username | ForEach-Object { # 对每组内的登录记录按时间倒序,取第一条就是最新的 $_.Group | Sort-Object LastLogin -Descending | Select-Object -First 1 } # 格式化输出结果 $latestUserLogins | Format-Table Username, LastLogin -AutoSize
关键步骤解释
转换自定义对象:
直接操作EventRecord的Properties集合确实不太顺手,所以我们用ForEach-Object把每个事件转换成包含Username和LastLogin的自定义对象,这样后续的分组、排序操作都会简单很多。分组与筛选最新记录:
先用Group-Object把记录按用户名分组,然后对每个组内的记录按登录时间降序排序,取第一条就是该用户的最新登录时间。
扩展:找出30天未登录的用户(用于清理配置文件)
如果你要清理无登录记录的用户配置文件,可以结合本地用户列表对比:
# 获取本地启用的普通用户(排除系统默认账号) $localEnabledUsers = Get-LocalUser | Where-Object { $_.Enabled -and $_.Name -notin @('Administrator', 'Guest', 'DefaultAccount') } # 找出30天内没有登录记录的用户 $usersToClean = $localEnabledUsers | Where-Object { $_.Name -notin $latestUserLogins.Username } # 输出待清理用户列表(建议先确认再执行删除) $usersToClean | Format-Table Name, Description -AutoSize # (可选)删除用户及配置文件,请务必先测试! # $usersToClean | ForEach-Object { # # 删除本地用户 # Remove-LocalUser -Name $_.Name -Confirm:$false # # 删除用户配置文件目录 # Remove-Item -Path "C:\Users\$($_.Name)" -Recurse -Force -ErrorAction SilentlyContinue # }
注意事项
- 确认Properties索引:不同Windows版本中,4624事件的
Properties索引可能有变化,你可以先运行$winEvents[0].Properties | Format-Table Value, Description,确认用户名对应的索引是否为5。 - 权限要求:必须以管理员身份运行PowerShell,否则无法读取安全日志和修改用户账号。
- 测试验证:执行删除操作前,一定要先核对
$usersToClean的输出,避免误删重要用户的配置文件。
内容的提问来源于stack exchange,提问作者tb1




