1. 一台"说不清哪里不对劲"的机器,逼我把CMD捡了回来
我平时远程连一台机器,第一反应不是打开任务管理器点来点去,而是先开一个 CMD 窗口敲几条命令。原因很简单:图形界面给你的信息是"被筛选过的",命令行给你的是"原始的"。任务管理器里看到一个进程占着 30% 的 CPU,你想知道它的完整命令行参数、启动用户、父进程、所在目录,这些在界面上要点三四层,在 CMD 里一条带筛选的tasklist或者wmic process就能一次性摊开。Windows 命令提示符里的系统信息查询和系统管理这两类命令,本质上就是一套"体检工具加手术刀",前者负责看清家底,后者负责动手干预。
这篇是 CMD 系列的第二部分,重心从文件目录操作挪到机器本身:怎么在三十秒内摸清一台 Windows 的版本、补丁、内存、账户、服务、进程、磁盘占用,出问题时用什么命令去定位、去干预、去收尾。我在生产环境里反复用过这套命令,下面会尽量把"为什么这么敲"和"敲完之后会发生什么"讲明白,而不是甩一张参数表让读者自己去猜。适合日常要维护几台到几百台 Windows 机器的人、写批处理脚本的人,也适合被"电脑很卡但不知道卡在哪"困扰的普通用户。
2. 系统底账:先把机器的身份和家底问清楚
2.1 systeminfo 的输出里,真正有用的只有四行
systeminfo是我登录一台陌生机器的第一条命令,但它输出几十行,很多人扫一眼就关掉了。实际上真正有诊断价值的只有四块内容:OS 版本与构建号、系统启动时间、物理内存总量、热修复补丁列表。启动时间这一项尤其被低估,一台本该常年不重启的服务器如果显示"系统启动时间"就在两小时前,那说明它刚刚意外重启过,后面所有的"服务连不上"都要先怀疑这个。
构建号(Build)是判断系统版本层级的硬指标,比"Windows 10"这种商品名靠谱得多。常见对应关系我整理了一下,省得每次都要去翻资料:
| 构建号区间 | 对应系统层级 | 实用判断 |
|---|---|---|
| 19041 - 19045 | 较早期的桌面系统分支 | 部分新组件默认不可用 |
| 22000 | 桌面系统的一个过渡分支 | 界面改动大,兼容性坑多 |
| 22621 / 22631 | 较新的桌面系统分支 | 主流支持版本 |
| 20348 / 25398 | 服务器分支 | 桌面组件默认缺失 |
systeminfo支持远程查询,参数是/s 目标机器 /u 用户名 /p 密码。但我得提醒一句:这个命令远程跑起来很慢,因为它背后要串行拉取一大串 WMI 类,跨网段时等个二三十秒是常事。批量巡检场景下,宁可写个循环配合超时控制,也别指望它秒回。如果只想看补丁,用wmic qfe list brief会快得多;如果只想看系统名和版本,wmic os get Caption,Version,BuildNumber /value一行就够。
2.2 ver 分不出系统大版本,这是个流传很广的误解
很多人习惯敲ver看系统版本,看到Microsoft Windows [版本 10.0.22631.3737]就以为知道是什么系统了。问题在于,这一串版本号里的大版本号长期停留在 10.0,不同代际的桌面系统都可能显示 10.0 开头,光看ver你没法区分具体是哪一代。真正靠谱的取值位置在注册表:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v DisplayVersion reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildDisplayVersion给出的是年度功能更新标识,ProductName给出的是产品名,CurrentBuild是构建号。这三条一起看,基本不会有歧义。写成一行批处理也很方便:
for /f "tokens=2,*" %a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v DisplayVersion ^| findstr DisplayVersion') do @echo 系统版本: %bhostname和whoami是两个小到容易被忘掉的命令,但在排障时很关键。多开远程会话的时候,你经常需要确认"我现在这条命令到底打在哪台机器上"——hostname一眼就能确认。whoami更狠一点,加上/all参数会把当前账户的 SID、所属用户组、启用/禁用的特权列表全列出来。我遇到过一个很典型的场景:脚本明明在管理员账户下运行,某个操作还是被拒绝,whoami /all一看,账户虽然在管理员组里,但当前进程是以筛选后的令牌运行的,特权列表里缺少SeDebugPrivilege之类的高危项。这种问题在图形界面上基本查不出来。
2.3 set 不只是看环境变量,它是定位"路径类故障"的快捷入口
set不带参数会列出当前会话的全部环境变量,输出很长,但配合管道筛选就非常好用:
set | findstr /i path set | findstr /i temp我碰到最多的一类问题叫"命令行能跑、双击脚本就跑不了",九成是PATH在用户级和系统级之间打架,或者某个工具的新版本把旧版本目录挤出了 PATH。用set path看清楚当前会话的实际拼接结果,比在系统属性对话框里逐条比对快得多。
还有一个更隐蔽的坑:环境变量改了但没生效。这通常是因为你改的是系统级变量,而已打开的 CMD 窗口继承的是启动那一刻的环境快照。批处理里如果依赖新加的环境变量,最稳的做法是在脚本开头显式call一次刷新,或者干脆用绝对路径,别赌环境变量。
2.4 wmic 的退场与替代写法
wmic曾经是 CMD 下查硬件和管理系统的一把好手,但它已经被标记为弃用,新系统上默认可能不存在或者被裁剪。老脚本里大量出现它的身影,所以还是得知道几个高频用法,同时也得知道替代方案。
高频的几条:
wmic logicaldisk get Caption,FileSystem,FreeSpace,Size wmic cpu get Name,NumberOfCores,NumberOfLogicalProcessors wmic memorychip get Capacity,Speed,Manufacturer wmic bios get SerialNumber,ReleaseDate wmic qfe list brief替代方案是 CIM 类查询,在支持的命令行环境里写成:
powershell -NoProfile -Command "Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID,FileSystem,FreeSpace,Size | Format-Table"我个人在家用和小规模场景里还是习惯用wmic,因为它启动快、输出简单;但在新机器上部署脚本时,我会优先写 CIM 版本,避免哪天机器升级后wmic直接报"不是内部或外部命令"。这个取舍没什么对错,关键是别把整条排障链路押在一个已被标记弃用的工具上。
3. 进程与服务:把"谁在吃资源"这条链路走通
3.1 tasklist 的筛选参数,比任务管理器好用在哪
tasklist默认输出进程名、PID、会话名、内存占用,看着和任务管理器差不多。真正拉开差距的是/fi筛选器,它支持按内存、CPU 时间、状态、会话、用户名做条件过滤:
tasklist /fi "memusage gt 500000" /fo table tasklist /fi "username eq 某账号" /v tasklist /fi "status eq not responding" tasklist /svc /fi "imagename eq svchost.exe"第一条命令列出内存占用超过 500MB 的进程(单位是 KB,所以 500000 大约是 488MB,这个单位换算第一次用的人基本都会搞错)。第三条筛出"无响应"的进程,处理卡死窗口时比一个个点过去效率高得多。第四条是我最常用的:svchost.exe一个进程名下面挂着几十个系统服务,加/svc参数能把 PID 和它承载的服务名一一对应列出,定位"到底是哪个系统服务在闹事"时必不可少。
配合/fo csv和/nh(不打印表头),输出变