最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python腳本實(shí)現(xiàn)自動(dòng)化批量管理Windows終端

 更新時(shí)間:2026年05月07日 08:31:06   作者:紅魔Y  
這篇文中主要介紹了如何利用 Python + WMI + COM 接口,寫出能批量管理 Windows 終端的自動(dòng)化腳本,不需要安裝任何第三方 Agent,純 Windows 原生能力,感興趣的可以了解下

企業(yè) IT 運(yùn)維中,最痛苦的不是技術(shù)難題,而是"同樣的操作要做 1000 遍"。Python 的 WMI 和 COM 接口,就是解決這個(gè)問題的終極武器。

前言

如果你在管理 50 臺(tái)以上的 Windows 終端,大概率遇到過這些場(chǎng)景:

  • 領(lǐng)導(dǎo)說"把全公司電腦的 Office 從 2016 升到 365"
  • 安全審計(jì)要求"統(tǒng)計(jì)所有電腦的殺毒軟件版本和補(bǔ)丁更新情況"
  • 新人入職需要"批量創(chuàng)建 AD 賬號(hào)、分配權(quán)限、配置郵箱"
  • 月底要交一份"全公司硬件資產(chǎn)清單"

手動(dòng)一臺(tái)臺(tái)操作?可能加班到凌晨。用組策略?配置復(fù)雜,靈活性差。

這篇教你用 Python + WMI + COM 接口,寫出能批量管理 Windows 終端的自動(dòng)化腳本。不需要安裝任何第三方 Agent,純 Windows 原生能力。

基礎(chǔ)概念:WMI 和 COM 到底是什么?

WMI(Windows Management Instrumentation)

WMI 是 Windows 內(nèi)置的管理框架,幾乎所有系統(tǒng)信息都可以通過 WMI 查詢:

操作系統(tǒng)版本 → Win32_OperatingSystem
CPU 型號(hào) → Win32_Processor
內(nèi)存容量 → Win32_PhysicalMemory
磁盤分區(qū) → Win32_LogicalDisk
已安裝軟件 → Win32_Product
運(yùn)行中的服務(wù) → Win32_Service

COM(Component Object Model)

COM 是 Windows 的組件通信協(xié)議,通過它可以操控任何支持 COM 接口的應(yīng)用程序——包括 Office 套件、WMI 本身、Windows Shell 等。

import win32com.client

# 通過 COM 連接 WMI
wmi = win32com.client.Dispatch("WbemScripting.SWbemLocator")
service = wmi.ConnectServer(".", "root\\cimv2")

實(shí)戰(zhàn)一:批量收集硬件資產(chǎn)信息

這是 IT 運(yùn)維最高頻的需求——盤點(diǎn)硬件。

import wmi
import json
import socket
from datetime import datetime


def collect_hardware_info():
    """收集本機(jī)硬件信息"""
    c = wmi.WMI()
    hostname = socket.gethostname()

    info = {
        "hostname": hostname,
        "collect_time": datetime.now().isoformat(),
        "os": {},
        "cpu": {},
        "memory": {},
        "disks": [],
        "network": [],
        "software": [],
    }

    # 操作系統(tǒng)信息
    for os_info in c.Win32_OperatingSystem():
        info["os"] = {
            "name": os_info.Caption.strip(),
            "version": os_info.Version,
            "build": os_info.BuildNumber,
            "install_date": os_info.InstallDate[:8] if os_info.InstallDate else "Unknown",
            "last_boot": os_info.LastBootUpTime,
        }

    # CPU 信息
    for cpu in c.Win32_Processor():
        info["cpu"] = {
            "name": cpu.Name.strip(),
            "cores": cpu.NumberOfCores,
            "threads": cpu.NumberOfLogicalProcessors,
            "max_clock": f"{cpu.MaxClockSpeed / 1000:.1f} GHz",
        }
        break  # 通常只需要第一個(gè) CPU

    # 內(nèi)存信息
    total_ram = 0
    for mem in c.Win32_PhysicalMemory():
        total_ram += int(mem.Capacity)
    info["memory"] = {
        "total_gb": round(total_ram / (1024 ** 3), 1),
        "slots": len(list(c.Win32_PhysicalMemory())),
    }

    # 磁盤信息
    for disk in c.Win32_LogicalDisk(DriveType=3):  # 只取本地磁盤
        free_pct = round(int(disk.FreeSpace) / int(disk.Size) * 100, 1)
        info["disks"].append({
            "letter": disk.DeviceID,
            "total_gb": round(int(disk.Size) / (1024 ** 3), 1),
            "free_gb": round(int(disk.FreeSpace) / (1024 ** 3), 1),
            "free_percent": free_pct,
            "filesystem": disk.FileSystem,
        })

    # 網(wǎng)卡信息(只取啟用的)
    for nic in c.Win32_NetworkAdapterConfiguration(IPEnabled=True):
        info["network"].append({
            "description": nic.Description,
            "mac": nic.MACAddress,
            "ip": nic.IPAddress[0] if nic.IPAddress else "N/A",
        })

    return info


