Sunday, July 8, 2007

Using Ruby & WMI to Get Win32 Process Information

In an earlier post, we looked at using Windows Management Instrumentation (WMI) to determine if a "USB Mass Storage Device" is inserted. Today we'll use WMI to get information about the Win32 processes being run.

WMI is installed and already running on all recent versions of Windows, so we'll connect to it using the win32ole library's connect method:


require 'win32ole'
wmi = WIN32OLE.connect("winmgmts://")

Next, we'll call WMI's ExecQuery method to query the Win32_Process table:

processes = wmi.ExecQuery("select * from win32_process")

This returns a collection of all WMI Win32_Process objects.

The Win32_Process class has dozens of properties. You can find a complete list of those properties here. You could also produce a list of these properties by calling the Properties_ method (note the underscore) on one of the Win32_Process objects. This returns a collection of Properties; then call the Name method/property for each of these Property objects. For example:

for process in processes do
for property in process.Properties_ do
puts property.Name
end
break
end

To obtain data about a process, call that Process object's relevant property/method. For example, the following code prints four properties for each process:

for process in processes do
puts "Name: #{process.Name}"
puts "CommandLine: #{process.CommandLine}"
puts "CreationDate: #{process.CreationDate}"
puts "WorkingSetSize: #{process.WorkingSetSize}"
puts
end

That's all for now. Got a question or suggestion? Post a comment or send me email.

Thanks for stopping by!

Digg my article

6 comments:

Daniel Berger said...

The approach you use there is what sys-proctable does on Windows behind the scenes. :)

GimbalGambit said...

David,

Thanks so much for your (excellent) tutorials... I've been messing with WMI to get remote server status data for a reporting system, and have had troubles using the WIN32OLE.connect(...) method as well as the WIN32OLE.new("WbemScripting.SWbemLocator").ConnectServer(...) method.

Do you have any advice on how to pass credentials to a remote host for this? If the script is executed as a domain user that is in the Administrator's group on the remote server, shouldn't it work?

Is there a special server-configuration change that needs to be made to allow remote requests?

Thanks!

-Warren

GimbalGambit said...

Oh, I figured it out! For anyone else who is struggling:

[code]
objWMI = WIN32OLE.new("WbemScripting.SWbemLocator")
connection = objWMI.ConnectServer("server", "root\\cimv2", "domain\\username", "password")

connection.InstancesOf('Win32_LogicalDisk').each do |disk|
puts disk.Description
end

[/code]

Works!

Anonymous said...

Great tutorial! I'm just starting to use ruby on windows for some system administration tasks and so I'm finding the many code examples on your blog very instructive. Thanks for sharing them.

For learning more about wmi, I've also found the scriptomatic tool very useful:
http://www.microsoft.com/technet/scriptcenter/tools/scripto2.mspx

Roger Pack said...

definitely check out ruby-wmi gem for easy queries :)

http://wiki.github.com/rdp/ruby_tutorials_any_gem/ruby-wmi

Anonymous said...

Very good job man!