简介这是一款面向企业IT运维人员与设备管理者的电脑硬件信息采集与资产管理工具基于C#开发可一键获取CPU、内存、硬盘、显卡、主板等关键硬件的型号与规格参数并支持资产分类存储、增删改查及使用状态记录帮助解决企业硬件信息手工登记繁琐、资产台账更新滞后的问题。资源包共32个文件约115KB以18个cs源码文件为核心配合5个resx界面资源、sln解决方案与csproj工程文件另含README说明、LICENSE授权、ico图标及html页面等结构完整便于直接编译运行或二次开发。目前已有327人学习下载。通过该源码读者可了解C#桌面端硬件信息采集的实现思路、.NET工程组织方式以及资产数据管理模块的代码结构适合作为企业IT工具开发的学习参考或功能扩展基础。1. 企业IT资产盘点从一台电脑的硬件信息采集说起公司新采购了五十台笔记本IT部门需要在一周内完成资产录入。如果一台台开机、手动抄写CPU型号、内存容量、硬盘序列号两个人干三天也未必能对齐数据。更麻烦的是半年后要做资产核查发现台账上写的“8GB内存”和实际机器里的“8GB44”对不上保修申请被驳回。这类场景在企业IT运维里反复出现核心痛点只有一个硬件信息采集没有标准化、自动化。所谓一键收集电脑硬件信息本质是写一个脚本或小工具在目标机器上运行后自动读取主板、CPU、内存、硬盘、网卡、显卡等部件的型号、序列号、容量、使用状态并输出成结构化数据CSV、JSON或直接入库。它解决的是企业电脑设备资产从“人工抄写”到“自动上报”的问题适合IT运维、资产管理、设备巡检岗位的从业者。你不需要买昂贵的资产管理系统用系统自带的命令行工具加一段脚本就能跑通最小闭环。2. 硬件信息到底从哪里读WMI、SMBIOS与系统命令的选型对比2.1 为什么优先选WMI而不是直接读注册表Windows系统里获取硬件信息的途径很多注册表、设备管理器、系统API、WMIWindows Management Instrumentation都能拿到部分数据。但注册表里的硬件信息分散且不完整比如内存条的具体型号和序列号在注册表里往往缺失设备管理器只适合人眼看不适合程序批量提取。WMI是微软官方提供的管理接口它把硬件抽象成类每个类对应一类设备查询语法统一返回字段稳定。常见做法是用Win32_Processor拿CPUWin32_PhysicalMemory拿内存条Win32_DiskDrive拿物理硬盘Win32_BIOS拿主板和BIOS序列号。这些类在Windows 7到Windows 11上都存在兼容性好。我一般会先用WMI跑一遍如果某个字段为空再考虑用wmic命令或PowerShell的Get-CimInstance兜底。2.2 用PowerShell跑通第一台机器的采集下面这段脚本在PowerShell里直接运行输出当前机器的核心硬件信息。注意以管理员身份运行否则部分字段如硬盘序列号可能读不到。# 采集CPU信息 $cpu Get-CimInstance -ClassName Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed # 采集内存信息 $memory Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object Manufacturer, Capacity, Speed, SerialNumber # 采集硬盘信息 $disk Get-CimInstance -ClassName Win32_DiskDrive | Select-Object Model, Size, SerialNumber, InterfaceType # 采集BIOS和主板 $bios Get-CimInstance -ClassName Win32_BIOS | Select-Object SerialNumber, Manufacturer, SMBIOSBIOSVersion $board Get-CimInstance -ClassName Win32_BaseBoard | Select-Object Product, Manufacturer, SerialNumber # 输出为JSON $result [PSCustomObject]{ CPU $cpu Memory $memory Disk $disk BIOS $bios Board $board } $result | ConvertTo-Json -Depth 3 | Out-File -FilePath C:\AssetInfo.json -Encoding UTF8逻辑说明Get-CimInstance是PowerShell推荐的WMI查询方式比老旧的Get-WmiObject性能更好。Select-Object只保留需要的字段避免输出冗余。ConvertTo-Json把对象转成JSON方便后续入库或上传。参数方面-Depth 3确保嵌套对象如内存数组被完整序列化-Encoding UTF8防止中文型号乱码。2.3 用wmic命令做轻量级采集如果目标机器不允许运行PowerShell脚本或者你只想快速看一眼wmic命令是最轻量的选择。下面几条命令分别采集CPU、内存、硬盘和主板序列号。wmic cpu get Name,NumberOfCores,NumberOfLogicalProcessors /format:csv wmic memorychip get Manufacturer,Capacity,Speed,SerialNumber /format:csv wmic diskdrive get Model,Size,SerialNumber,InterfaceType /format:csv wmic bios get SerialNumber,Manufacturer,SMBIOSBIOSVersion /format:csv wmic baseboard get Product,Manufacturer,SerialNumber /format:csv/format:csv让输出直接是逗号分隔方便重定向到文件。注意wmic在Windows 11部分版本里已被标记为弃用但截至我写这篇文章时仍能正常使用。如果遇到命令不存在改用Get-CimInstance即可。2.4 跨平台场景Linux下用dmidecode和lshw企业里如果有Linux服务器或国产化终端采集方式不同。dmidecode能读SMBIOS信息lshw能列出所有硬件。下面这条命令输出JSON格式的硬件摘要。sudo lshw -json /tmp/hardware.json sudo dmidecode -t system -t baseboard -t processor -t memory /tmp/dmi.txtlshw -json适合程序解析dmidecode适合人工核对。注意dmidecode需要root权限普通用户只能看到部分信息。3. 把采集结果变成资产台账批量执行与数据清洗3.1 批量下发脚本的三种方式单台机器跑通后下一步是批量执行。常见做法有三种域环境用组策略登录脚本非域环境用PsExec远程执行或者用计划任务定时运行。我一般会写一个入口脚本放在共享目录然后通过组策略推送到每台机器。# 入口脚本采集后写入网络共享 $sharePath \\192.168.1.10\asset$ $fileName $env:COMPUTERNAME _ (Get-Date -Format yyyyMMdd) .json $localFile C:\Temp\AssetInfo.json # 调用采集脚本 \\192.168.1.10\asset$\collect.ps1 # 复制到共享目录 Copy-Item -Path $localFile -Destination (Join-Path $sharePath $fileName) -Force逻辑说明$env:COMPUTERNAME作为文件名前缀避免多台机器覆盖。Get-Date加日期方便追溯。Copy-Item -Force覆盖旧文件。参数方面共享目录需要给域计算机账户写权限否则复制失败。3.2 用Python做数据清洗和去重采集上来的JSON文件往往有重复、字段缺失、单位不统一的问题。比如内存容量是字节数硬盘容量也是字节数但台账里需要GB。下面这段Python脚本读取所有JSON清洗后输出CSV。import json import glob import csv import os def bytes_to_gb(value): if value is None: return 0 return round(int(value) / (1024**3), 2) rows [] for file in glob.glob(//192.168.1.10/asset$/*.json): with open(file, r, encodingutf-8) as f: data json.load(f) hostname os.path.basename(file).split(_)[0] cpu data.get(CPU, [{}])[0] memory_list data.get(Memory, []) disk_list data.get(Disk, []) total_mem sum(bytes_to_gb(m.get(Capacity)) for m in memory_list) total_disk sum(bytes_to_gb(d.get(Size)) for d in disk_list) rows.append({ 主机名: hostname, CPU型号: cpu.get(Name, ).strip(), 核心数: cpu.get(NumberOfCores, ), 内存GB: total_mem, 硬盘GB: total_disk, BIOS序列号: data.get(BIOS, {}).get(SerialNumber, ).strip(), 主板序列号: data.get(Board, {}).get(SerialNumber, ).strip() }) with open(asset_summary.csv, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnamesrows[0].keys()) writer.writeheader() writer.writerows(rows)逻辑说明glob.glob遍历共享目录下所有JSON。bytes_to_gb统一单位。data.get(CPU, [{}])[0]防止CPU字段为空导致索引报错。encodingutf-8-sig让Excel打开CSV不乱码。参数方面共享目录路径需要根据实际环境修改rows[0].keys()要求至少有一个文件否则报错。3.3 入库与去重策略如果企业有资产管理系统可以把CSV导入数据库。常见做法是用主机名加BIOS序列号作为唯一键每次采集后做UPSERT。下面这条SQL在MySQL里创建表并插入数据。CREATE TABLE asset ( id INT AUTO_INCREMENT PRIMARY KEY, hostname VARCHAR(64) NOT NULL, cpu_model VARCHAR(128), cores INT, memory_gb DECIMAL(10,2), disk_gb DECIMAL(10,2), bios_sn VARCHAR(64), board_sn VARCHAR(64), collect_date DATE, UNIQUE KEY uk_host_sn (hostname, bios_sn) ); INSERT INTO asset (hostname, cpu_model, cores, memory_gb, disk_gb, bios_sn, board_sn, collect_date) VALUES (PC-001, Intel Core i5-10400, 6, 16.00, 512.00, ABC123, DEF456, CURDATE()) ON DUPLICATE KEY UPDATE cpu_model VALUES(cpu_model), cores VALUES(cores), memory_gb VALUES(memory_gb), disk_gb VALUES(disk_gb), board_sn VALUES(board_sn), collect_date VALUES(collect_date);逻辑说明UNIQUE KEY确保同一台机器同一天不会重复插入。ON DUPLICATE KEY UPDATE实现UPSERT硬件变更时更新字段。参数方面bios_sn作为唯一标识比主机名更可靠因为主机名可能被修改。4. 避坑与排查硬件信息采集的五个血泪教训4.1 现象硬盘序列号读出来是乱码或空值原因部分NVMe硬盘的序列号在WMI里返回的是十六进制字符串或者需要管理员权限才能读取。另外某些品牌机如部分联想、戴尔机型的硬盘序列号被厂商工具隐藏。解决以管理员身份运行脚本如果仍为空改用Get-PhysicalDisk | Select-Object SerialNumber再不行就用厂商提供的命令行工具如戴尔的omreport兜底。4.2 现象内存条只读到一条实际插了两条原因Win32_PhysicalMemory在某些主板BIOS下只返回第一条内存的信息或者双通道内存被识别为一条。解决改用Win32_PhysicalMemoryArray读插槽总数再结合Win32_PhysicalMemory逐条读取。如果还是不对用wmic memorychip list full交叉验证。4.3 现象脚本在部分机器上执行超时原因WMI查询本身较慢尤其是硬盘和网卡类如果机器同时在做Windows更新查询可能卡住。解决给每个查询加超时限制。PowerShell里可以用-OperationTimeoutSec参数或者把采集拆成多个小脚本分步执行。4.4 现象采集上来的JSON文件中文乱码原因PowerShell默认输出编码是UTF-16或ANSIPython读取时按UTF-8解析会乱码。解决在PowerShell里用Out-File -Encoding UTF8Python读取时用encodingutf-8-sig。如果还是乱码用chardet库检测编码后再读。4.5 现象域环境下组策略脚本不执行原因组策略登录脚本默认在用户登录时运行如果用户没有管理员权限部分WMI查询会失败。另外脚本路径如果用了映射驱动器计算机账户可能访问不到。解决改用计算机启动脚本以系统权限运行共享目录用IP地址而不是映射驱动器在组策略里勾选“以最高权限运行”。5. 进阶用Python封装成可执行文件并自动上报5.1 为什么用PyInstaller打包企业里不是每台机器都装了Python把采集脚本打包成单个exe双击就能跑是最省事的落地方式。PyInstaller能把Python脚本和依赖库打包成一个文件目标机器不需要装Python。pip install pyinstaller pyinstaller --onefile --noconsole --name AssetCollector collect.py--onefile生成单个exe--noconsole不弹黑窗口--name指定输出文件名。生成的exe在dist目录下复制到目标机器即可运行。5.2 自动上报到HTTP接口采集完成后把JSON通过HTTP POST上报到资产服务器。下面这段Python代码用requests库实现。import requests import json import socket def report(data, server_url): payload { hostname: socket.gethostname(), data: data } try: resp requests.post(server_url, jsonpayload, timeout10) if resp.status_code 200: print(上报成功) else: print(f上报失败状态码{resp.status_code}) except requests.exceptions.RequestException as e: print(f网络异常{e}) if __name__ __main__: with open(AssetInfo.json, r, encodingutf-8) as f: data json.load(f) report(data, http://192.168.1.10:8000/api/asset)逻辑说明socket.gethostname()获取主机名requests.post发送JSONtimeout10防止卡死。参数方面server_url替换成实际接口地址接口需要支持接收JSON并返回200。5.3 验证采集完整性的三个检查点第一对比设备管理器里看到的硬件数量和脚本采集到的数量是否一致。第二用Get-CimInstance Win32_ComputerSystem读到的总内存和Win32_PhysicalMemory累加值是否吻合。第三把采集结果和采购台账做一次全量比对重点看序列号字段。我一般会在脚本里加一个自检逻辑如果CPU、内存、硬盘任一字段为空就写一条警告日志方便后续排查。这个习惯帮我省了很多后悔药因为硬件信息采集最怕的不是采不到而是采到了但字段是空的台账看起来有数据实际没法用。希望帮到你。本文还有配套的精品资源点击获取