Python批量远程关机:Windows局域网多机自动关机脚本实战

发布时间:2026/10/23 15:34:22
Python批量远程关机:Windows局域网多机自动关机脚本实战 简介这份资源面向需要在Windows环境下管理多台设备的IT运维人员与Python学习者提供一套自动远程批量关机的脚本方案解决逐台手动关机效率低、易遗漏的问题。压缩包共3个文件包含1个py脚本与2个txt说明文档整体仅923B轻量易取脚本可直接参考或改造使用。内容围绕WMI远程管理展开涉及通过win32com.client建立远程连接、调用Win32_ComputerSystem的Shutdown方法执行软关机或强制关机并以IP列表遍历实现批量下发命令同时提示管理员权限、目标机远程管理策略配置以及用户名密码的安全存放方式。已有897人学习下载适合希望快速掌握远程批量关机思路、并在此基础上扩展重试与超时等健壮性处理的读者参考借鉴。1. 机房巡检收尾那点事为什么我最终选了 Python 批量远程关机凌晨一点半实验室的灯还亮着三十多台 Windows 工作站跑完最后一轮渲染任务风扇声像一群不肯落地的直升机。手动一台台点“开始→关机→确定”点到最后手都麻了还漏了两台第二天被导师问“昨晚那几台怎么还开着”。这就是我最初折腾批量远程关机的真实动机——不是炫技是实在受不了重复劳动。这份资源要解决的核心问题很具体在 Windows 环境下用 Python 脚本对局域网内多台 Windows 主机发起自动、批量的远程关机。它适合谁适合手里管着几台到几十台 Windows 机器、又不想逐台登录操作的人——实验室管理员、测试机维护者、小型机房值守人员。关键词里的“自动”“远程关机”“批量关机”“windows”“python”五个词基本就是它的全部能力边界。下面我按“先跑通一台再扩到一批最后处理翻车”的顺序拆开讲。2. 远程关机的底层通道WMI、RPC 与 shutdown 命令怎么选2.1 三条常见技术路线对比Windows 上让另一台机器关机绕不开三个东西shutdown命令、WMIWindows Management Instrumentation、以及基于 RPC 的远程调用。它们不是并列关系而是层层包裹——shutdown /m底层走的就是 RPCWMI 也能调Win32_OperatingSystem的Shutdown方法。路线调用方式依赖服务适用场景主要限制shutdown 命令shutdown /s /m \\目标IPRPC、Remote Registry快速脚本、临时操作报错信息模糊权限要求高WMIwmic /node:IP或 Pythonwmi库WMI 服务、DCOM需要读取状态再关机配置复杂防火墙端口多PsExec 类工具远程执行进程Admin$ 共享、SMB需要执行任意命令需额外工具易被杀软拦截我一般优先用shutdown命令因为它最轻不需要额外装库Python 里一个subprocess就能调。但它的坑也最多后面避坑章节会细说。2.2 为什么用 Python 而不是批处理批处理也能写for循环调shutdown但一旦要处理“哪些机器在线”“失败重试”“记录日志”“并发控制”bat 就力不从心了。Python 的优势在于可以用concurrent.futures做并发用subprocess拿返回码用logging落日志用ipaddress生成网段。这些在几十台机器的场景下不是锦上添花是刚需——串行关机等一台超时 30 秒三十台就是十五分钟。2.3 前置条件目标机器必须打开什么远程关机不是发个包就完事目标 Windows 主机必须满足几个条件缺一个就报“拒绝访问”Remote Registry 服务默认手动启动远程 RPC 调用需要它。设为自动并启动。防火墙规则入站放行“Windows Management Instrumentation (WMI)”和“Remote Service Management”相关规则或者临时关闭域内防火墙测试。账号权限发起端使用的账号必须是目标机的管理员组成员且目标机不能是空密码账号Windows 默认禁止空密码远程登录。网络发现同一网段或路由可达能 ping 通是基本前提。这些条件在域环境里通常由组策略统一配好但在工作组环境比如实验室临时搭的机器里得一台台确认。我习惯先拿一台当“小白鼠”跑通了再批量。import subprocess def shutdown_one(ip, timeout10): 对单台 Windows 主机发起远程关机 :param ip: 目标主机 IP :param timeout: 子进程超时秒数防止卡死 :return: (ip, 是否成功, 返回信息) cmd fshutdown /s /t 0 /m \\\\{ip} /f try: # capture_output 捕获 stdout/stderrtext 让输出为字符串 result subprocess.run( cmd, shellTrue, capture_outputTrue, textTrue, timeouttimeout ) if result.returncode 0: return ip, True, 关机指令已发送 else: return ip, False, result.stderr.strip() or result.stdout.strip() except subprocess.TimeoutExpired: return ip, False, 超时目标无响应这段代码是整套脚本的最小单元。shutdown /s表示关机/t 0表示立即执行延迟 0 秒/m \\IP指定远程目标/f强制关闭正在运行的程序——不加/f时如果有未保存的文档目标机会弹窗等待远程场景下没人点确认就会一直挂着。timeout参数是血泪经验网络不通时shutdown命令可能卡很久不设超时整个批量任务会被一台机器拖死。提示/t 0和/f组合会直接丢弃未保存内容生产环境慎用测试机随意。3. 从单台到批量IP 列表、并发与日志三件套3.1 IP 来源文件读取还是网段扫描批量关机的第一步是拿到目标列表。常见做法有两种一是维护一个hosts.txt每行一个 IP二是给一个网段先 ping 扫描再关机。前者可控后者省事但容易误伤。我一般用文件方式因为“哪些机器该关”是个业务判断不该交给脚本猜。文件格式就一行一个 IP允许#开头注释# 渲染组 192.168.1.101 192.168.1.102 # 测试组 192.168.1.201读取时过滤空行和注释顺便去重def load_targets(path): 从文本文件加载 IP 列表忽略空行和 # 注释 targets [] with open(path, r, encodingutf-8) as f: for line in f: line line.strip() if not line or line.startswith(#): continue targets.append(line) # 去重但保持顺序 return list(dict.fromkeys(targets))dict.fromkeys是去重的常用技巧比set好的地方是保留原始顺序日志读起来符合直觉。3.2 并发控制线程池不是越多越好三十台机器串行关机每台哪怕只花 2 秒也要一分钟。用线程池并发能把时间压到几秒。但线程数不是越大越好——shutdown命令本身会创建进程线程太多反而抢资源而且目标机可能扛不住同时涌入的连接。from concurrent.futures import ThreadPoolExecutor, as_completed def shutdown_batch(targets, max_workers8): 并发批量关机max_workers 控制同时发起的关机数 results [] with ThreadPoolExecutor(max_workersmax_workers) as executor: future_map { executor.submit(shutdown_one, ip): ip for ip in targets } for future in as_completed(future_map): ip future_map[future] try: results.append(future.result()) except Exception as e: results.append((ip, False, f异常: {e})) return resultsmax_workers8是我在几十台规模下比较稳的值。机器少可以调到 4上百台可以到 16但再高收益递减还容易触发目标机的连接限制。as_completed保证谁先返回先处理谁不会因为某台慢而阻塞日志输出。3.3 日志与结果核对别关完就完事批量操作最怕“以为都关了其实有几台没关”。所以每次执行都要落日志记录时间、IP、成功与否、失败原因。日志用标准logging模块同时输出到控制台和文件import logging def setup_logger(log_fileshutdown.log): logger logging.getLogger(batch_shutdown) logger.setLevel(logging.INFO) fmt logging.Formatter(%(asctime)s [%(levelname)s] %(message)s) # 文件处理器追加模式 fh logging.FileHandler(log_file, encodingutf-8) fh.setFormatter(fmt) # 控制台处理器 ch logging.StreamHandler() ch.setFormatter(fmt) logger.addHandler(fh) logger.addHandler(ch) return logger执行完打印一个汇总表成功多少、失败多少、失败的是哪些 IP。失败列表可以直接复制出来排查后重跑——脚本要支持“只对失败的重试”而不是每次全量重来。注意日志文件别放在会被关机影响的机器上发起端自己别被关进去。4. 避坑与排查远程关机最常见的五类翻车4.1 现象提示“拒绝访问(5)”原因发起端账号不是目标机管理员或目标机禁用了空密码远程登录或 Remote Registry 服务没启动。解决确认账号在目标机Administrators组用net use \\IP\IPC$ /user:管理员账号先建立凭据会话再关机检查组策略“账户使用空密码的本地账户只允许进行控制台登录”是否被启用。4.2 现象命令返回成功但机器没关原因shutdown返回 0 只代表指令送达不代表目标机执行了。目标机可能因为有待保存文档、有程序阻止关机、或电源策略拦截。解决加/f强制关闭如果仍不关去目标机事件查看器看“系统”日志里User32或Kernel-Power的记录确认目标机没有处于“演示模式”或接了不允许关机的策略。4.3 现象部分机器超时脚本卡住原因网络不通或目标机防火墙拦截shutdown命令在等 RPC 响应。解决subprocess.run必须带timeout批量前先并发 ping 一轮把不在线的剔掉减少无效等待。4.4 现象关机后无法再次远程唤醒原因这是关机不是重启Wake-on-LAN 需要网卡和主板支持且关机后网卡仍供电。解决如果后续要远程开机关机前确认目标机 BIOS 和网卡驱动开启了 WOL否则只能现场开机。这个坑我在实验室踩过关得爽第二天全员现场按电源键。4.5 现象杀软或安全软件拦截 shutdown 调用原因部分终端防护会把远程shutdown当成可疑行为。解决在目标机安全软件里把发起端 IP 或shutdown.exe加入白名单或者改用 WMI 方式但 WMI 同样可能被拦。没有银弹只能按环境调。5. 进阶把关机做成可调度、可回滚的例行任务5.1 用计划任务做定时批量关机脚本跑通后下一步是让它自动在固定时间执行。Windows 任务计划程序里建一个基本任务触发器设为每天 23:30操作设为python.exe D:\scripts\batch_shutdown.py起始目录填脚本所在目录。注意“不管用户是否登录都要运行”要勾上否则锁屏后不执行。5.2 加一个“预演模式”再真关直接批量关机风险高我后来给脚本加了一个--dry-run参数只 ping 和打印将要关机的列表不真正调用shutdown。确认列表无误后再去掉参数执行。这个习惯救过我好几次——有一次 IP 文件里混进了一台正在跑重要任务的机器预演时看到了及时删掉。import argparse def parse_args(): parser argparse.ArgumentParser(descriptionWindows 批量远程关机) parser.add_argument(--file, defaulthosts.txt, helpIP 列表文件) parser.add_argument(--workers, typeint, default8, help并发数) parser.add_argument(--dry-run, actionstore_true, help只预演不关机) return parser.parse_args()argparse让脚本从“改代码调参数”变成“命令行传参”配合计划任务和手动执行都方便。--dry-run是布尔开关不加就是真关加了就只打印。5.3 验证关机结果ping 轮询确认指令发出去不等于关掉了。执行完等 30 秒再对目标列表做一轮 ping还在线的就是没关成功的单独列出来。这个“发指令→等待→验证”的闭环比只看shutdown返回码可靠得多。import subprocess def check_offline(ip): ping 一次返回 True 表示已离线关机成功 # -n 1 发一个包-w 1000 超时 1 秒 result subprocess.run( fping -n 1 -w 1000 {ip}, shellTrue, capture_outputTrue, textTrue ) return result.returncode ! 0ping返回非 0 通常意味着目标不可达结合关机场景可以判定为已关机。但要注意有些机器关机后网卡仍响应 ARPping 可能还通这时以shutdown返回码和事件日志为准。从那以后我每次批量关机前都强制走一遍--dry-run确认列表、确认时间、确认没有漏网的重要机器再真刀真枪执行。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询