您的位置:

Python Windows 系统管理

手动管理 Windows 系统管理的活动可能会很累。如果我们可以设置一些 Python 代码,而不是手动管理这些任务,会怎么样。在下面的教程中,我们将发现一个这样的模块,它允许程序基于系统管理执行不同的过程。这个 Python 模块被称为 WMI 模块。

WMI ,Windows Management Instrumentation 的缩写,是微软对 DMTF 通用信息模型(CMI 的简称)的实现,这是一种展示管理信息的供应商中立的行业标准方法。它允许程序员以适当的权限从执行所需代理的任何计算机上查询几乎任何数据。

Python 提供了 wmi 模块,它充当了可用的 WMI 类和功能的轻量级包装器,系统管理员可以使用它来查询本地或远程 Windows 机器的数据。

在本教程中,我们将了解如何使用 wmi 模块执行基于 Windows 系统管理的各种活动。但是在开始之前,让我们先安装所需的模块。

如何安装 Python wmi 模块?

为了安装 Python 模块,我们需要“ pip ”,这是一个管理从可信公共存储库中安装模块所需的包的框架。一旦我们有了“ pip ”,我们就可以使用来自 Windows 命令提示符(CMD)或终端的命令安装 wmi 模块,如下所示:

语法:


$ python.exe -m pip install wmi

验证安装

一旦模块安装完成,我们可以通过创建一个空的 Python 程序文件并编写一个 import 语句来验证它,如下所示:

文件:验证. py


import wmi

现在,保存上述文件,并在终端中使用以下命令执行它:

语法:


$ python verify.py

如果上述 Python 程序文件没有返回任何错误,则模块安装正确。但是,在出现异常的情况下,请尝试重新安装该模块,并且还建议参考该模块的官方文档。

建立连接

在下一节中,我们将从建立与机器的连接开始。大多数情况下,我们将借助以下 Python 语法连接到本地机器:

语法:


# connecting to local machine
my_connection = wmi.WMI()

假设我们想要连接到远程机器。在这种情况下,我们必须提供一个机器名称(或 IP 地址),并使用以下参数,如“用户”和“密码”来传递凭据,以便我们可以验证帐户以建立远程 WMI 连接。

示例:


# importing the required module
import wmi

# connecting to a remote machine
my_connection = wmi.WMI("13.78.128.231", user = r"mango", password = "mango@123")

寻找 WMI 班

现在我们已经建立了联系;但是,要查询关于系统的特定信息,我们必须首先找到能够传递该信息的 WMI 类。我们也可以使用 WMI 物体的类属性,比如 wmi。WMI()。班级,为了归还 WMI 班级的名单。

从这些提取的类中,我们可以过滤出特定的关键字来找到我们正在寻找的特定类,如下例所示:

示例:


# importing the required module
import wmi

# connecting to a local machine
my_connection = wmi.WMI()

# extracting the class names from WMI
for className in my_connection.classes:
    if 'Process' in className:
        print(className)

输出:

Win32_ProcessStartTrace
Win32_PerfFormattedData_PerfOS_Processor
Win32_PerfFormattedData_PerfProc_Process
Win32_SessionProcess
Win32_PerfRawData_PerfProc_Process
Win32_PerfRawData_Counters_PerProcessorNetworkInterfaceCardActivity
Win32_PerfRawData_LSM_UserInputDelayperProcess
Win32_PerfFormattedData_Counters_ProcessV2
Win32_PerfFormattedData_LSM_UserInputDelayperProcess
Win32_PerfFormattedData_Counters_PerProcessorNetworkInterfaceCardActivity
Win32_Processor
Win32_ProcessTrace
CIM_OSProcess
CIM_ProcessExecutable
CIM_Processor
CIM_AssociatedProcessorMemory
Win32_ComputerSystemProcessor
Win32_PerfFormattedData_GPUPerformanceCounters_GPUProcessMemory
Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor
Win32_PerfFormattedData_Counters_ProcessorInformation
CIM_ProcessThread
CIM_Process
Win32_PerfFormattedData_Counters_PerProcessorNetworkActivityCycles
Win32_AssociatedProcessorMemory
Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
Win32_PerfFormattedData_Counters_SecurityPerProcessStatistics
Win32_ProcessStartup
Win32_PerfRawData_GPUPerformanceCounters_GPUProcessMemory
Win32_PerfRawData_Counters_ProcessorInformation
Win32_PerfRawData_Counters_ProcessV2
Win32_PerfRawData_Counters_PerProcessorNetworkActivityCycles
Win32_PerfRawData_Counters_SecurityPerProcessStatistics
Win32_PerfFormattedData_HvStats_HyperVHypervisorLogicalProcessor
Win32_Process
Win32_PerfFormattedData_HvStats_HyperVHypervisorRootVirtualProcessor
Win32_NamedJobObjectProcess
Win32_SystemProcesses
Win32_ProcessStopTrace
Win32_PerfRawData_PerfOS_Processor