if __name__ == "__main__":
    info = collect_hardware_info()
    print(json.dumps(info, indent=2, ensure_ascii=False))

輸出示例:

{
  "hostname": "SH-IT-042",
  "collect_time": "2026-05-06T15:00:00",
  "os": {
    "name": "Microsoft Windows 11 Enterprise",
    "version": "10.0.22631",
    "build": "22631"
  },
  "cpu": {
    "name": "Intel(R) Core(TM) i7-13700",
    "cores": 16,
    "threads": 24,
    "max_clock": "5.4 GHz"
  },
  "memory": {
    "total_gb": 32.0,
    "slots": 2
  },
  "disks": [
    {"letter": "C:", "total_gb": 512.0, "free_gb": 187.3, "free_percent": 36.6}
  ]
}

實(shí)戰(zhàn)二:遠(yuǎn)程查詢多臺(tái)電腦(無需安裝 Agent)

WMI 支持遠(yuǎn)程連接,只要目標(biāo)電腦開啟了 WMI 服務(wù)(默認(rèn)開啟)和 RPC 端口。

import wmi
import socket


def remote_hardware_info(ip, username, password, domain=""):
    """遠(yuǎn)程查詢指定電腦的硬件信息"""
    try:
        # 構(gòu)造連接字符串
        if domain:
            target = f"{domain}\\{username}"
        else:
            target = username

        # 連接遠(yuǎn)程 WMI
        c = wmi.WMI(
            computer=ip,
            user=target,
            password=password,
        )

        result = {"ip": ip, "status": "online"}

        # 快速獲取關(guān)鍵信息
        for os_info in c.Win32_OperatingSystem():
            result["os"] = os_info.Caption.strip()
            result["ram_gb"] = round(int(os_info.TotalVisibleMemorySize) / (1024 ** 2), 1)
            break

        for cpu in c.Win32_Processor():
            result["cpu"] = cpu.Name.strip()
            break

        return result

    except wmi.x_wmi as e:
        if "RPC" in str(e) or "access" in str(e).lower():
            return {"ip": ip, "status": "access_denied", "error": str(e)}
        return {"ip": ip, "status": "offline", "error": str(e)}
    except socket.timeout:
        return {"ip": ip, "status": "timeout"}
    except Exception as e:
        return {"ip": ip, "status": "error", "error": str(e)}


def batch_query(ip_list, username, password, domain="", max_workers=10):
    """批量查詢多臺(tái)電腦"""
    from concurrent.futures import ThreadPoolExecutor, as_completed

    results = []
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {
            executor.submit(remote_hardware_info, ip, username, password, domain): ip
            for ip in ip_list
        }
        for future in as_completed(futures):
            result = future.result()
            results.append(result)
            status_icon = "OK" if result["status"] == "online" else "FAIL"
            print(f"  [{status_icon}] {result['ip']} - {result.get('status', 'unknown')}")

    return results


# 使用示例
if __name__ == "__main__":
    # 從文件讀取 IP 列表
    with open("ip_list.txt") as f:
        ips = [line.strip() for line in f if line.strip()]

    print(f"開始掃描 {len(ips)} 臺(tái)電腦...")
    results = batch_query(ips, "admin", "password123", domain="CORP")

    # 輸出匯總
    online = [r for r in results if r["status"] == "online"]
    print(f"\n結(jié)果: {len(online)}/{len(ips)} 臺(tái)在線")

經(jīng)驗(yàn): 遠(yuǎn)程 WMI 需要目標(biāo)電腦的防火墻放行 135 端口(RPC)和 WMI 動(dòng)態(tài)端口范圍。如果掃描失敗,先檢查防火墻規(guī)則。

實(shí)戰(zhàn)三:用 COM 自動(dòng)化操作 Office

WMI 負(fù)責(zé)讀取系統(tǒng)信息,COM 負(fù)責(zé)操控應(yīng)用程序。運(yùn)維中最常見的 COM 應(yīng)用是 Office 自動(dòng)化。

批量轉(zhuǎn)換 Excel 為 PDF

import win32com.client
import os
from pathlib import Path


def excel_to_pdf(excel_path, pdf_path=None):
    """將 Excel 文件轉(zhuǎn)換為 PDF"""
    if pdf_path is None:
        pdf_path = str(Path(excel_path).with_suffix(".pdf"))

    excel = win32com.client.Dispatch("Excel.Application")
    excel.Visible = False
    excel.DisplayAlerts = False

    try:
        workbook = excel.Workbooks.Open(os.path.abspath(excel_path))

        # 導(dǎo)出為 PDF(0 = xlTypePDF)
        workbook.ExportAsFixedFormat(0, os.path.abspath(pdf_path))
        workbook.Close(False)

        print(f"轉(zhuǎn)換成功: {excel_path} -> {pdf_path}")
        return pdf_path

    except Exception as e:
        print(f"轉(zhuǎn)換失敗: {excel_path} - {e}")
        return None

    finally:
        excel.Quit()


