type
status
date
slug
summary
tags
category
icon
password
背景
单位自己搞的备用电力线路,但内部小机房没冗余供电,需要切换电力线路时就需要把机器全关掉,切换完成后再全部开启。
痛点
以前机器少,人肉上去一顿操作猛如虎就完了。现在小机房有40左右物理机器,人工操作太慢了、容易遗漏。
设想
写一个操作带外管理的脚本,日常只要维护好idrac账号和对象清单,实际操作时执行一个命令就可以安逸摘果子吃。
前提
需要安装
redfish
库pip install redfish
脚本
import csv import argparse import logging from datetime import datetime from redfish import RedfishClient # 文件路径 ACCOUNT_FILE = "./idrac_accounts.csv" # 账户信息文件的默认路径 TARGET_FILE = "./operation_targets.txt" # 目标服务器IP地址文件的默认路径 LOG_FILE = "./idrac_operations.log" # 日志文件的默认路径 # 定义开机和关机操作 POWER_STATES = { "on": "On", "off": "GracefulShutdown", } def get_confirmation(state): """获取用户确认""" while True: user_input = input(f"你确定要将所有服务器 {state} 吗?(y/n): ") if user_input.lower() in ["y", "n"]: return user_input.lower() == "y" else: print("无效的输入,请输入 'y' 或 'n'。") def change_power_state(ip, username, password, state): """更改服务器电源状态""" client = RedfishClient(base_url=f"https://{ip}", username=username, password=password) client.login(auth="session") res = client.set_system_boot(POWER_STATES[state]) client.logout() if res.status != 200: logging.error(f"{ip} - {datetime.now()} - Failed to {state} the server: {res.status}") print(f"警告:{ip} 服务器电源状态更改失败。") else: print(f"{ip} 服务器已成功更改电源状态为 '{state}'。") def main(): # Enable logging logging.basicConfig(filename=LOG_FILE, level=logging.ERROR) # 解析命令行参数 parser = argparse.ArgumentParser(description="执行 iDRAC 服务器开机或关机操作") parser.add_argument("state", choices=["on", "off"], help="指定 'on' 开机 或 'off' 关机") args = parser.parse_args() # 读取账号信息文件 accounts = {} try: with open(ACCOUNT_FILE, "r") as f: reader = csv.reader(f) for row in reader: ip, username, password = row accounts[ip] = (username, password) except FileNotFoundError: print(f"警告:账户信息文件 '{ACCOUNT_FILE}' 不存在。") exit() # 读取操作对象文本文件 targets = [] try: with open(TARGET_FILE, "r") as f: for line in f: ip = line.strip() if ip: targets.append(ip) except FileNotFoundError: print(f"警告:目标服务器IP地址文件 '{TARGET_FILE}' 不存在。") exit() # 确认步骤 if not get_confirmation(args.state): print("操作已取消。") exit() # 执行开机/关机操作 for target_ip in targets: if target_ip not in accounts: print(f"警告:{target_ip} 的账号信息不存在。跳过此 IP。") continue username, password = accounts[target_ip] change_power_state(target_ip, username, password, args.state) if __name__ == "__main__": main()
- Po主:瓶幾¬_¬
- 链接:https://blog.v2cu.com/idrac-pwrctl
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。