
简介这份文档面向需要了解电脑使用痕迹的普通用户与办公人员系统梳理了查看电脑使用记录的常见途径涵盖开机记录、文档操作记录与上网记录三大方向适合希望掌握基础排查与日常管理技能的学习者。资源包内含1个doc文件约30KB以图文步骤形式组织内容便于按需查阅与对照操作。文档从计划任务日志、事件查看器、系统命令等角度说明如何获取开关机时间并介绍通过Prefetch目录、Recent文件夹及History记录追踪程序运行与文件打开历史同时给出查看浏览器历史与临时文件的方法。目前已有6304人学习下载内容偏重实操指引可帮助读者快速定位所需记录位置理解各类日志与缓存文件的用途为电脑使用情况核查与日常维护提供参考。1. 从一次取证需求说起电脑使用记录到底能查到什么朋友的公司最近遇到一桩麻烦事一台公用办公电脑在非工作时间被用来处理过一批敏感文件但没人承认。他第一反应是“能不能查电脑使用记录”第二反应是“是不是得找专业取证公司”。我告诉他Windows 本身就留下了大量可追溯的痕迹只要没被刻意清理普通工程师靠系统自带工具就能还原出相当完整的使用画像。“如何查看电脑使用记录”这件事本质上不是装一个监控软件那么简单而是理解操作系统在哪些位置、以什么格式、保留多久地记录用户行为。它涵盖的范围比大多数人想象的广程序启动记录、文件访问痕迹、USB 设备插拔历史、网络连接日志、开关机时间线、浏览器行为、最近打开的文档列表。不同需求对应的取证深度完全不同——HR 想确认员工是否在工作时间摸鱼和法务想固定一份可提交的证据走的路子差别很大。这篇文章面向三类人需要做内部合规排查的 IT 运维、遇到纠纷想自行取证的普通用户、以及想搞清楚自己电脑到底泄露了多少行为信息的隐私关注者。我会按“先搞清楚记录存在哪 → 再用工具读出来 → 最后避开取证翻车点”的顺序讲每个命令都能直接复制执行。2. Windows 使用记录的六大藏身之处从注册表到事件日志2.1 注册表中的程序与文件访问痕迹Windows 注册表是使用记录最密集的存储区没有之一。以下几个键值几乎在所有版本的系统里都存在且默认不会被自动清理注册表路径记录内容保留特征NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU运行对话框输入历史最多保留最近若干条NTUSER.DAT\...\Explorer\RecentDocs最近打开的文档按扩展名分子键NTUSER.DAT\...\Explorer\ComDlg32\OpenSavePidlMRU打开/保存对话框路径按扩展名分组SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall已安装程序列表含安装时间SYSTEM\...\Enum\USBSTORUSB 存储设备插拔记录含设备序列号用 PowerShell 可以直接读取这些键值不需要装任何第三方工具# 读取 RunMRUWinR 运行对话框的输入历史 $runMRU HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU if (Test-Path $runMRU) { Get-ItemProperty -Path $runMRU | Select-Object -Property * -ExcludeProperty PS* } # 读取 RecentDocs最近打开的文档按扩展名遍历子键 $recentBase HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs Get-ChildItem -Path $recentBase -ErrorAction SilentlyContinue | ForEach-Object { $key $_.PSPath $props Get-ItemProperty -Path $key -ErrorAction SilentlyContinue $props.PSObject.Properties | Where-Object { $_.Name -match ^\d$ } | ForEach-Object { # 值是二进制需要转成可读字符串 $bytes $_.Value $text [System.Text.Encoding]::Unicode.GetString($bytes) -replace \0, [PSCustomObject]{ 扩展名键$_.Name; 文件名$text } } }第一段代码读取RunMRU输出的是用户在“运行”对话框里敲过的命令比如cmd、regedit、某个共享路径。第二段遍历RecentDocs下的扩展名子键把二进制值转成 Unicode 字符串——这里有个坑直接Get-ItemProperty看到的是System.Byte[]必须手动解码才能看到文件名。参数说明-ExcludeProperty PS*是为了过滤掉 PowerShell 自动添加的PSPath、PSParentPath等属性让输出干净。-replace \0,是去掉 Unicode 解码后残留的空字符否则文件名中间会夹一堆不可见字符。2.2 事件日志开关机、程序启动与审计记录事件查看器是第二个核心数据源。和注册表不同事件日志有明确的时间戳和事件 ID取证价值更高。几个关键日志通道System 日志事件 ID 6005事件日志服务启动约等于开机、6006服务停止约等于关机、41非正常关机。Security 日志如果开启了审核策略4624 是登录成功、4634 是注销、4688 是进程创建。注意 4688 默认不开启需要先在组策略里启用“审核进程创建”。Application 日志部分应用程序会在这里写入启动和错误信息。用wevtutil或 PowerShell 都可以查询# 查询最近 7 天的开关机记录System 日志事件 ID 6005/6006 $start (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable { LogNameSystem ID6005,6006,41 StartTime$start } | Select-Object TimeCreated, Id, {N含义;E{ switch ($_.Id) { 6005 {开机} 6006 {关机} 41 {异常断电/崩溃} } }} | Sort-Object TimeCreated -Descending # 如果启用了进程审核查询 4688 进程创建事件 Get-WinEvent -FilterHashtable { LogNameSecurity ID4688 StartTime$start } -MaxEvents 50 -ErrorAction SilentlyContinue | Select-Object TimeCreated, {N进程;E{$_.Properties[5].Value}}第一段用哈希表过滤比Where-Object快得多尤其在日志量大的机器上。switch语句把事件 ID 翻译成可读含义省得每次查表。第二段查 4688Properties[5]对应新进程名称字段——这个索引在不同 Windows 版本上可能略有差异如果取出来是空值用$_.Properties | Format-List先看一眼实际结构。注意4688 事件默认不记录命令行参数。如果需要完整命令行得在组策略里额外开启“在进程创建事件中包含命令行”选项否则只能看到进程名。2.3 文件系统痕迹Prefetch、Amcache 与 Jump List注册表和事件日志之外文件系统里还散落着几类高价值痕迹Prefetch预读取位于C:\Windows\Prefetch\每个可执行文件对应一个.pf文件记录该程序的运行次数和最近运行时间。文件名格式是程序名-哈希.pf。直接看文件属性里的“修改时间”就能大致判断最近运行时间但更精确的信息需要解析.pf二进制格式。Amcache位于C:\Windows\AppCompat\Programs\Amcache.hve记录曾经运行过的程序路径、首次运行时间、文件哈希。这是一个注册表 hive 文件需要用reg load挂载后读取。Jump List跳转列表位于%APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations\记录任务栏右键菜单里的最近文件。文件名是 AppID 加后缀需要对照 AppID 表才能知道对应哪个程序。# 查看 Prefetch 目录下最近运行的程序按修改时间排序 Get-ChildItem C:\Windows\Prefetch\*.pf -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 20 Name, LastWriteTime, Length # 挂载 Amcache.hve 并读取程序执行记录 reg load HKLM\AmcacheTemp C:\Windows\AppCompat\Programs\Amcache.hve Get-ChildItem HKLM:\AmcacheTemp\Root\InventoryApplicationFile -ErrorAction SilentlyContinue | ForEach-Object { $p Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue [PSCustomObject]{ 程序名 $p.Name 路径 $p.LowerCaseLongPath 首次运行 [DateTime]::FromFileTime($p.LinkDate) } } | Sort-Object 首次运行 -Descending | Select-Object -First 30 reg unload HKLM\AmcacheTempPrefetch 那段代码直接按修改时间排序取前 20 条适合快速扫一眼最近跑了什么。Amcache 那段先reg load把 hive 挂到临时路径读完再reg unload卸载——这一步必须做否则 hive 文件会被锁定下次系统更新可能报错。LinkDate是 FILETIME 格式用FromFileTime转成可读时间。提示Prefetch 只在系统盘启用了预读取的情况下才有文件。SSD 机器上部分系统会默认关闭 Prefetch此时这条路走不通得转向 Amcache 或事件日志。3. 用自带工具与开源脚本把记录读出来三条可复现路径3.1 路径一纯手工排查适合快速确认如果只是想知道“这台电脑最近有没有被用来干不该干的事”不需要上重型工具。按以下顺序过一遍十分钟内能有个大致判断打开事件查看器eventvwr.msc查 System 日志的 6005/6006确认非工作时间的开关机记录。查 Security 日志的 4624看有没有非工作时间登录注意登录类型类型 2 是本地登录类型 10 是远程桌面。打开C:\Windows\Prefetch按修改时间排序看非工作时间段有没有程序运行。检查C:\Users\用户名\Recent目录看最近打开的文档快捷方式。查注册表USBSTOR看有没有未经授权的 USB 设备接入。这套流程的优点是零依赖、不写盘、不触发任何告警。缺点是效率低且只能看个大概拿不到精确的时间线关联。3.2 路径二PowerShell 脚本批量导出时间线手工排查适合单次快速确认但如果要出一份完整报告得把多个数据源合并成统一时间线。下面这个脚本把开关机、程序运行、USB 插拔三类事件合并输出# 生成统一时间线开关机 Prefetch 程序运行 USB 插拔 $timeline () # 1. 开关机事件 $timeline Get-WinEvent -FilterHashtable {LogNameSystem; ID6005,6006} -MaxEvents 100 -ErrorAction SilentlyContinue | ForEach-Object { [PSCustomObject]{ 时间 $_.TimeCreated 类型 if ($_.Id -eq 6005) {开机} else {关机} 详情 $_.ProviderName } } # 2. Prefetch 程序运行用文件修改时间近似 $timeline Get-ChildItem C:\Windows\Prefetch\*.pf -ErrorAction SilentlyContinue | ForEach-Object { [PSCustomObject]{ 时间 $_.LastWriteTime 类型 程序运行 详情 $_.BaseName -replace -[A-F0-9]$, } } # 3. USB 存储设备插拔从注册表读取 $usbKey HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR Get-ChildItem $usbKey -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -match Properties$ } | ForEach-Object { $props Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue if ($props.(default)) { [PSCustomObject]{ 时间 $null # USBSTOR 不直接存时间需结合 setupapi.dev.log 类型 USB接入 详情 $props.(default) } } } # 按时间排序输出 $timeline | Where-Object { $_.时间 } | Sort-Object 时间 -Descending | Format-Table -AutoSize脚本的核心思路是“先收集、后合并、再排序”。三个数据源各自输出PSCustomObject字段统一为时间、类型、详情最后用Sort-Object排成一条时间线。Prefetch 的程序名用正则-[A-F0-9]$去掉哈希后缀还原成可读的程序名。USB 那段的时间字段留了$null因为USBSTOR注册表键本身不存插拔时间。要拿精确时间得去解析C:\Windows\INF\setupapi.dev.log里面按时间戳记录了设备安装过程。这个日志文件很大建议用Select-String过滤# 在 setupapi.dev.log 中搜索 USB 设备安装记录 findstr /I /C:USBSTOR C:\Windows\INF\setupapi.dev.log | findstr /I /C:Device Install3.3 路径三开源取证工具的选择与边界手工和脚本能覆盖大部分日常需求但如果要做正式取证还是得用专门工具。常见的几类Eric Zimmerman 工具集包括PECmd解析 Prefetch、AmcacheParser、JLECmd解析 Jump List、MFTECmd解析 MFT。命令行工具输出 CSV适合批量处理。Autopsy / Sleuth Kit完整的取证平台支持磁盘镜像分析、文件恢复、时间线可视化。适合做法务级取证。KAPE自动化取证收集工具可以按预设规则把目标机器上的关键痕迹打包导出适合批量排查多台机器。这些工具的边界在于它们读取的是“当前存在的痕迹”如果记录已被清理比如 Prefetch 被删、事件日志被覆盖工具也无力回天。所以取证的第一原则是“先固定、后分析”——拿到机器后第一时间做磁盘镜像或至少导出关键日志不要在原始机器上反复操作。4. 查看使用记录时最容易翻车的五个坑4.1 时间戳对不上时区与 FILETIME 转换错误现象脚本输出的时间和事件查看器里看到的时间差了几个小时。原因Get-WinEvent返回的TimeCreated是本地时间但注册表里的 FILETIME 是 UTC 时间。如果直接混用时间线就乱了。另外[DateTime]::FromFileTime()返回的是本地时间而FromFileTimeUtc()返回 UTC用错方法也会偏。解决统一转成 UTC 再比较或者统一转成本地时间。在脚本开头加一句$tz [System.TimeZoneInfo]::Local所有时间字段都过一遍[System.TimeZoneInfo]::ConvertTime($utcTime, $tz)。4.2 权限不够Security 日志读不出来现象查询 Security 日志时报“拒绝访问”或返回空结果。原因Security 日志默认只有 SYSTEM 账户有读权限普通管理员账户也读不了。必须用管理员权限运行 PowerShell且部分系统还需要手动获取日志文件的所有权。解决以管理员身份运行终端。如果仍然不行检查“本地安全策略 → 本地策略 → 审核策略”里是否开启了对应审核项。没开启审核日志里根本不会有记录权限再高也查不到。4.3 Prefetch 被关闭或清理现象C:\Windows\Prefetch目录为空或者只有零星几个文件。原因SSD 系统上部分优化工具会关闭 Prefetch或者有人手动清理过该目录。另外Windows Server 版本默认关闭 Prefetch。解决转向 Amcache 和事件日志。Amcache 记录的是程序首次运行时间虽然不如 Prefetch 精确但胜在不容易被清理。事件日志里的 4688如果开启了审核也能补上程序启动记录。4.4 注册表 RecentDocs 显示乱码现象用 PowerShell 读RecentDocs时文件名显示为一堆方块或问号。原因RecentDocs的值是二进制格式前几个字节是文件名的 Unicode 编码后面还跟着 PIDL项目标识符列表数据。直接Get-ItemProperty看到的是System.Byte[]不做解码就是乱码。解决用[System.Text.Encoding]::Unicode.GetString($bytes)解码然后用-replace \0,去掉空字符。如果文件名仍然不完整说明后面跟着 PIDL 数据需要截断到第一个\0\0之前。4.5 在原始机器上反复操作导致痕迹被覆盖现象第一次查还能看到某些记录查了几次之后记录消失了。原因Windows 的日志文件有大小上限写满后会覆盖最旧的记录。反复查询、重启、运行程序都会产生新日志加速旧记录被覆盖。另外某些取证工具在运行时会写入临时文件反而污染了原始痕迹。解决拿到机器后第一件事是导出关键日志和注册表 hive后续分析都在副本上做。导出命令# 导出 Security 和 System 日志 wevtutil epl Security C:\evidence\Security.evtx wevtutil epl System C:\evidence\System.evtx # 导出注册表 hive reg save HKLM\SYSTEM C:\evidence\SYSTEM.hiv reg save HKLM\SOFTWARE C:\evidence\SOFTWARE.hiv导出之后原始机器上的操作就不会影响证据了。这一步是血泪经验——我见过有人直接在原始机器上跑了三遍分析脚本结果把最关键的登录记录覆盖掉了。5. 把使用记录变成可验证的时间线两个进阶技巧5.1 用 MFT 补全文件操作时间线前面讲的大多是“程序运行”和“登录”记录但很多时候真正关心的是“某个文件什么时候被打开、修改、删除”。NTFS 文件系统的 MFT主文件表里记录了每个文件的四个时间戳创建时间、修改时间、访问时间、MFT 变更时间。其中“访问时间”默认在 Vista 之后被关闭了但可以通过fsutil behavior set disablelastaccess 0重新开启。解析 MFT 需要专门工具Eric Zimmerman 的MFTECmd是常用选择# 用 MFTECmd 解析 MFT输出 CSV MFTECmd.exe -f C:\evidence\$MFT --csv C:\evidence\output --csvf mft.csv # 在 CSV 中筛选特定文件的记录 python -c import csv with open(C:/evidence/output/mft.csv, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: if 敏感文件名 in row.get(FileName, ): print(row[FileName], row[Created0x10], row[LastModified0x10]) MFTECmd的输出 CSV 里Created0x10和LastModified0x10分别对应$STANDARD_INFORMATION属性里的创建和修改时间。注意还有0x30后缀的列那是$FILE_NAME属性里的时间戳两者可能不一致——0x30的时间在文件被重命名或移动时不会更新所以取证时以0x10为准。5.2 用时间线关联验证记录真实性单一数据源容易被质疑“是不是被篡改过”。把多个独立数据源交叉验证才能让时间线站得住脚。比如验证目标数据源 A数据源 B交叉验证逻辑某程序是否运行过Prefetch 修改时间Amcache 首次运行时间两者时间接近则可信某文件是否被打开RecentDocs 快捷方式Jump List 记录文件名和路径一致某时段是否有人使用事件日志 6005 开机Security 4624 登录开机后紧接着登录USB 是否接入过USBSTOR 注册表setupapi.dev.log设备序列号匹配交叉验证的核心是“找独立来源”。Prefetch 和 Amcache 是两套独立机制一个被清理了另一个可能还在。事件日志和注册表也是独立存储。如果两个独立来源指向同一结论可信度就高得多。我自己的习惯是先跑一遍自动脚本生成初步时间线然后针对关键时间点手工去两个以上数据源确认。这一步多花十分钟但能避免在报告里写出经不起追问的结论。希望帮到你。本文还有配套的精品资源点击获取