IT运维资产盘点脚本,批量采集服务器信息
当服务器数量超过十几台,手工登录记录配置就很容易漏记或写错。
本文提供一套可直接运行的IT运维资产盘点脚本思路:用Shell脚本在本机采集CPU、内存、磁盘、IP和系统版本,再通过Ansible批量分发执行,最后汇总成CSV清单。
零基础用户按步骤操作,约半小时能得到一份可核对的服务器资产表。
盘点前需要确认的环境和文件
这套方案依赖两个基础条件:控制机能够通过SSH免密登录所有被采集服务器,以及被采集服务器上存在bash和常用基础命令。
如果还没有配置免密登录,先在控制机执行:
ssh-keygen -t rsa -b 2048
ssh-copy-id root@192.168.1.101
把192.168.1.101替换成实际服务器IP。
验证免密是否生效:
ssh root@192.168.1.101 "hostname && uptime"
能直接返回主机名和负载信息,说明免密登录可用。
接着准备两个文件:
/etc/ansible/hosts:写入被采集服务器IP或主机名,按业务分组,例如[web]、[db]。/opt/asset/collect.sh:采集脚本本体,放在控制机本地,由Ansible推送到远端执行。
如果控制机没有安装Ansible,
用系统包管理器安装即可,
例如CentOS系执行yum install -y ansible,
Ubuntu/Debian系执行apt install -y ansible。
编写批量采集服务器信息的Shell脚本
采集脚本的目标是输出一行以逗号分隔的资产记录,字段包括主机名、IP、CPU核数、内存、磁盘总量、系统版本和采集时间。
把下面内容保存为/opt/asset/collect.sh:
#!/bin/bash
HOSTNAME=$(hostname)
IP=$(hostname -I | awk '{print $1}')
CPU=$(nproc)
MEM=$(free -m | awk '/Mem:/{print $2"MB"}')
DISK=$(df -h --total | awk '/total/{print $2}')
OS=$(cat /etc/os-release | awk -F'"' '/PRETTY_NAME/{print $2}')
TIME=$(date '+%Y-%m-%d %H:%M:%S')
echo "${HOSTNAME},${IP},${CPU},${MEM},${DISK},${OS},${TIME}"
给脚本加执行权限:
chmod +x /opt/asset/collect.sh
在单台服务器上先验证一次,确认字段没有错位、没有空值:
ssh root@192.168.1.101 'bash -s' < /opt/asset/collect.sh
输出应该类似web01,192.168.1.101,4,7983MB,100G,CentOS Linux 7,2025-01-01 10:00:00。
如果某个字段为空,优先检查对应命令是否存在于该服务器,例如部分精简系统没有nproc,可换成grep -c ^processor /proc/cpuinfo。
用Ansible把采集脚本批量推送到所有服务器
单台验证通过后,就可以批量执行。
Ansible的script模块会把本地脚本复制到远端并运行,适合这种一次性采集场景。
先确认/etc/ansible/hosts内容,例如:
[all:vars]
ansible_ssh_user=root
[web]
192.168.1.101
192.168.1.102
[db]
192.168.1.201
执行采集并把结果写入CSV文件:
ansible all -i /etc/ansible/hosts -m script -a "/opt/asset/collect.sh" -o > /opt/asset/asset_raw.txt
-o参数让输出压缩成一行一台服务器,方便后续处理。
接着把Ansible输出中的主机前缀去掉,只保留采集字段:
awk -F'"' '{print $2}' /opt/asset/asset_raw.txt > /opt/asset/asset.csv
如果输出格式因Ansible版本不同有差异,可以先打开asset_raw.txt看一眼,再调整awk的截取位置。
最终给CSV加上表头:
sed -i '1i hostname,ip,cpu,memory,disk,os,collect_time' /opt/asset/asset.csv
此时用column -s, -t /opt/asset/asset.csv就能在终端里看到对齐的资产表。
容易踩坑的几个地方
免密登录只配了一半:ssh-copy-id只对当前用户生效,如果Ansible使用root而密钥配在普通用户下,采集会直接报Permission denied。
建议先执行ansible all -m ping确认全部返回pong。
脚本换行符问题:在Windows上编辑过的脚本可能带\r,远端执行时报bad interpreter。
用sed -i 's/\r$//' /opt/asset/collect.sh清理一次。
字段错位:如果系统版本名称里本身带逗号,会导致CSV列数变多。
稳妥做法是把分隔符换成竖线|,最后再统一转换。
内存和磁盘单位不统一:不同命令输出单位不同,盘点表里最好统一标注单位,避免后续统计时把MB和GB混在一起。
怎么确认盘点结果可信
不要只看脚本有没有报错,还要做交叉验证。
挑两台服务器,手工执行hostname、nproc、free -m、df -h,和CSV中对应行逐一比对。
数量上,CSV行数应等于/etc/ansible/hosts中配置的主机数,可以用wc -l /opt/asset/asset.csv核对。
如果后续需要定期盘点,把上述命令写进crontab,例如每天凌晨2点执行一次,并在文件名中带上日期,就能形成历史资产快照。
这样即使某台服务器配置被临时调整,也能通过对比发现变化。
常见疑问
脚本采集不到新加的服务器怎么办? 检查/etc/ansible/hosts是否已添加该IP,再执行ansible all -m ping确认连通性。
没有Ansible可以用什么替代? 可以用for ip in $(cat iplist.txt); do ssh root@$ip 'bash -s' < collect.sh; done这种循环方式,
缺点是并发差、
出错后不好定位。
采集信息会不会影响业务? 脚本只读取系统状态,不修改配置、不重启服务,对业务基本无影响;
但建议避开业务高峰执行,尤其是磁盘IO较高的时段。
能不能采集更多字段? 可以,在脚本里追加lspci、dmidecode等命令的输出即可,但要注意部分命令需要root权限,且输出过长会影响CSV可读性。