说明:

在上面的代码片段中,我们已经导入了 wmi 模块,并与本地机器建立了连接。然后我们从 wmi 模块中提取类名,使用进行循环迭代模块中的每个可用类。

WMI 类的发现方法和性质

即使我们知道 WMI 类的名称,我们仍然需要这些类提供的属性的精确名称和能够执行特定操作的方法。为了检索 as 特定的 WMI 类的方法和属性,我们可以创建一个 WMI 连接并使用点运算符(。)和“类名”来访问命名空间,然后使用“属性或“方法属性来返回属性/方法名称的 Python 列表。

让我们考虑下面的例子来证明这一点:

示例:


# importing the wmi module
import wmi
# printing all properties
print("Properties of WMI class:")
print(wmi.WMI().Win32_Process.methods.keys())

# printing all methods
print("\nMethods of WMI class:")
print(wmi.WMI().Win32_Process.properties.keys())

输出:

Properties of WMI class:
dict_keys(['Create', 'Terminate', 'GetOwner', 'GetOwnerSid', 'SetPriority', 'AttachDebugger', 'GetAvailableVirtualSize'])

Methods of WMI class:
dict_keys(['Caption', 'CommandLine', 'CreationClassName', 'CreationDate', 'CSCreationClassName', 'CSName', 'Description', 'ExecutablePath', 'ExecutionState', 'Handle', 'HandleCount', 'InstallDate', 'KernelModeTime', 'MaximumWorkingSetSize', 'MinimumWorkingSetSize', 'Name', 'OSCreationClassName', 'OSName', 'OtherOperationCount', 'OtherTransferCount', 'PageFaults', 'PageFileUsage', 'ParentProcessId', 'PeakPageFileUsage', 'PeakVirtualSize', 'PeakWorkingSetSize', 'Priority', 'PrivatePageCount', 'ProcessId', 'QuotaNonPagedPoolUsage', 'QuotaPagedPoolUsage', 'QuotaPeakNonPagedPoolUsage', 'QuotaPeakPagedPoolUsage', 'ReadOperationCount', 'ReadTransferCount', 'SessionId', 'Status', 'TerminationDate', 'ThreadCount', 'UserModeTime', 'VirtualSize', 'WindowsVersion', 'WorkingSetSize', 'WriteOperationCount', 'WriteTransferCount'])

说明:

在上面的代码片段中,我们已经导入了所需的模块。然后,我们使用 WMI() 与远程机器建立连接。然后我们写了 WMI 类的名字,后跟点运算符(。)连同关键字“属性”和“方法”一起为用户打印所有属性和方法。

处理过程

由于我们已经收集了关于类“ Win32_Process ”的方法和属性的信息,我们现在将使用 WMI 的类名,后跟一个开&右括号,以便返回 WMI 类的对象。

让我们考虑下面的例子来证明这一点:

示例:


# importing the wmi module
import wmi
# establishing the connection with a local machine
my_connection = wmi.WMI()
# processing list
for process in my_connection.Win32_Process():
    print("ID: {0}\nHandle Count: {1}\nProcess Name: {2}\n".format(
        process.ProcessId, process.HandleCount, process.Name
        )
    )

输出:

ID: 0
Handle Count: 0
Process Name: System Idle Process

ID: 4
Handle Count: 5863
Process Name: System

ID: 160
Handle Count: 0
Process Name: Registry

ID: 540
Handle Count: 57
Process Name: smss.exe

ID: 788
Handle Count: 773
Process Name: csrss.exe

ID: 892
Handle Count: 149
Process Name: wininit.exe

ID: 912
Handle Count: 765
Process Name: csrss.exe

ID: 964
Handle Count: 714
Process Name: services.exe

ID: 984
Handle Count: 1571
Process Name: lsass.exe

ID: 568
Handle Count: 267
Process Name: winlogon.exe

ID: 1056
Handle Count: 1746
Process Name: svchost.exe

ID: 1084
Handle Count: 33
Process Name: fontdrvhost.exe
.
.
.
ID: 14104
Handle Count: 301
Process Name: python3.9.exe

说明:

在上面的代码片段中,我们已经导入了 wmi 模块,并与本地机器建立了成功的连接。我们使用的来提取流程列表——循环迭代每个流程及其标识、句柄计数和流程名称。

我们还可以用进程的名称和属性过滤这些进程,只打印选定的进程。例如,我们希望选择本地运行的名为“code.exe”的所有进程,然后借助条件语句过滤掉必须处理计数超过 100 的进程: if < condition >

