本文目录导读:

可以的,SNMP 非常适合批量操作,尤其是在网络设备(交换机、路由器、防火墙)、服务器(Linux/Windows)以及各种支持 SNMP 的硬件(UPS、打印机)上。
根据你的具体需求(是批量读取数据,还是批量修改配置),有不同的实用脚本方法,以下我会分场景给出几种最常用的实用脚本方案。
批量读取 SNMP 数据(最常见需求)
需求: 从成百上千台设备中获取 CPU 使用率、接口流量、系统名称等。
最佳工具: snmpbulkwalk (Net-SNMP 套件) + Shell/Bash 脚本
实用脚本 1:批量获取多个设备的系统描述 (Bash)
#!/bin/bash
# 文件名:batch_snmp_get.sh
# 用途:从IP列表文件中批量读取设备的 sysDescr
# 1. 准备一个 IP 列表文件,每行一个IP (或主机名)
# cat ip_list.txt
# 192.168.1.1
# 192.168.1.2
# 192.168.1.3
# 2. 定义 SNMP 参数
COMMUNITY="public"
OID="1.3.6.1.2.1.1.1.0" # sysDescr
# 3. 循环读取文件并执行
while IFS= read -r ip; do
# 使用 snmpget 读取单个 OID,设置2秒超时
result=$(snmpget -v 2c -c "$COMMUNITY" -t 2 "$ip" "$OID" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "$ip: $result"
else
echo "$ip: FAILED (Timeout or No response)"
fi
done < ip_list.txt
实用脚本 2:批量获取接口流量并导出到 CSV (Python + pysnmp)
Python 更适合处理大量数据并进行格式化输出。
import os
import sys
from pysnmp.hlapi import *
import csv
# 文件名:batch_snmp_traffic.py
# 设备列表
devices = ["192.168.1.1", "192.168.1.2", "10.0.0.1"]
community = "public"
port = 161
# 要采集的 OID (示例:接口入方向字节数)
oid_ifInOctets = "1.3.6.1.2.1.2.2.1.10"
with open('snmp_traffic.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['Device', 'Interface Index', 'InOctets'])
for device in devices:
# 使用 snmpbulkwalk 高效遍历
iterator = bulkCmd(
SnmpEngine(),
CommunityData(community),
UdpTransportTarget((device, port)),
ContextData(),
0, 50, # nonRepeaters=0, maxRepetitions=50 (每次取50条)
ObjectType(ObjectIdentity(oid_ifInOctets))
)
for errorIndication, errorStatus, errorIndex, varBinds in iterator:
if errorIndication:
print(f"{device} Error: {errorIndication}")
break
elif errorStatus:
print(f"{device} Error: {errorStatus.prettyPrint()}")
break
else:
for varBind in varBinds:
# varBind 是 (OID, 值) 元组
oid, value = varBind
# 解析索引 (接口编号)
iface_index = oid.prettyPrint().split('.')[-1]
writer.writerow([device, iface_index, value.prettyPrint()])
print(f"Device: {device}, Iface: {iface_index}, Value: {value}")
批量修改 SNMP 配置(批量写操作)
需求: 批量修改所有网络设备的 SNMP Community 字符串、禁用某个接口、或修改 SysLocation。
注意: 批量写操作风险较高,务必先在测试环境验证。
实用脚本 3:批量修改 Community 字符串 (Bash + snmpset)
#!/bin/bash
# 文件名:batch_snmp_set.sh
# 用途:批量修改设备的只读 Community (示例,实际需确认设备OID)
# 注意:很多新设备不支持通过SNMP修改 community,需走CLI。
# 此示例为假设设备支持写入此OID (实际需查询设备MIB)
OLD_COMMUNITY="public"
NEW_COMMUNITY="NewReadOnly2023"
# 假设OID: .1.3.6.1.6.3.16.1.4.1.1.4.1 (此OID仅为示例,实际不可用)
OID_TO_WRITE="1.3.6.1.6.3.16.1.4.1.1.4.1"
while IFS= read -r ip; do
# 使用 snmpset 写入新值 (字符串类型)
result=$(snmpset -v 2c -c "$OLD_COMMUNITY" -t 5 "$ip" "$OID_TO_WRITE" s "$NEW_COMMUNITY" 2>&1)
if [ $? -eq 0 ]; then
echo "$ip: SUCCESS - Community changed"
else
echo "$ip: FAILED - $result"
fi
done < ip_list.txt
批量发现设备(自动扫描)
需求: 在不知道有哪些设备的情况下,自动发现局域网内的 SNMP 设备。
实用脚本 4:基于 Ping 扫描 + SNMP 验证 (Bash)
#!/bin/bash
# 扫描子网 /24
SUBNET="192.168.1"
COMMUNITY="public"
for ip in $(seq 1 254); do
full_ip="${SUBNET}.${ip}"
# 先快速ping一下 ( -c 1 -W 1 )
ping -c 1 -W 1 "$full_ip" > /dev/null 2>&1
if [ $? -eq 0 ]; then
# ping通,尝试获取sysName
result=$(snmpget -v 2c -c "$COMMUNITY" -t 2 "$full_ip" "1.3.6.1.2.1.1.5.0" 2>/dev/null)
if [ $? -eq 0 ]; then
echo "FOUND: $full_ip - $result"
fi
fi
done
几个关键建议(实用经验)
- 超时与重试:网络不稳定,脚本中要加
-t 2(超时2秒)或-r 1(重试1次)。 - 并发处理:如果设备超过 100 台,串行执行会非常慢(每台2秒),可以改用
xargs -P(并行)或 Python 的ThreadPoolExecutor。# 用 xargs 并行执行,-P 10 表示最多10个并发 cat ip_list.txt | xargs -I {} -P 10 snmpget -v2c -c public {} 1.3.6.1.2.1.1.1.0 - MIB 文件:OID 显示为数字,需要加载对应 MIB 文件才能显示为可读名称(如
sysDescr),使用 Bash 时,先执行export MIBS=+ALL。 - 安全性:
- 绝对不要在公网生产环境写死
public。 - 批量写操作日志一定要记录到文件,方便回滚。
- SNMPv3 更安全,但脚本复杂度会高一些(需要设置用户名、认证密码、加密密码)。
- 绝对不要在公网生产环境写死
- 单纯批量读:用 Bash + snmpbulkwalk 最轻量、最方便。
- 需要数据处理/复杂逻辑:用 Python + pysnmp 更灵活。
- 需要并发和效率:用 xargs -P 或在 Python 里加线程池。
如果你能提供更具体的目标(批量采集思科交换机的 ARP 表、或批量修改所有 H3C 设备的登录密码),我可以给出针对性更强的脚本。