
1. 为什么我劝你先学会看关机记录而不是急着装监控软件很多人遇到电脑半夜自动重启、下班关机第二天发现机器是开着的、或者服务器莫名其妙断过电第一反应是去装个什么监控工具、上个带告警的软件。我早年也这么干过后来发现纯属绕远路——Windows自己就一直在记这些事只是大多数人从来没打开过那个界面。这个能力就是事件查看器Event Viewer。它不是什么高级工具就是系统自带的一个日志浏览器从Windows NT时代活到现在Win7、Win10、Win11、Server全系都有。它记录的东西细到什么程度你几点几分关机、是正常关机还是异常断电、谁触发的重启、重启前系统有没有报错全都在里面躺着。关键词就三个Windows、事件查看器、关机/重启记录。这篇文章适合谁看三类人。第一类是普通用户电脑老是自己重启想搞清楚到底是谁干的第二类是运维和IT支持需要排查服务器非计划停机第三类是做自动化、脚本、虚拟机的朋友机器状态变化直接影响任务执行必须有个可追溯的依据。不管你是哪类看完这篇你都能自己动手把记录翻出来不用求人。我先说个反直觉的结论关机记录比开机记录更有价值。开机记录只能告诉你它起来了关机记录能告诉你它是怎么倒下的。正常关机、强制断电、蓝屏崩溃、系统更新重启这四种情况在日志里的表现完全不同而区分它们恰恰是定位问题的关键。下面我就按我实际排查的顺序一层层拆给你看。2. 事件查看器里到底该盯哪几个日志通道打开事件查看器很简单Win R输入eventvwr.msc回车或者在开始菜单搜事件查看器。但打开之后很多人就懵了——左边树状目录里几十个日志分类Windows日志下面还有应用程序、安全、系统、Setup等等到底看哪个我直接给结论关机重启相关的记录99%集中在Windows 日志 → 系统这一个通道里。别去应用程序日志里翻那里是软件自己写的也别一上来就看安全日志那是登录审计用的。系统日志才是内核和系统服务汇报状态的地方。2.1 系统日志里的事件来源怎么认系统日志里每一行都有来源Source这一列关机重启相关的来源主要有这么几个我列个表你对照着记事件来源典型事件ID含义Kernel-General12、13系统启动12、系统关闭13Kernel-Power41非正常关机通常是断电或强制关机EventLog6005、6006、6008日志服务启动、停止、意外关闭User321074有程序或用户主动发起的关机/重启Winlogon6000、6003登录相关辅助判断Kernel-Boot20、27启动类型、引导信息这张表是我自己排查时反复用的建议你截图存下来。重点记三个6006是正常关机6008是意外关机41是断电级别的异常。这三个ID基本能覆盖你80%的排查场景。2.2 6006和6008的区别是判断正常与异常的分水岭很多人分不清6006和6008我用大白话解释。6006的意思是事件日志服务已停止它出现的前提是系统走完了正常的关机流程各个服务按顺序退出最后日志服务自己关掉自己。所以你看到6006基本可以认定这是一次体面的关机。6008就难看了它的原文是上一次系统关机是意外的。注意这个上一次——6008是在下次开机时才写进去的因为系统当时已经来不及写日志了。它出现说明系统在关机时没有走完流程可能是直接断电、长按电源键、蓝屏死机或者虚拟机被宿主机强行杀掉。提示6008的时间戳是意外关机发生的时间不是它被记录的时间。这个细节很多人搞错导致时间线对不上。2.3 Kernel-Power 41最需要警惕的那一条如果说6008是意外那Kernel-Power 41就是严重意外。它的完整描述是系统已重新启动但未正常关闭。触发41的原因通常是供电中断、硬件故障、过热保护、驱动崩溃导致死机。它和6008经常成对出现但41的指向性更强——它明确告诉你系统是非正常掉电。我处理过一台工作站每天凌晨三点左右重启6008天天有41隔三差五出现。最后查出来是电源老化负载一高就保护性断电。所以看到41别只盯着软件先怀疑供电和散热这是经验。3. 手把手把关机记录筛出来从图形界面到命令行知道了看哪个通道、认哪些ID接下来就是实操。我给你两条路图形界面适合偶尔查一次命令行适合批量导出和写脚本。两条都学会你才算真正掌握。3.1 图形界面筛选三步锁定目标事件第一步打开事件查看器左侧展开Windows 日志右键系统选筛选当前日志。第二步在弹出的窗口里找到事件 ID输入框把你要查的ID用英文逗号隔开填进去。比如查关机就填6006,6008,41,1074。注意是英文逗号中文逗号不认。第三步如果只想看某个时间段切到筛选器选项卡里的记录时间选指定日期范围。查昨天为什么重启就选昨天到今天的区间。筛完之后中间列表会只剩这几类事件。双击任意一条下面常规标签里有人话描述详细信息标签里有XML格式的原始数据。我一般直接看XML因为里面字段更全比如BugcheckCode、PowerButtonTimestamp这些图形界面不显示。3.2 用PowerShell一条命令导出关机历史图形界面查一次两次还行要长期跟踪就得靠命令。下面这条是我常用的直接复制到管理员权限的PowerShell里跑Get-WinEvent -FilterHashtable { LogNameSystem ID6006,6008,41,1074 } | Select-Object TimeCreated, Id, ProviderName, Message | Sort-Object TimeCreated -Descending | Format-Table -AutoSize -Wrap这条命令的逻辑是从System日志里捞出这四个ID按时间倒序排列输出时间、ID、来源和描述。-Wrap是为了让长描述换行显示不然会被截断。如果你想导出成CSV存档把最后两行换成Export-Csv -Path C:\shutdown_log.csv -NoTypeInformation -Encoding UTF8这样每次排查完存一份时间长了就能看出规律。我之前帮一个客户查每周一早上机器状态不对就是靠连续四周的CSV对比发现是周末的备份任务把机器拖垮导致异常重启。3.3 老系统用wevtutil兼容性更好有些环境还在跑Windows Server 2008或者Win7PowerShell版本低Get-WinEvent可能不好使。这时候用wevtutil这个老工具wevtutil qe System /q:*[System[(EventID6006 or EventID6008 or EventID41)]] /f:text /rd:true /c:50参数解释一下qe是查询事件/q:后面是XPath查询语句/f:text指定文本输出/rd:true表示倒序最新在前/c:50限制返回50条。这条命令在几乎所有Windows版本上都能跑是保底方案。注意wevtutil查询语法是XPath和PowerShell的哈希表写法不一样别混用。我第一次用的时候把EventID6006写成ID6006查出来空的折腾了十分钟才发现。4. 1074事件揪出是谁按下了重启键前面讲的6006、6008、41都是结果告诉你机器怎么关的。但很多时候你真正想知道的是谁让它关的——是Windows更新是某个软件还是有人远程操作这个答案在事件ID 1074里。1074的来源是User32描述格式大致是进程 xxx 已代表用户 xxx 启动计算机 xxx 的关机原因如下xxx。这句话信息量极大它把发起进程、发起用户、关机类型、关机原因全交代了。4.1 从1074里读出四个关键字段我拿一条真实记录举例脱敏处理进程 C:\Windows\System32\svchost.exe 已代表用户 NT AUTHORITY\SYSTEM 启动计算机 的 重启原因如下: 操作系统: 恢复 (计划内) 原因代码: 0x80020002 关机类型: 重启拆开看进程是svchost用户是SYSTEM说明是系统服务发起的原因是恢复计划内原因代码0x80020002关机类型是重启。这一条基本可以判定是Windows更新或系统维护任务触发的重启。再看另一条进程 C:\Program Files\SomeApp\app.exe 已代表用户 DESKTOP-XXX\admin 启动计算机 的 关机原因如下: 其他 (计划外) 原因代码: 0x500ff 关机类型: 关机这条就明确了是某个应用以admin身份发起的关机属于计划外。如果你不认识这个app那它就是嫌疑对象。4.2 原因代码对照0x80020002和0x500ff差在哪原因代码是个32位数高16位表示原因类型低16位表示具体原因。常用的几个我整理如下原因代码含义0x80020002系统更新/维护计划内0x80020003系统更新计划内其他0x500ff其他计划外用户发起0x40010004电源按钮计划外0x84020004应用程序发起的更新重启看到0x8002xxxx基本就是系统自己干的看到0x500ff或0x4001xxxx就要警惕前者是软件后者是物理按键。这个对照表网上不常见是我从微软文档和实际记录里一点点攒出来的你存着有用。4.3 没有1074怎么办反推法有时候你只看到6006正常关机但没看到对应的1074。这种情况通常是关机流程走得太快或者日志被覆盖了。这时候用反推法先找到6006的时间点然后往前推30秒到2分钟看这个窗口内有没有1074、有没有应用程序日志里的异常、有没有系统服务的停止记录。我遇到过一次6006有1074没有往前翻发现是某个备份软件在关机前调用了系统API直接关机没走User32的路径。这种就得结合应用程序日志一起看单看系统日志会漏。5. 虚拟机、蓝屏、更新重启三种特殊场景的日志特征前面讲的是通用方法但实际排查中有三类场景特别容易让人迷惑我单独拎出来说。5.1 虚拟机里的意外关机往往是宿主机干的在VMware、Hyper-V、VirtualBox里跑系统你经常会在客户机日志里看到6008和41。别急着怀疑客户机自己有问题大概率是宿主机把它杀了。比如宿主机重启、宿主机资源不足触发回收、或者你直接点了关闭电源而不是关机。判断方法看客户机41事件的时间戳和宿主机的操作时间对不对得上。如果对得上那就是宿主机的锅。另外Hyper-V的客户机如果装了集成服务正常关机时会走一套心跳流程日志里会有对应的关机请求记录如果没装或者被强制关闭就只有41。提示虚拟机排查时客户机日志和宿主机日志要对着看只看一边永远找不到真相。5.2 蓝屏后的重启41里藏着BugcheckCode蓝屏BSOD导致的重启在系统日志里也是41但它的XML里会多一个字段叫BugcheckCode。这个代码是定位蓝屏原因的关键。比如BugcheckCode0x0000007E通常指向驱动问题0x00000050指向内存问题。提取方法Get-WinEvent -FilterHashtable {LogNameSystem; ID41} | ForEach-Object { $xml [xml]$_.ToXml() [PSCustomObject]{ Time $_.TimeCreated BugcheckCode $xml.Event.EventData.Data | Where-Object {$_.Name -eq BugcheckCode} | Select-Object -ExpandProperty #text } }这段脚本把41事件里的BugcheckCode单独抽出来配合蓝屏代码表一查方向就清楚了。我一般还会同时看C:\Windows\Minidump目录下有没有dump文件有的话用分析工具进一步定位。5.3 Windows更新重启1074 19 43的组合拳系统更新导致的重启日志特征很典型先有一条1074原因代码0x80020002然后关机时6006开机后可能还有事件ID 19更新安装成功和43更新开始安装。这一串连起来就是一次完整的更新重启。如果你发现机器在凌晨自动重启先别慌按这个组合去对。对上了就是更新对不上再往硬件和软件方向查。我见过有人因为更新重启把重要任务跑挂了后来在任务计划里把活动时间设成工作时间就避开了。6. 日志被覆盖、时间对不上、权限不够三个高频坑的解法方法讲完了但实操中总有意外。下面这三个坑我几乎每次带新人都要讲一遍。6.1 日志被覆盖默认只有20MB几天就滚没了系统日志默认最大20MB机器一忙几天就写满老的记录被循环覆盖。等你出问题去查发现记录没了那叫一个绝望。解决办法提前把日志调大。图形界面在系统日志右键→属性把日志最大大小改成100MB甚至更大选按需覆盖或存档。命令行更利索wevtutil sl System /ms:104857600/ms:后面是字节数104857600就是100MB。这个操作建议所有做运维的都提前做别等出事。6.2 时间对不上时区和UTC的坑事件查看器默认显示本地时间但XML里存的是UTC。你用脚本导出的时候如果不做转换时间会差8小时东八区。我第一次导出CSV给客户客户说你这时间怎么是凌晨就是这个问题。PowerShell里TimeCreated默认已经是本地时间但如果你直接读XML的SystemTime字段那是UTC。转换方法[System.TimeZoneInfo]::ConvertTimeToUtc($localTime)或者反过来。总之导出前先确认时区不然时间线全乱。6.3 权限不够普通用户看不到安全日志系统日志普通用户能看但安全日志Security需要管理员权限而且默认审计策略下关机重启不一定记在安全日志里。如果你查的是谁登录后关的机那得先开审计策略再结合安全日志的4634注销和1074一起看。开启方法secpol.msc→ 本地策略 → 审核策略 → 审核登录事件勾选成功和失败。这个改动会影响日志量生产环境要评估。7. 把排查流程固化成脚本我的日常做法查得多了我就把常用操作写成一个脚本放在U盘里到哪台机器插上就能跑。核心逻辑是先导出最近N天的关机相关事件再按ID分类统计最后输出一个摘要。$days 7 $start (Get-Date).AddDays(-$days) $events Get-WinEvent -FilterHashtable { LogNameSystem; ID6006,6008,41,1074; StartTime$start } -ErrorAction SilentlyContinue $summary $events | Group-Object Id | Select-Object Name, Count $summary | Format-Table -AutoSize $events | Sort-Object TimeCreated -Descending | Select-Object TimeCreated, Id, {NBrief;E{$_.Message.Split(n)[0]}} | Export-Csv C:\shutdown_report.csv -NoTypeInformation -Encoding UTF8跑完你会得到一张统计表每个ID出现几次和一份明细CSV。统计表用来看趋势明细用来看具体。我一般每周跑一次机器状态心里有数。提示-ErrorAction SilentlyContinue是为了防止某个ID不存在时报错中断加上更稳。8. 几个我踩过的坑和私藏技巧最后分享几个文档里不会写、但实际特别有用的点。第一6008的时间戳是上次关机时间不是本次开机时间。这个我强调过但还是有人搞错。你看到6008它的时间往前推才是问题发生的时刻。第二关机记录和开机记录要配对看。一次完整的循环是6006关机→ 12启动→ 6005日志服务启动。如果中间缺了6006直接跳到12那这次关机就是异常的。这个配对法比单看一个ID准得多。第三Kernel-Boot的20和27能告诉你启动类型。20是正常启动27是引导相关。如果机器频繁出现27可能是引导配置有问题值得深挖。第四日志里的任务类别字段别忽略。比如1074的任务类别会写关机41会写无这些细节能帮你快速分类。第五长期跟踪建议用自定义视图。事件查看器支持把筛选条件存成自定义视图下次直接点开就行不用重新填ID。路径是左侧自定义视图右键→创建自定义视图把筛选条件配好保存。我给自己建了三个日常关机、异常关机、更新重启切换起来一秒的事。这套东西我从Win7时代用到现在Win11和Server 2022上依然好使。核心就一句话系统一直在记你只要知道去哪看、看哪个ID、怎么把时间线串起来。剩下的就是熟练度的问题了。