def batch_excel_to_pdf(folder, pattern="*.xlsx"):
    """批量轉(zhuǎn)換文件夾中的所有 Excel 文件"""
    folder = Path(folder)
    files = list(folder.glob(pattern))

    print(f"找到 {len(files)} 個(gè) Excel 文件")

    for f in files:
        excel_to_pdf(str(f))

    print("批量轉(zhuǎn)換完成")


# 使用示例
if __name__ == "__main__":
    batch_excel_to_pdf(r"C:\Reports\Monthly")

通過 COM 發(fā)送 Outlook 郵件(帶附件)

import win32com.client


def send_outlook_email(
    to_addr: str,
    subject: str,
    body: str,
    attachments: list[str] | None = None,
    cc: list[str] | None = None,
):
    """通過 Outlook COM 接口發(fā)送郵件"""
    outlook = win32com.client.Dispatch("Outlook.Application")
    mail = outlook.CreateItem(0)  # 0 = olMailItem

    mail.To = to_addr
    mail.Subject = subject
    mail.BodyFormat = 1  # 1 = olFormatPlain

    # HTML 正文
    mail.HTMLBody = f"""
    <html>
    <body>
        <p>{body.replace(chr(10), '<br>')}</p>
        <hr>
        <p style="color:gray;font-size:11px">
            此郵件由 IT 自動(dòng)化系統(tǒng)發(fā)送,請(qǐng)勿直接回復(fù)。
        </p>
    </body>
    </html>
    """

    if cc:
        mail.CC = ";".join(cc)

    if attachments:
        for att in attachments:
            mail.Attachments.Add(att)

    # mail.Send()  # 直接發(fā)送
    mail.Display()  # 預(yù)覽模式(推薦先預(yù)覽)


# 使用示例:發(fā)送硬件盤點(diǎn)報(bào)告
if __name__ == "__main__":
    send_outlook_email(
        to_addr="manager@company.com",
        subject="2026年5月 硬件資產(chǎn)盤點(diǎn)報(bào)告",
        body="請(qǐng)查收附件中的本月硬件盤點(diǎn)報(bào)告。\n如有問題請(qǐng)聯(lián)系 IT 部門。",
        attachments=[r"C:\Reports\hardware_inventory.xlsx"],
    )

實(shí)戰(zhàn)四:批量管理 Windows 服務(wù)

結(jié)合第一篇講過的服務(wù)管理,加上遠(yuǎn)程能力:

import wmi


def check_remote_service(ip, username, password, service_name):
    """遠(yuǎn)程檢查服務(wù)狀態(tài)"""
    c = wmi.WMI(computer=ip, user=username, password=password)

    for svc in c.Win32_Service(Name=service_name):
        return {
            "name": svc.Name,
            "display_name": svc.DisplayName,
            "state": svc.State,
            "start_mode": svc.StartMode,
            "process_id": svc.ProcessId,
        }
    return None


def batch_check_service(ip_list, username, password, service_name):
    """批量檢查多臺(tái)電腦的服務(wù)狀態(tài)"""
    from concurrent.futures import ThreadPoolExecutor

    def check_one(ip):
        try:
            result = check_remote_service(ip, username, password, service_name)
            if result:
                return {"ip": ip, "status": "ok", **result}
            return {"ip": ip, "status": "service_not_found"}
        except Exception as e:
            return {"ip": ip, "status": "error", "error": str(e)}

    with ThreadPoolExecutor(max_workers=20) as executor:
        results = list(executor.map(check_one, ip_list))

    # 匯總
    running = [r for r in results if r.get("state") == "Running"]
    stopped = [r for r in results if r.get("state") == "Stopped"]
    failed = [r for r in results if r["status"] not in ("ok", "service_not_found")]

    print(f"服務(wù) '{service_name}' 檢查結(jié)果:")
    print(f"  運(yùn)行中: {len(running)} 臺(tái)")
    print(f"  已停止: {len(stopped)} 臺(tái)")
    print(f"  檢查失敗: {len(failed)} 臺(tái)")

    if stopped:
        print("\n已停止的電腦:")
        for r in stopped:
            print(f"  {r['ip']}")

    return results


# 使用示例
if __name__ == "__main__":
    ips = ["192.168.1.101", "192.168.1.102", "192.168.1.103"]
    batch_check_service(ips, "admin", "password", "TermService")  # 檢查遠(yuǎn)程桌面服務(wù)

