本文目录导读:

如何用脚本精准获取内存条序列号(附完整代码)
目录导读
- 为什么需要获取内存序列号?
资产管理、合规审计、远程维护等场景的真实需求
- 核心原理:内存硬件信息的存储与读取机制
SMBIOS与DMI协议如何暴露序列号
- 实战脚本:Windows/Linux/macOS三平台代码
PowerShell、Bash、Python脚本详解
- 常见问题与脚本优化技巧
权限不足、乱码、多通道识别等解决方案
- 问答环节:读者最关心的5个问题
脚本会损坏硬件吗?虚拟机中能否获取?
- 总结与延伸
结合API实现自动化资产盘点
为什么需要获取内存序列号?——场景驱动需求
在企业IT运维中,内存条序列号是资产唯一标识的关键字段。
- 库存管理:批量服务器需追踪每个内存条的生产批次与保修状态。
- 故障排查:通过序列号快速定位损坏内存在哪台机器。
- 安全审计:确保未授权内存未被插入关键设备。
一位运维工程师曾反馈:“手动拆机拍照记录序列号,不仅低效,还容易漏记。” 用脚本自动化获取成了刚需。
核心原理:硬件信息如何被系统读取?
内存序列号并非直接暴露在某文件里,而是通过SMBIOS(系统管理BIOS)标准存储,操作系统通过DMI(桌面管理接口)API查询这些数据:
- Windows:WMI(Windows Management Instrumentation)类
Win32_PhysicalMemory的SerialNumber属性。 - Linux:解析
/sys/devices/system/memory/下的文件,或使用dmidecode命令。 - macOS:通过
system_profiler命令的SPMemoryDataType类型。
注意:部分OEM厂商可能在BIOS中屏蔽序列号字段,此时返回空值属正常现象。
实战脚本:三平台全覆盖代码
1 Windows系统(PowerShell)
# 获取所有内存条序列号(管理员权限可选) Get-WmiObject -Class Win32_PhysicalMemory | Select-Object BankLabel, SerialNumber, Capacity, Manufacturer # 若WMI失效,改用CIM(更现代) Get-CimInstance -ClassName CIM_PhysicalMemory | Format-Table BankLabel, SerialNumber
执行结果示例:
BankLabel SerialNumber Capacity
---------- -------------- --------
BANK 0 2C1D5B3A 8589934592
BANK 2 9F0E4A7C 8589934592
2 Linux系统(Bash脚本)
#!/bin/bash
# 使用dmidecode(需root权限)
sudo dmidecode --type 17 | grep -E 'Locator:|Serial Number' | paste - - | awk '{print $1,$2,$NF}'
# 或直接从sysfs读取(部分内核支持)
for mem in /sys/devices/system/memory/memory*/serial_number; do
echo "$(basename $(dirname $mem)): $(cat $mem 2>/dev/null)"
done
避坑提示:
- 若未安装
dmidecode:apt install dmidecode或yum install dmidecode。 sysfs路径因内核版本而异,建议优先用dmidecode。
3 macOS 系统(Python + system_profiler)
import subprocess, json
def get_mac_serial():
cmd = ['system_profiler', 'SPMemoryDataType', '-json']
result = subprocess.run(cmd, capture_output=True, text=True)
data = json.loads(result.stdout)
memories = data.get('SPMemoryDataType', [])
for mem in memories:
# 注意:macOS 的序列号可能显示为 '0x...' 或空
serial = mem.get('_serial_number', 'N/A')
locator = mem.get('_sp_bank_label', 'Unknown')
print(f'{locator}: {serial}')
get_mac_serial()
常见问题与脚本优化技巧
1 权限不足怎么办?
- Windows:以管理员身份运行PowerShell。
- Linux:
sudo或把当前用户加入dmidecode组(不推荐)。
2 序列号全是空值?
- 可能原因:虚拟机默认不填充序列号(VMware、VirtualBox需在VM配置中开启)。
- 解决方案:尝试读取
Part Number(部件号)作为备选标识。
3 多通道内存如何区分槽位?
使用 BankLabel(Windows)或 Locator(Linux)字段,它们对应主板上的物理插槽编号。
问答环节:读者最关心的5个问题
Q1:脚本会损坏内存硬件吗?
A:不会,脚本仅通过操作系统API读取静态数据,不对硬件进行任何写入操作。
Q2:不同品牌内存(如金士顿、三星)的序列号格式是否一致?
A:不一致,例如金士顿常为字母数字混合(如 KF3200C16D4/16GX),而三星为纯数字,脚本返回原始值,需自行标准化处理。
Q3:为什么我的内存序列号显示为 0x00000000?
A:常见于低端主板或OEM机,BIOS未实现该字段,可尝试更新BIOS或换用 Part Number。
Q4:能否批量获取100台服务器内存序列号?
A:可以,将上述脚本封装为远程执行工具(如Ansible、PowerShell Remoting),返回CSV文件后分析。
Q5:脚本在容器或WSL中能运行吗?
A:WSL直通宿主机硬件信息,但容器默认隔离硬件,需映射 /dev/mem 等设备文件(不推荐生产环境使用)。
总结与延伸
核心结论:
- 通过3个主流平台的脚本,5分钟内即可完成内内存序列号采集。
- 最佳实践:将脚本集成到自动化工具(如SaltStack、Zabbix)中,实现定时轮询与告警。
进阶方向:
- 结合Python
pandas库,将数据清洗后存入数据库。 - 使用REST API(如Redfish)远程获取服务器硬件信息,无需登录系统。
最后提醒:序列号本质是生产商的标识,而非全球唯一ID(可能出现重复,尤其是同一批次),若需绝对唯一,建议组合 SerialNumber + Manufacturer + Part Number 使用。
附录:一行代码快速测试(Linux)
sudo dmidecode -t memory | grep -A5 'Memory Device' | grep -E 'Locator:|Serial Number'