wmi - a lightweight Python wrapper around Microsoft's WMI interface Windows Management Instrumentation (WMI) is Microsoft's answer to the DMTF's Common Information Model. It allows you to query just about any conceivable piece of information from any computer which is running the necessary agent and over which have you the necessary authority. The implementation is by means of COM/DCOM and most of the examples assume you're running one of Microsoft's scripting technologies. Fortunately, Mark Hammond's pywin32 has pretty much all you need for a workable Python adaptation. I haven't tried any of the fancier stuff like Async calls and so on, so I don't know if they'd work. Since the COM implementation doesn't give much away to Python programmers, I've wrapped it in some lightweight classes with some getattr / setattr magic to ease the way. In particular:
disks = wmi.WMI ().Win32_LogicalDisk ()In addition, you can specify what would become the WHERE clause as keyword parameters:
fixed_disks = wmi.WMI ().Win32_LogicalDisk (DriveType = 3)
for p in wmi.WMI ().Win32_Process (): if p.Name.lower () == 'notepad.exe': p.Terminate (Result=1)
for p in wmi.WMI ().Win32_Process (): if p.Name.lower () == 'notepad.exe': for r in p.references (): print r.Name
process = wmi.WMI ().Win32_Process process.Create (CommandLine="notepad.exe")
import wmi vodev1 = wmi.WMI ("vodev1") for disk in vodev1.Win32_LogicalDisk (): if disk.DriveType == 3: space = 100 * long (disk.FreeSpace) / long (disk.Size) print "%s has %d%% free" % (disk.Name, space)
Helper function to add an attribute directly into the instance dictionary, bypassing possible __getattr__ calls
Currying class to assist in issuing queries against a WMI namespace.
For more information about this class, see The _wmi_class Class.
A currying sort of wrapper around a WMI method name.
For more information about this class, see The _wmi_method Class.
A WMI root of a computer system.
For more information about this class, see The _wmi_namespace Class.
A lightweight wrapper round an OLE WMI object
For more information about this class, see The _wmi_object Class.
Simple, data only result for targeted WMI queries which request data only result classes via fetch_as_classes.
For more information about this class, see The _wmi_result Class.
Helper class for WMI.watch_for below (qv)
For more information about this class, see The _wmi_watcher Class.
The WMI constructor can either take a ready-made moniker or as many parts of one as are necessary. Eg,
c = wmi.WMI (moniker="winmgmts:{impersonationLevel=Delegate}//remote") # or c = wmi.WMI (computer="remote", privileges=["!RemoteShutdown", "Security"])I daren't link to a Microsoft URL; they change so often. Try Googling for WMI construct moniker and see what it comes back with. For complete control, a named argument "wmi" can be supplied, which should be a SWbemServices object, which you create yourself. Eg,
loc = win32com.client.Dispatch("WbemScripting.SWbemLocator") svc = loc.ConnectServer(...) c = wmi.WMI(wmi=svc)This is the only way of connecting to a remote computer with a different username, as the moniker syntax does not allow specification of a user name. If the "wmi" parameter is supplied, all other parameters are ignored.
Return a remote server running WMI server - name of the server namespace - namespace to connect to: defaults to whatever's defined as default user - username to connect as, either local or domain (dom ame or user@domain for XP) password: leave blank to use current context locale: desired locale in form MS_XXXX (eg MS_409 for Am En) authority: either "Kerberos:" or an NT domain. Not needed if included in user security_flags: if 0, connect will wait forever; if 0x80, connect will timeout at 2 mins named_value_set: typically empty, otherwise a context-specific SWbemNamedValueSet
c = wmi.WMI (wmi=wmi.connect_server (server="remote_machine", user="myname", password="mypassword"))
Convenience wrapper to take a series of date/time elements and return a WMI time of the form yyyymmddHHMMSS.mmmmmm+UUU. All elements may be int, string or omitted altogether. If omitted, they will be replaced in the output string by a series of stars of the appropriate length.
Convenience wrapper for displaying all manner of COM errors. Raises a x_wmi exception with more useful information attached
A class which, when called on a win32com.client.Dispatch object, provides lazy access to constants defined in the typelib.
For more information about this class, see The ProvideConstants Class.
Convenience wrapper to take a WMI datetime string of the form yyyymmddHHMMSS.mmmmmm+UUU and return a 9-tuple containing the individual elements, or None where string contains placeholder stars.
Currying class to assist in issuing queries against a WMI namespace. The idea is that when someone issues an otherwise unknown method against the WMI object, if it matches a known WMI class a query object will be returned which may then be called with one or more params which will form the WHERE clause. eg,
c = wmi.WMI () c_drive = c.Win32_LogicalDisk (Name='C:')
Return a list of instances of the WMI class
This is the equivalent to the raw-WMI SpawnInstance_ method. Note that there are relatively few uses for this, certainly fewer than you might imagine. Most classes which need to create a new *real* instance of themselves, eg Win32_Process, offer a .Create method. SpawnInstance_ is generally reserved for instances which are passed as parameters to such .Create methods, a common example being the Win32_SecurityDescriptor, passed to Win32_Share.Create and other instances which need security. The example here is Win32_ProcessStartup, which controls the shown/hidden state etc. of a new Win32_Process instance.
import win32con import wmi c = wmi.WMI () startup = c.Win32_ProcessStartup.new (ShowWindow=win32con.SW_SHOWMINIMIZED) pid, retval = c.Win32_Process.Create ( CommandLine="notepad.exe", ProcessStartupInformation=startup )NB previous versions of this module, used this function to create new process. This is *not* a good example of its use; it is better handled with something like the example above.
Make it slightly easier to query against the class, by calling the namespace's query with the class preset. Won't work if the class has been instantiated directly.
A currying sort of wrapper around a WMI method name. It abstract's the method's parameters and can be called like a normal Python object passing in the parameter values. Output parameters are returned from the call as a tuple. In addition, the docstring is set up as the method's signature, including an indication as to whether any given parameter is expecting an array, and what special privileges are required to call the method.
Execute the call to a WMI method, returning a tuple (even if is of only one value) containing the out and return parameters.
A WMI root of a computer system. The classes attribute holds a list of the classes on offer. This means you can explore a bit with things like this:
c = wmi.WMI () for i in c.classes: if "user" in i.lower (): print i
Offer WMI classes as simple attributes. Pass through any untrapped unattribute to the underlying OLE object. This means that new or unmapped functionality is still available to the module user.
Standard caching helper which keeps track of classes already retrieved by name and returns the existing object if found. If this is the first retrieval, store it and pass it back
Execute a WQL query and return its raw results. Use the flags recommended by Microsoft to achieve a read-only, semi-synchronous query where the time is taken while looping through. Should really be a generator, but ... NB Backslashes need to be doubled up.
Build and execute a wql query to fetch the specified list of fields from the specified wmi_classname + where_clause, then return the results as a list of simple class instances with attributes matching fields_list. If fields is left empty, select * and pre-load all class attributes for each class returned.
Build and execute a wql query to fetch the specified list of fields from the specified wmi_classname + where_clause, then return the results as a list of lists whose values correspond fields_list.
The raw OLE object representing the WMI namespace
Return a list of instances of the WMI class. This is (probably) equivalent to querying with no qualifiers.
system.instances ("Win32_LogicalDisk") # should be the same as system.Win32_LogicalDisk ()
This is now implemented by a call to _wmi_namespace.new (qv)
Perform an arbitrary query against a WMI object, and return a list of _wmi_object representations of the results.
Set up an event tracker on a WMI event. This function returns an wmi_watcher which can be called to get the next event. eg,
c = wmi.WMI () raw_wql = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'" watcher = c.watch_for (raw_wql=raw_wql) while 1: process_created = watcher () print process_created.Name # or watcher = c.watch_for ( notification_type="Creation", wmi_class="Win32_Process", delay_secs=2, Name='calc.exe' ) calc_created = watcher ()Now supports timeout on the call to watcher, eg:
import pythoncom import wmi c = wmi.WMI (privileges=["Security"]) watcher1 = c.watch_for ( notification_type="Creation", wmi_class="Win32_NTLogEvent", Type="error" ) watcher2 = c.watch_for ( notification_type="Creation", wmi_class="Win32_NTLogEvent", Type="warning" ) while 1: try: error_log = watcher1 (500) except wmi.x_wmi_timed_out: pythoncom.PumpWaitingMessages () else: print error_log try: warning_log = watcher2 (500) except wmi.x_wmi_timed_out: pythoncom.PumpWaitingMessages () else: print warning_log
A lightweight wrapper round an OLE WMI object
Use WMI's CompareTo_ to compare this object with another. Don't try to do anything if the other object is not a wmi object. It might be possible to compare this object's unique key with a string or something, but this doesn't seem to be universal enough to merit a special case.
Attempt to pass attribute calls to the proxied COM object. If the attribute is recognised as a property, return its value; if it is recognised as a method, return a method wrapper which can then be called with parameters; otherwise pass the lookup on to the underlying object.
Indicate both the fact that this is a wrapped WMI object and the WMI object's own identifying class.
If the attribute to be set is valid for the proxied COM object, set that objects's parameter value; if not, raise an exception.
For a call to print [object] return the OLE description of the properties / values of the object
Return a list of objects related to this one, optionally limited either by association class (ie the name of the class which relates them) or by result class (ie the name of the class which would be retrieved)
c = wmi.WMI () pp = c.Win32_ParallelPort ()[0] for i in pp.associators (wmi_association_class="Win32_PortResource"): print i for i in pp.associators (wmi_result_class="Win32_PnPEntity"): print i
Return a tuple representing the object derivation for this object, with the most specific object first. eg, pp0 = wmi.WMI ().Win32_ParallelPort ()[0] print ' <- '.join (pp0.derivation ())
Return the WMI URI to this object. Can be used to determine the path relative to the parent namespace. eg,
pp0 = wmi.WMI ().Win32_ParallelPort ()[0] print pp0.path ().RelPath
Return a list of associations involving this object, optionally limited by the result class (the name of the association class). NB Associations are treated specially; although WMI only returns the string corresponding to the instance of each associated object, this module will automatically convert that to the object itself.
c = wmi.WMI () sp = c.Win32_SerialPort ()[0] for i in sp.references (): print i for i in sp.references (wmi_class="Win32_SerialPortSetting"): print i
Set several properties of the underlying object at one go. This is particularly useful in combination with the new () method below. However, an instance which has been spawned in this way won't have enough information to write pack, so only try if the instance has a path.
Simple, data only result for targeted WMI queries which request data only result classes via fetch_as_classes.
Helper class for WMI.watch_for below (qv)
When called, return the instance which caused the event. Supports timeout in milliseconds (defaulting to infinite). If the watcher times out, x_wmi_timed_out is raised. This makes it easy to support watching for multiple objects.
A class which, when called on a win32com.client.Dispatch object, provides lazy access to constants defined in the typelib. They can be accessed as attributes of the _constants property. From Thomas Heller on c.l.py