简介:这份资源面向需要了解电脑使用痕迹的普通用户与IT运维初学者,系统梳理了查看电脑使用记录的多种实用方法,涵盖开机记录、文档操作记录与上网记录三大方向。资源包内含1个doc文档,约30KB,以图文步骤形式呈现,便于按需查阅与对照操作。内容涉及通过计划任务日志、事件查看器、systeminfo命令查看开关机时间,借助Prefetch目录、Recent文件夹与History记录追溯程序运行和文件打开历史,以及通过Temporary Internet Files与IE历史记录还原上网轨迹。目前已有6308人学习下载,适合希望掌握电脑使用痕迹排查思路、提升日常维护与安全审计能力的读者参考,可作为快速上手的操作指南使用。
1. 电脑使用记录到底藏在哪:一次把 Windows 三条取证链路讲透
很多人第一次认真想查电脑使用记录,都是因为遇到了具体麻烦:家里共用机被人半夜开机、公司资产盘点发现某台机器有异常外联、或者自己想知道孩子放学后到底在电脑上干了什么。标题里的「如何查看电脑使用记录」,落到工程上其实不是一条命令的事,而是三条互相独立的取证链路:系统事件日志、文件系统痕迹、应用程序自留数据。三条链路各有各的时间戳格式、覆盖周期和权限门槛,只查一条经常会得出错误结论。
这篇文章面向三类人:需要做终端自查的普通用户、要写自动化采集脚本的运维、以及做数字取证入门的安全从业者。我会按「先搞清楚数据源在哪 → 再动手采集 → 最后讲清楚哪些坑会让你白忙一场」的顺序展开,所有命令都在本机可复现,不依赖任何第三方商业工具。读完你应该能自己判断:这台机器上到底还能捞出多少有效记录,以及哪些记录其实早就被系统自己清掉了。
2. 三条取证链路的数据源与选型逻辑
在动手敲命令之前,得先明白 Windows 把「使用痕迹」分散存放在哪几个地方。选错数据源,后面所有分析都是无用功。这一章先把三条链路的边界讲清楚,再给出各自的采集入口。
2.1 事件日志:最权威但覆盖周期最短的一条
Windows 事件日志由 Event Log 服务统一管理,存放在C:\Windows\System32\winevt\Logs\目录下,格式是.evtx。和「使用记录」最相关的是这几个通道:
| 日志通道 | 记录内容 | 默认单文件上限 | 典型覆盖周期 |
|---|---|---|---|
| Security | 登录/注销、特权使用、对象访问 | 20 MB | 数天到数周 |
| System | 开关机、服务启停、驱动加载 | 20 MB | 数周 |
| Application | 应用崩溃、安装行为 | 20 MB | 数周 |
| Microsoft-Windows-TaskScheduler/Operational | 计划任务触发 | 1 MB | 数天 |
关键点在于「默认单文件上限」这一列。Security 日志默认只留 20 MB,一台活跃机器一天就能写满,滚动覆盖非常快。所以事件日志适合回答「最近几天发生了什么」,不适合回答「上个月谁用过」。
采集入口有两个:图形化的eventvwr.msc,以及命令行的wevtutil。做批量分析时我一般直接用后者导出,再用脚本解析。
# 导出 Security 日志为 evtx,便于离线分析 wevtutil epl Security D:\case\Security.evtx # 按事件 ID 过滤登录成功(4624)和登录失败(4625),输出为文本 wevtutil qe Security /q:"*[System[(EventID=4624 or EventID=4625)]]" /f:text /c:50 > D:\case\logon.txtepl是 export-log 的缩写,把整个通道原样导出,保留二进制结构,适合后续用解析库处理。qe是 query-events,/q:后面跟 XPath 过滤表达式,/c:50限制返回最近 50 条,/f:text输出可读文本。注意/q:里的 XPath 必须严格符合事件日志的 schema,写错一个括号就返回空结果,而且不报错——这是新手最容易翻车的地方。
2.2 文件系统痕迹:覆盖周期最长但最容易被忽略
事件日志会被滚动覆盖,但文件系统上的痕迹往往能留几个月甚至更久。几个高价值位置:
C:\Users\<用户名>\AppData\Roaming\Microsoft\Windows\Recent\:快捷方式文件,记录最近打开过的文档,每个.lnk的修改时间就是访问时间。C:\Windows\Prefetch\:预读取文件,.pf后缀,记录程序首次和最近运行时间、运行次数。这是判断「某个 exe 有没有被执行过」的黄金证据。C:\Users\<用户名>\NTUSER.DAT:注册表用户配置单元,里面的UserAssist键用 ROT13 编码记录了 GUI 程序的启动次数和最后执行时间。$MFT:NTFS 主文件表,记录每个文件的创建、修改、访问时间(MACB 四个时间戳)。
Prefetch 值得单独说。它默认在 SSD 系统上也是开启的(除非是服务器版或手动关了 SysMain 服务),文件名格式是程序名-哈希.pf,哈希是执行路径的校验值。用下面这段 PowerShell 可以把 Prefetch 目录按最后写入时间排序,快速看出最近跑过什么:
# 列出 Prefetch 目录,按最后写入时间倒序,取前 30 条 Get-ChildItem "C:\Windows\Prefetch\*.pf" | Sort-Object LastWriteTime -Descending | Select-Object -First 30 Name, LastWriteTime, Length | Format-Table -AutoSizeLastWriteTime近似等于程序最后一次启动时间,Length是预读取文件大小,异常小的文件可能对应很少运行的程序。这里有个细节:Prefetch 默认最多保留 128 个文件,超过后按 LRU 淘汰,所以它也不是无限的。
2.3 应用程序自留数据:浏览器、办公软件、即时通讯
第三类数据不在系统统一管理下,而是各应用自己写。浏览器是最典型的:Chrome/Edge 的History文件是 SQLite 数据库,路径在C:\Users\<用户名>\AppData\Local\...\User Data\Default\History。直接复制这个文件(因为运行时被锁)后用 SQLite 打开,就能查到访问过的 URL 和访问次数。
-- 查询最近 100 条浏览记录,按最后访问时间倒序 SELECT url, title, visit_count, datetime(last_visit_time / 1000000 - 11644473600, 'unixepoch', 'localtime') AS last_visit FROM urls ORDER BY last_visit_time DESC LIMIT 100;这里last_visit_time是 Windows FILETIME 格式,单位是 100 纳秒,起点是 1601-01-01。所以要除以 1000000 转成秒,再减去 11644473600(1601 到 1970 的秒数差),才能用unixepoch转换。这个换算写错,时间就会差出几百年,是浏览器取证里最常见的低级错误。
三条链路对比下来,选型逻辑很清楚:要精确的登录/权限事件,走事件日志;要判断程序是否运行过、文档是否打开过,走文件系统痕迹;要知道具体访问了什么网页、聊了什么,走应用自留数据。三者时间戳格式不统一,交叉验证时务必先统一到同一时区再比对。
3. 从零采集一份可复现的使用记录报告
上一章讲清了数据源,这一章把采集流程串成一条可执行的流水线。目标是在一台 Windows 机器上,不装任何第三方工具,产出一份包含登录记录、程序运行记录、浏览记录的结构化报告。
3.1 用 PowerShell 统一采集入口
手工一条条敲命令容易漏,我一般写一个采集脚本,把所有输出落到同一个目录,方便后续打包。下面这段脚本做了四件事:建目录、导事件日志、抓 Prefetch 清单、复制浏览器 History。
# 采集脚本:collect_usage.ps1 $out = "D:\case_$(Get-Date -Format yyyyMMdd_HHmmss)" New-Item -ItemType Directory -Path $out | Out-Null # 1. 导出安全日志中的登录事件 wevtutil qe Security /q:"*[System[(EventID=4624)]]" /f:text /c:200 > "$out\logon.txt" # 2. 抓取 Prefetch 清单 Get-ChildItem "C:\Windows\Prefetch\*.pf" | Select-Object Name, LastWriteTime, Length | Export-Csv "$out\prefetch.csv" -NoTypeInformation -Encoding UTF8 # 3. 复制浏览器 History(先复制再读,避免文件锁) $hist = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default\History" if (Test-Path $hist) { Copy-Item $hist "$out\edge_history.db" -Force } Write-Host "采集完成,输出目录:$out"脚本里$env:LOCALAPPDATA会自动展开到当前用户的 Local 目录,避免硬编码用户名。Copy-Item那一步是关键:浏览器运行时History文件被独占锁定,直接读会报错,必须先复制一份副本再分析。Export-Csv加-Encoding UTF8是为了避免中文程序名乱码,Windows PowerShell 5.1 默认编码是 ANSI,不加这个参数导出的 CSV 在别的机器上打开就是乱码。
3.2 解析事件日志里的登录类型
导出的logon.txt是纯文本,但 4624 事件里有个关键字段叫「登录类型」(Logon Type),不同数值含义完全不同,不区分就会把系统服务登录误判成真人登录。
| Logon Type | 含义 | 是否代表真人操作 |
|---|---|---|
| 2 | 交互式登录(本地键盘) | 是 |
| 3 | 网络登录(共享访问) | 否 |
| 4 | 批处理登录(计划任务) | 否 |
| 5 | 服务登录 | 否 |
| 10 | 远程交互登录 | 是(远程) |
| 11 | 缓存凭据登录 | 是(离线) |
只看 Type 2 和 Type 10,才能对应到「有人真的坐在这台机器前或远程连进来」。Type 3 和 5 是系统自己产生的,数量巨大且没有取证价值。用下面这段 Python 可以从导出的文本里筛出有效登录:
import re # 从 wevtutil 文本输出中提取登录类型为 2 或 10 的记录 pattern = re.compile(r"登录类型:\s+(\d+)") valid = {"2", "10"} with open("logon.txt", encoding="utf-16") as f: for line in f: m = pattern.search(line) if m and m.group(1) in valid: print(line.strip())注意wevtutil /f:text导出的文件默认是 UTF-16 编码,Python 打开时必须指定encoding="utf-16",否则读出来全是乱码或者直接抛异常。这个编码坑我在不同机器上踩过至少三次,每次都要愣一下才想起来。
3.3 把三类记录对齐到同一时间轴
采集完只是原料,真正有价值的是把登录时间、程序启动时间、网页访问时间放到同一条时间轴上,看它们是否互相印证。比如登录记录显示 14:03 有人本地登录,Prefetch 显示 14:05 浏览器启动,History 显示 14:06 访问了某站点——三条独立链路指向同一行为,可信度就很高。
对齐时统一用本地时间,并且注意事件日志的时间是 UTC 存储、显示时按系统时区转换,而 Prefetch 的LastWriteTime直接就是本地时间。如果机器时区被改过,两者会对不上,这时候要以事件日志里的SystemTime字段为准去反推真实时区偏移。
4. 避坑与排查:五个让取证结果失真的常见问题
这一章是我这些年踩过的坑里挑出来的五条,每条都按「现象 → 原因 → 解决」写,遇到对不上的情况可以逐条排查。
4.1 查不到任何登录记录,Security 日志几乎是空的
现象:wevtutil qe Security返回条数极少,或者只有最近一两条。原因是 Security 日志默认上限 20 MB,机器活跃时几小时就滚动覆盖,加上很多家用系统根本没开审核策略,4624 事件压根不记录。解决办法是先确认审核策略:auditpol /get /category:*查看「登录/注销」是否设为「成功」。如果没开,只能靠 Prefetch 和浏览器 History 反推,事件日志这条路走不通。
4.2 Prefetch 目录整个是空的
现象:C:\Windows\Prefetch\下没有任何.pf文件。原因通常是三种:系统装在 SSD 上且被优化工具关了 SysMain 服务;系统是 Windows Server 版本(默认关闭);或者被人手动清理过。解决:先Get-Service SysMain看服务状态,如果是停止的,说明 Prefetch 功能被禁用,此时改用UserAssist注册表键作为替代数据源。
4.3 浏览器 History 复制出来打不开
现象:Copy-Item成功,但用 SQLite 打开报「database disk image is malformed」。原因是复制时浏览器正在写入,副本处于不一致状态。解决:复制前先关闭浏览器,或者用支持热备份的方式读取(比如先复制History和同目录的History-journal两个文件)。如果已经拿到损坏副本,可以用sqlite3 recovered.db ".recover"尝试恢复。
4.4 时间戳全部偏移了 8 小时
现象:解析出来的时间和实际发生时间差整整一个时区。原因是把 UTC 时间当成本地时间直接输出了。事件日志的SystemTime是 UTC,浏览器 FILETIME 换算后默认也是 UTC。解决:在转换时显式加时区,SQL 里用'localtime'修饰符,Python 里用datetime.fromtimestamp(ts)而不是utcfromtimestamp。
4.5 用普通权限跑脚本,一半数据读不到
现象:脚本能跑,但 Security 日志导出为空,或者 Prefetch 目录访问被拒。原因是这些位置需要管理员权限。解决:以管理员身份运行 PowerShell,或者用Start-Process powershell -Verb RunAs提权。注意提权后$env:LOCALAPPDATA会变成管理员账户的路径,如果要采集普通用户的数据,得手动指定用户目录,不能依赖环境变量。
5. 把采集做成可复用脚本的几个进阶技巧
前面四章走完,你已经能手工捞出一份记录了。但如果要定期采集、或者要在多台机器上批量做,手工流程撑不住。这一章讲三个我实际在用的进阶做法,都是围绕「让结果可复现、可对比」这个目标。
第一个技巧是把采集脚本参数化。不要硬编码输出目录和用户名,改成从命令行接收参数,这样同一份脚本能跑在不同机器上。下面这个写法把输出根目录和要采集的用户名都做成参数:
param( [string]$OutRoot = "D:\case", [string]$TargetUser = $env:USERNAME ) $stamp = Get-Date -Format yyyyMMdd_HHmmss $out = Join-Path $OutRoot "$TargetUser`_$stamp" New-Item -ItemType Directory -Path $out -Force | Out-Null # 采集指定用户的 Recent 快捷方式 $recent = "C:\Users\$TargetUser\AppData\Roaming\Microsoft\Windows\Recent" if (Test-Path $recent) { Get-ChildItem $recent -Filter *.lnk | Select-Object Name, LastWriteTime | Export-Csv (Join-Path $out "recent.csv") -NoTypeInformation -Encoding UTF8 }param块让脚本可以.\collect.ps1 -TargetUser someone这样调用,Join-Path比字符串拼接更安全,能自动处理路径分隔符。-Force保证目录已存在时不报错。
第二个技巧是给采集结果算哈希。取证场景里,证明「这份数据没被改过」和「数据本身」一样重要。采集完对整个输出目录算一次 SHA256,把哈希值单独存一份:
Get-ChildItem $out -Recurse -File | Get-FileHash -Algorithm SHA256 | Export-Csv (Join-Path $out "hashes.csv") -NoTypeInformationGet-FileHash默认就是 SHA256,-Recurse保证子目录也覆盖。之后任何时候重新算一遍对比,就能确认文件有没有被动过。
第三个技巧是建立基线对比。单次采集只能看到「现在有什么」,看不出「多了什么」。我一般会在机器状态正常时先采一次作为基线,之后每次采集都和基线做差集,重点关注新增的 Prefetch 文件和新增的登录事件。差集用 PowerShell 的Compare-Object就能做:
$base = Import-Csv "D:\case\baseline\prefetch.csv" $now = Import-Csv "D:\case\latest\prefetch.csv" Compare-Object $base $now -Property Name | Where-Object SideIndicator -eq "=>" | Select-Object NameSideIndicator为=>表示只在$now里出现,也就是新增项。这个思路在排查「机器最近有没有被人装过新软件」时特别管用,比一条条肉眼比对快得多。
最后说一个我自己的习惯:每次采集完,我会在输出目录里放一个README.txt,写清楚采集时间、机器名、采集人、用了哪个脚本版本。听起来很土,但真到了需要拿这份数据去跟别人对质的时候,没有这份元信息,数据的可信度会大打折扣。取证这件事,记录「怎么采的」和记录「采到了什么」同样重要。希望帮到你。
本文还有配套的精品资源,点击获取