寫在最后

WMI + COM 是 Windows 運(yùn)維自動(dòng)化的基石,它有兩個(gè)巨大優(yōu)勢(shì):

  1. 零部署成本 —— Windows 自帶,不需要在目標(biāo)電腦上安裝任何東西
  2. 能力全覆蓋 —— 從硬件信息、系統(tǒng)配置到 Office 自動(dòng)化,幾乎無所不能

三個(gè)實(shí)用建議:

  1. 遠(yuǎn)程操作前先測(cè)試連通性 —— ping + telnet 135 確認(rèn) RPC 端口可達(dá)
  2. 用線程池并發(fā) —— 單線程掃描 1000 臺(tái)電腦要幾小時(shí),20 線程只要幾分鐘
  3. 結(jié)果存文件,不要只打印 —— 導(dǎo)出為 CSV/Excel,方便后續(xù)分析和匯報(bào)

到此這篇關(guān)于Python腳本實(shí)現(xiàn)自動(dòng)化批量管理Windows終端的文章就介紹到這了,更多相關(guān)Python管理Windows終端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Flask框架學(xué)習(xí)筆記之模板操作實(shí)例詳解

    Flask框架學(xué)習(xí)筆記之模板操作實(shí)例詳解

    這篇文章主要介紹了Flask框架學(xué)習(xí)筆記之模板操作,結(jié)合實(shí)例形式詳細(xì)分析了flask框架模板引擎Jinja2的模板調(diào)用、模板繼承相關(guān)原理與操作技巧,需要的朋友可以參考下
    2019-08-08
  • pandas數(shù)據(jù)處理之繪圖的實(shí)現(xiàn)

    pandas數(shù)據(jù)處理之繪圖的實(shí)現(xiàn)

    這篇文章主要介紹了pandas數(shù)據(jù)處理之繪圖的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python常用內(nèi)置函數(shù)和關(guān)鍵字使用詳解

    Python常用內(nèi)置函數(shù)和關(guān)鍵字使用詳解

    在Python中有許許多多的內(nèi)置函數(shù)和關(guān)鍵字,它們是我們?nèi)粘V薪?jīng)常可以使用的到的一些基礎(chǔ)的工具,可以方便我們的工作。本文將詳細(xì)講解他們的使用方法,需要的可以參考一下
    2022-05-05
  • django xadmin action兼容自定義model權(quán)限教程

    django xadmin action兼容自定義model權(quán)限教程

    這篇文章主要介紹了django xadmin action兼容自定義model權(quán)限教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Pandas中時(shí)間序列分析的核心功能和實(shí)戰(zhàn)指南

    Pandas中時(shí)間序列分析的核心功能和實(shí)戰(zhàn)指南

    本文介紹了Pandas時(shí)間序列分析的核心功能,包括日期時(shí)間類型轉(zhuǎn)換、日期序列生成、重采樣和滑動(dòng)窗口計(jì)算,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2026-05-05
  • 通過python連接Linux命令行代碼實(shí)例

    通過python連接Linux命令行代碼實(shí)例

    這篇文章主要介紹了通過python連接Linux命令行代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Python將QQ聊天記錄生成詞云的示例代碼

    Python將QQ聊天記錄生成詞云的示例代碼

    這篇文章主要介紹了Python將QQ聊天記錄生成詞云的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Python給Excel寫入數(shù)據(jù)的四種方法小結(jié)

    Python給Excel寫入數(shù)據(jù)的四種方法小結(jié)

    本文主要介紹了Python給Excel寫入數(shù)據(jù)的四種方法小結(jié),包含openpyxl庫(kù)、xlsxwriter庫(kù)、pandas庫(kù)和win32com庫(kù),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • python中time tzset()函數(shù)實(shí)例用法

    python中time tzset()函數(shù)實(shí)例用法

    在本篇文章里小編給大家整理的是一篇關(guān)于python中time tzset()函數(shù)實(shí)例用法內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • ?python中的元類metaclass詳情

    ?python中的元類metaclass詳情

    這篇文章主要介紹了python中的metaclass詳情,在python中的metaclass就是幫助developer實(shí)現(xiàn)元編程,更多詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05

最新評(píng)論

台南县| 洱源县| 南投县| 油尖旺区| 集安市| 白水县| 右玉县| 资中县| 合江县| 华蓥市| 德庆县| 贞丰县| 巩义市| 灵丘县| 剑川县| 铜陵市| 阳曲县| 旺苍县| 龙海市| 玉树县| 广饶县| 桓仁| 乐陵市| 运城市| 天门市| 青海省| 滁州市| 桓仁| 屏山县| 江城| 宜春市| 兴仁县| 孟村| 舟山市| 临武县| 屯门区| 青浦区| 湖口县| 普定县| 长顺县| 建水县|