让我们考虑以下脚本来理解相同的内容:

示例:


# importing the wmi module
import wmi
# establishing the connection with a local machine
my_connection = wmi.WMI()
# filtering specific processes
for process in my_connection.Win32_Process(name = "code.exe"): 
    if process.HandleCount > 100:
        # only processes with Handle Count above 100
        print("ID: {0}\nHandle Count: {1}\nProcess Name: {2}\n".format(
            process.ProcessId, process.HandleCount, process.Name
            )
        )

输出:

ID: 10464
Handle Count: 859
Process Name: Code.exe

ID: 14796
Handle Count: 228
Process Name: Code.exe

ID: 12388
Handle Count: 704
Process Name: Code.exe

ID: 2504
Handle Count: 284
Process Name: Code.exe

ID: 1044
Handle Count: 485
Process Name: Code.exe

ID: 12668
Handle Count: 334
Process Name: Code.exe

ID: 8088
Handle Count: 362
Process Name: Code.exe

ID: 10720
Handle Count: 180
Process Name: Code.exe

ID: 8976
Handle Count: 210
Process Name: Code.exe

ID: 14804
Handle Count: 278
Process Name: Code.exe

说明:

在上面的代码片段中,我们再次导入了 wmi 模块,并与本地机器建立了连接。然后,我们使用for-循环来遍历 WMI 类中的流程,并指定流程的名称来过滤掉所需的流程。我们还包括 if 条件语句,以便仅打印那些处理计数大于 100 的过程细节。

WMI 模块还允许程序员开始一个新的过程,并杀死任何现有的过程。

让我们考虑下面的示例,演示我们已经创建了一个新流程,然后存储流程标识来唯一标识该流程,以便我们以后可以使用该标识终止它:

示例:


# importing the wmi module
import wmi
# establishing the connection with the local machine
my_connection = wmi.WMI()

# starting a new process and capturing the process ID
process_id, return_val = my_connection.Win32_Process.Create(CommandLine = "notepad.exe")

# killing the process using process ID
my_connection.Win32_Process(ProcessId = process_id)[0].Terminate()

说明:

在上面的代码片段中,我们已经导入了 wmi 模块,并与本地机器建立了成功的连接。然后,我们使用创建()功能启动了一个新的进程,并存储了它的进程标识。最后,我们使用了终止()功能来终止进程。

搬运服务

我们可以采用类似的方法,在名为 Win32_Service 的 WMI 类的帮助下,列出并过滤出在机器上工作的服务。

让我们考虑下面的代码片段来证明这一点:

示例:


# importing the wmi module
import wmi
# establishing connection with a local machine
my_connection = wmi.WMI()
# listing services
for service in my_connection.Win32_Service(StartMode = "Auto", State = "Running"):
    # filtering the service names
    if 'Windows' in service.DisplayName:
        print("Status: {0} \nStart Mode: {1} \nService Name: {2} \nDisplay Name: {3} \n\n".format(
            service.State, service.StartMode, service.Name, service.DisplayName
            )
        )

输出:

Status: Running 
Start Mode: Auto
Service Name: AudioEndpointBuilder
Display Name: Windows Audio Endpoint Builder

Status: Running
Start Mode: Auto
Service Name: Audiosrv
Display Name: Windows Audio

Status: Running 
Start Mode: Auto
Service Name: EventLog
Display Name: Windows Event Log

Status: Running 
Start Mode: Auto
Service Name: FontCache
Display Name: Windows Font Cache Service

Status: Running 
Start Mode: Auto
Service Name: mpssvc
Display Name: Windows Defender Firewall

Status: Running 
Start Mode: Auto
Service Name: StiSvc
Display Name: Windows Image Acquisition (WIA)

Status: Running 
Start Mode: Auto
Service Name: Wcmsvc
Display Name: Windows Connection Manager

Status: Running
Start Mode: Auto
Service Name: Winmgmt
Display Name: Windows Management Instrumentation

Status: Running 
Start Mode: Auto
Service Name: WpnService
Display Name: Windows Push Notifications System Service

Status: Running 
Start Mode: Auto
Service Name: WSearch
Display Name: Windows Search

Status: Running 
Start Mode: Auto
Service Name: WpnUserService_a17f9
Display Name: Windows Push Notifications User Service_a17f9

说明:

在上面的代码片段中,我们已经导入了 wmi 模块,并与本地机器建立了连接。然后,我们使用的循环在给定条件下遍历 wmi 模块的 Win32_Services 类。我们还使用了条件语句来过滤掉所需的服务。

我们可以用这些类执行其他几个功能,比如启动和停止服务等等。