使用 Python 进行 Windows 系统管理

2024年8月29日 | 阅读 8 分钟

手动管理 Windows 系统管理活动可能会让人筋疲力尽。如果我们不手动管理这些任务,而是设置一些 Python 代码呢?在接下来的教程中,我们将探索一个允许程序基于系统管理执行不同任务的模块。这个 Python 模块称为 WMI 模块。

WMI(Windows Management Instrumentation 的缩写)是微软对通用信息模型(Common Information Model,CMI)的实现,该模型由 DMTF(分布式管理任务组)提出,是一种与供应商无关的、行业标准的管理信息表示方法。它允许程序员在具有适当权限的情况下,从任何执行所需代理的计算机上查询几乎任何数据。

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

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

如何安装 Python wmi 模块?

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

语法

验证安装

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

文件:verify.py

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

语法

如果上述 Python 程序文件未返回任何错误,则模块已正确安装。但是,如果引发异常,请尝试重新安装模块,并且还建议参考模块的官方文档。

建立连接

在以下部分,我们将开始建立与机器的连接。大多数情况下,我们将使用以下 Python 语法连接到本地机器。

语法

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

示例

查找 WMI 类

现在我们已经建立了连接;但是,要查询有关系统的特定信息,我们必须首先找出可以提供该信息的 WMI 类。我们还可以使用 WMI 对象的“classes”属性,例如 wmi.WMI().classes,来返回 WMI 类的列表。

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

示例

输出

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 模块并建立了与本地机器的连接。然后,我们使用 for 循环遍历模块中可用的每个类,从中提取类名。

查找 WMI 类的属性和方法

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

让我们看下面的例子来演示这一点:

示例

输出

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 类的名称,后跟点运算符(.),以及关键字“properties”和“methods”,以打印所有属性和方法供用户使用。

处理进程

由于我们已经收集了关于类 'Win32_Process' 的属性和方法的有关信息,现在我们将使用 WMI 类名称后跟一对开括号和闭括号来返回 WMI 类的对象。

让我们看下面的例子来演示这一点:

示例

输出

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 模块并与本地机器建立了成功的连接。我们使用 for 循环遍历每个进程,并提取了进程 ID、句柄计数和进程名称。

我们还可以根据进程名称和属性过滤这些进程,以仅打印选定的进程。例如,我们想要选择所有名为 'code.exe' 且在本地运行的进程,然后使用条件语句:if<condition> 过滤出句柄计数大于 100 的进程。

让我们考虑以下脚本来理解这一点:

示例

输出

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 模块还允许程序员启动新进程并终止现有进程。

让我们考虑以下示例来演示这一点,其中我们创建了一个新进程,然后存储了进程 ID 以唯一标识该进程,以便稍后可以使用该 ID 来终止它。

示例

说明

在上面的代码片段中,我们导入了 wmi 模块并与本地机器建立了成功的连接。然后,我们使用 Create() 函数启动了一个新进程,并存储了其进程 ID。最后,我们使用 Terminate() 函数来终止该进程。

处理服务

我们可以采用类似的方法来列出和过滤在机器上运行的服务,使用名为 Win32_ServiceWMI 类。

让我们看下面的代码片段来说明这一点:

示例

输出

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 模块并建立了与本地机器的连接。然后,我们使用 for 循环遍历 wmi 模块的 Win32_Services 类,并根据给定条件进行迭代。我们还使用条件语句来过滤出所需的服务。

我们可以使用这些类执行许多其他功能,例如启动和停止服务等等。