Windows System Administration Management using Python
Managing the activities of Windows System Administration manually can be exhausting. What if we could set up a few Python codes instead of managing these tasks manually. In the following tutorial, we will discover one such module that allows the program to perform different processes based on System Administration. This Python module is known as the WMI module.
WMI, abbreviated for Windows Management Instrumentation, is an implementation of Microsoft to the Common Information Model (short for CMI) for the DMTF, which is a vendor-neutral, industry-standard method of demonstrating the Management Information. It allows the programmers to query almost any piece of data from any computer executing the required agent with the appropriate permissions.
Python offers the wmi module that acts as a lightweight wrapper around available WMI classes and functionalities and could be utilized by the Systems Administrators in order to query data from the local or remote Windows machines.
In this tutorial, we will understand how to use the wmi module to perform various activities based on Windows System Administration. But before we get to it, let us begin by installing the required module.
How to Install the Python wmi Module?
In order to install the Python module, we need 'pip', a framework to manage packages required to install the modules from the trusted public repositories. Once we have 'pip', we can install the wmi module using the command from a Windows command prompt (CMD) or terminal as shown below:
Verifying the Installation
Once the module is installed, we can verify it by creating an empty Python program file and writing an import statement as follows:
Now, save the above file and execute it using the following command in a terminal:
If the above Python program file does not return any error, the module is installed properly. However, in the case where an exception is raised, try reinstalling the module, and it is also recommended to refer to the official documentation of the module.
Establishing a Connection
In the following section, we will begin by establishing a connection to a machine. Most of the time, we will connect to the local machine with the help of the following Python syntax:
Suppose we want to connect to a remote machine. In that case, we must provide a machine name (or IP Address) and use the following parameters such as 'user' and 'password' to pass the credentials so that we can authenticate the account to establish a remote WMI connection.
Finding a WMI Class
Now we have the connection established; however, to query specific information regarding the system, we must first find out the WMI class that can deliver that information. We can also use the 'classes' property of WMI objects such as wmi.WMI().classes, in order to return the list of WMI classes.
From these extracted classes, we can filter out particular keywords to find a specific class we are looking for, as shown in the following example:
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
In the above snippet of code, we have imported the wmi module and established a connection to the local machine. We have then extracted the class names from the wmi module using the for-loop iterating through each class available in the module.
Finding Methods and Properties of WMI Class
Even if we know the name of WMI Class, we will still need the precise name of the property these classes provide and methods that can carry out particular operations. In order to retrieve methods and properties of an as specific WMI class, we can create a WMI connection and utilize the Dot operator (.) and 'Class Name' in order to access namespace, then 'properties' or 'methods' attribute to return a Python List of property/method names.
Let us consider the following example demonstrating the same:
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'])
In the above snippet of code, we have imported the required module. We have then used the WMI() to establish a connection with a remote machine. We have then written the name of the WMI class followed by the Dot operator (.) along with the keywords 'properties' and 'methods' to print all the properties and methods for the users.
Since we have gathered the information regarding the methods and properties of class 'Win32_Process', we will now use the class name of WMI followed by an open & close parenthesis in order to return objects of the WMI class.
Let us consider the following example demonstrating the same:
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
In the above snippet of code, we have imported the wmi module and established a successful connection with the local machine. We extracted the process list using the for-loop iterating through each process with their ID, Handle Count, and Name of the process.
We can also filter these processes with their names and properties to print only selected processes (es). For example, we wanted to select all the processes named as 'code.exe' that are running locally and then filtered out the processes that have to handle count more than 100 with the help of a conditional statement: if<condition>
Let us consider the following script to understand the same:
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
In the above snippet of code, we have again imported the wmi module and established the connection with a local machine. We have then used the for-loop to iterate through the processes in the WMI class and specified the name of the process to filter out that required process. We have also included the if conditional statement in order to print those processes details only whose Handle Counts is more than 100.
WMI Module also allows programmers to begin a new process and kill any existing one.
Let us consider the following example demonstrating the same where we have created a new process then stored the Process ID to uniquely identify the process so that we can terminate it later using that ID:
In the above snippet of code, we have imported the wmi module and established a successful connection with the local machine. We have then started a new process using the Create() function and stored its process ID. At last, we have used the Terminate() function to kill the process.
We can adapt a similar approach in order to list and filter out services working on a machine with the help of the WMI class called Win32_Service.
Let us consider the following snippet of code demonstrating the same:
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
In the above snippet of code, we have imported the wmi module and established the connection with a local machine. We have then used the for-loop to iterate through the Win32_Services class of the wmi module over the given conditions. We have also used the conditional statement to filter out the required services.
We can perform several other functionalities with these classes, such as starting and stopping service and a lot more.