How to Query WMI from Linux and Python

Adam Bertram

Adam Bertram

Read more posts by this author.

I’ve recently been playing with Ansible quite a bit and, unfortunately, it’s only available on Linux. Being a big Windows guy, I’ve had to learn a ton about how Linux and Python interact with Windows. My goal was to get my Ubuntu Linux box to simply be able to query a Windows box. Let’s break it down!

My Environment

Ubuntu 14.04

WMIC on Linux

The first task was to query a common WMI class on a Windows box. To do this on Linux, we need to download and compile the WMIC package. To do this, check out this GitHub Gist. For anyone too lazy to click the link, here’s what to run to make it happen.

sudo apt-get install autoconf

## Download to your home folder
cd ~
wget http://www.openvas.org/download/wmi/wmi-1.3.14.tar.bz2 tar -xvf wmi-1.3.14.tar.bz2

## Edit the GNUMakeFile and add a line
cd wmi-1.4.14/ #or whatever version you installed

## Add "ZENHOME=../.." to the GNUMakeFile without the quotes
sudo make "CPP=gcc -E -ffreestanding"

## Make a copy of the wmic binary
cp bin wmic

## Copy the binary to somewhere in your path
sudo cp wmic /usr/bin/

## Test a query to a remote computer
wmic -Utestuser%tstpass //172.16.2.2 "SELECT * FROM Win32_OperatingSystem"

If you see the properties and values of Win32_OperatingSystem you’re good!

WMI in Python

The next step is to get a WMI module for Python. I chose to use the wmi-client-wrapper Python module. To get this installed:

> sudo pip install wmi-client-wrapper

Once installed, create a Python script to test it out. Here’s what mine looked like assuming you have Python 2.x installed. If you have Python 3.x your top line will probably read

#!/usr/bin/python3
#!/usr/bin/python

import wmi_client_wrapper as wmi
wmic = wmi.WmiClientWrapper(username="localaccount",password="localpassword",host="<HostNameOrIpAddress>",)
output = wmic.query("SELECT * FROM Win32_Processor")
print(output)

## Save this as <FileName>.py and mark is as executable:
chmod +x <FileName>.py
## Then, we can execute the script to see if it brings back the Win32_Processor class.

[{'L2CacheSize': '0', 'VMMonitorModeExtensions': False, 'ConfigManagerErrorCode': '0',  'VoltageCaps': '0', 'PowerManagementSupported': False, 'LoadPercentage': '1',  'CreationClassName': 'Win32_Processor', 'Version': '', 'Role': 'CPU', 'CpuStatus': '1',  'SecondLevelAddressTranslationExtensions': False, 'Revision': '11527', 'Status': 'OK',  'PNPDeviceID': None, 'L2CacheSpeed': '0', 'AddressWidth': '64',  'ConfigManagerUserConfig': False, 'ErrorCleared': False, 'ProcessorId': '0F8BFBFF000206D7',  'ProcessorType': '3', 'DeviceID': 'CPU0', 'CurrentVoltage': '12', 'CurrentClockSpeed':  '2600', 'Manufacturer': 'GenuineIntel', 'Name': 'Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz',  'InstallDate': None, 'Level': '6', 'SocketDesignation': 'None', 'NumberOfCores': '1',  'Caption': 'Intel64 Family 6 Model 45 Stepping 7', 'StatusInfo': '3', 'Architecture': '9',  'UniqueId': None, 'PowerManagementCapabilities': 'NULL', 'OtherFamilyDescription': None,  'Description': 'Intel64 Family 6 Model 45 Stepping 7', 'NumberOfLogicalProcessors': '1',  'Family': '179', 'ErrorDescription': None, 'UpgradeMethod': '6', 'SystemName': 'HOSTNAME',  'LastErrorCode': '0', 'ExtClock': '8000', 'Stepping': None,  'VirtualizationFirmwareEnabled': False, 'MaxClockSpeed': '2600', 'L3CacheSize': '0',  'L3CacheSpeed': '0', 'Availability': '3', 'SystemCreationClassName': 'Win32_ComputerSystem',  'DataWidth': '64'}]

Yay! The output is JSON and is pretty gnarly at this point but, for now, I just wanted to get this going. I hope this helps anyone trying to get Python to query WMI on a remote computer on Linux!

Subscribe to Adam the Automator

Get the latest posts delivered right to your inbox

Looks like you're offline!