rdp-ruby-wmi 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +44 -0
- data/Manifest.txt +14 -0
- data/README.txt +66 -0
- data/Rakefile +17 -0
- data/VERSION +1 -0
- data/lib/ruby-wmi.rb +6 -0
- data/lib/ruby-wmi/base.rb +213 -0
- data/lib/ruby-wmi/constants.rb +94 -0
- data/lib/ruby-wmi/core_ext.rb +1 -0
- data/lib/ruby-wmi/core_ext/time_ext.rb +9 -0
- data/lib/ruby-wmi/core_ext/win32ole_ext.rb +11 -0
- data/samples/disk.rb +9 -0
- data/samples/disk2.rb +5 -0
- data/samples/logoff.rb +8 -0
- data/samples/memory.rb +11 -0
- data/test/test_ruby-wmi.rb +2 -0
- data/web/public/css/active4d.css +114 -0
- data/web/public/css/all_hallows_eve.css +72 -0
- data/web/public/css/amy.css +147 -0
- data/web/public/css/blackboard.css +88 -0
- data/web/public/css/brilliance_black.css +605 -0
- data/web/public/css/brilliance_dull.css +599 -0
- data/web/public/css/cobalt.css +149 -0
- data/web/public/css/dawn.css +121 -0
- data/web/public/css/eiffel.css +121 -0
- data/web/public/css/espresso_libre.css +109 -0
- data/web/public/css/idle.css +62 -0
- data/web/public/css/iplastic.css +80 -0
- data/web/public/css/lazy.css +73 -0
- data/web/public/css/mac_classic.css +123 -0
- data/web/public/css/magicwb_amiga.css +104 -0
- data/web/public/css/pastels_on_dark.css +188 -0
- data/web/public/css/rspec.css +118 -0
- data/web/public/css/slush_poppies.css +85 -0
- data/web/public/css/spacecadet.css +51 -0
- data/web/public/css/sunburst.css +180 -0
- data/web/public/css/toader.css +285 -0
- data/web/public/css/twilight.css +137 -0
- data/web/public/css/zenburnesque.css +91 -0
- data/web/public/images/bg.gif +0 -0
- data/web/public/images/bullet.gif +0 -0
- data/web/public/images/footer_pic.gif +0 -0
- data/web/public/images/green_vr.gif +0 -0
- data/web/public/images/hr.gif +0 -0
- data/web/public/images/main.gif +0 -0
- data/web/public/images/nav_over.gif +0 -0
- data/web/public/images/nav_over_left.gif +0 -0
- data/web/public/images/nav_over_right.gif +0 -0
- data/web/public/images/nav_under.gif +0 -0
- data/web/public/images/your-face.gif +0 -0
- data/web/public/images/your-picture.gif +0 -0
- data/web/templates/index.html.erb +76 -0
- data/web/templates/template-1109.zip +0 -0
- metadata +178 -0
data/History.txt
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
== 0.3.0 / 2008-04-30
|
2
|
+
|
3
|
+
* 2 major enhancements
|
4
|
+
* added #all, #first, and #last methods as aliases for
|
5
|
+
#find(:all), #find(:first), and #find(:last)
|
6
|
+
* added #set_wmi_class_name method, similar to ActiveRecord's #set_table_name
|
7
|
+
|
8
|
+
This allows you to create models with names you like.
|
9
|
+
|
10
|
+
<code>
|
11
|
+
class Disk < WMI::Base
|
12
|
+
set_wmi_class_name "Win32_LogicalDisk"
|
13
|
+
end
|
14
|
+
|
15
|
+
disks = Disk.all
|
16
|
+
</code>
|
17
|
+
|
18
|
+
|
19
|
+
== 0.2.2 / 2008-01-11
|
20
|
+
|
21
|
+
* 1 major enhancement
|
22
|
+
* supports privileges
|
23
|
+
<code>
|
24
|
+
events = WMI::Win32_NTLogEvent.find(
|
25
|
+
:all,
|
26
|
+
:privileges => [WMI::Privilege::Security],
|
27
|
+
:conditions => {:logfile => 'Security', :eventcode => '517'} )
|
28
|
+
</code>
|
29
|
+
* minor enhancements
|
30
|
+
* added error handling for invalid queries and class name typos
|
31
|
+
* better documentation
|
32
|
+
|
33
|
+
== 0.2.1 / 2007-07-19
|
34
|
+
|
35
|
+
* minor enhancements
|
36
|
+
* fixed version numbers
|
37
|
+
* fixed sample code
|
38
|
+
|
39
|
+
|
40
|
+
== 0.2.0 / 2007-07-19
|
41
|
+
|
42
|
+
* 1 major enhancement
|
43
|
+
* Birthday!
|
44
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/ruby-wmi.rb
|
6
|
+
lib/ruby-wmi/base.rb
|
7
|
+
lib/ruby-wmi/constants.rb
|
8
|
+
lib/ruby-wmi/core_ext.rb
|
9
|
+
lib/ruby-wmi/core_ext/time_ext.rb
|
10
|
+
lib/ruby-wmi/core_ext/win32ole_ext.rb
|
11
|
+
samples/disk.rb
|
12
|
+
samples/logoff.rb
|
13
|
+
samples/memory.rb
|
14
|
+
test/test_ruby-wmi.rb
|
data/README.txt
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
ruby-wmi
|
2
|
+
by Gordon Thiesfeld
|
3
|
+
http://ruby-wmi.rubyforge.org/
|
4
|
+
gthiesfeld@gmail.com
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
ruby-wmi is an ActiveRecord style interface for Microsoft's Windows
|
9
|
+
Management Instrumentation provider.
|
10
|
+
|
11
|
+
Many of the methods in WMI::Base are borrowed directly, or with some
|
12
|
+
modification from ActiveRecord.
|
13
|
+
http://api.rubyonrails.org/classes/ActiveRecord/Base.html
|
14
|
+
|
15
|
+
The major tool in this library is the #find method. For more
|
16
|
+
information, see WMI::Base.
|
17
|
+
|
18
|
+
There is also a WMI.sublasses method included for reflection.
|
19
|
+
|
20
|
+
== SYNOPSIS:
|
21
|
+
|
22
|
+
# The following code sample kills all processes of a given name
|
23
|
+
# (in this case, Notepad), except the oldest.
|
24
|
+
|
25
|
+
require 'ruby-wmi'
|
26
|
+
|
27
|
+
procs = WMI::Win32_Process.find(:all,
|
28
|
+
:conditions => { :name => 'Notepad.exe' }
|
29
|
+
)
|
30
|
+
morituri = procs.sort_by{|p| p.CreationDate } #those who are about to die
|
31
|
+
morituri.shift
|
32
|
+
morituri.each{|p| p.terminate }
|
33
|
+
|
34
|
+
== REQUIREMENTS:
|
35
|
+
|
36
|
+
Windows 2000 or newer
|
37
|
+
Ruby 1.8
|
38
|
+
|
39
|
+
== INSTALL:
|
40
|
+
|
41
|
+
gem install ruby-wmi
|
42
|
+
|
43
|
+
== LICENSE:
|
44
|
+
|
45
|
+
(The MIT License)
|
46
|
+
|
47
|
+
Copyright (c) 2007 Gordon Thiesfeld
|
48
|
+
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
50
|
+
a copy of this software and associated documentation files (the
|
51
|
+
'Software'), to deal in the Software without restriction, including
|
52
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
53
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
54
|
+
permit persons to whom the Software is furnished to do so, subject to
|
55
|
+
the following conditions:
|
56
|
+
|
57
|
+
The above copyright notice and this permission notice shall be
|
58
|
+
included in all copies or substantial portions of the Software.
|
59
|
+
|
60
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
61
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
62
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
63
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
64
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
65
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
66
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jeweler'
|
3
|
+
|
4
|
+
Jeweler::Tasks.new do |p|
|
5
|
+
p.name = 'rdp-ruby-wmi'
|
6
|
+
p.summary = 'WMI queries, easier'
|
7
|
+
p.author = 'Gordon Thiesfeld'
|
8
|
+
p.email = 'gthiesfeld@gmail.com'
|
9
|
+
p.summary = "ruby-wmi is an ActiveRecord style interface for Microsoft\'s Windows Management Instrumentation provider."
|
10
|
+
p.description = File.read 'README.txt'
|
11
|
+
p.rdoc_options = ['--title' , p.name ,
|
12
|
+
'--main' , 'README.txt' ,
|
13
|
+
'--line-numbers']
|
14
|
+
|
15
|
+
p.homepage = 'http://rubyforge.org/projects/ruby-wmi/'
|
16
|
+
|
17
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.1
|
data/lib/ruby-wmi.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'win32ole'
|
2
|
+
|
3
|
+
module WMI
|
4
|
+
|
5
|
+
# Generic WMI exception class.
|
6
|
+
class WMIError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
# Invalid Class exception class.
|
10
|
+
class InvalidClass < WMIError
|
11
|
+
end
|
12
|
+
|
13
|
+
# Invalid Query exception class.
|
14
|
+
class InvalidQuery < WMIError
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns an array conating all the WMI subclasses
|
18
|
+
# on a sytem. Defaults to localhost
|
19
|
+
#
|
20
|
+
# WMI.subclasses
|
21
|
+
# => ["Win32_PrivilegesStatus", "Win32_TSNetworkAdapterSettingError", ...]
|
22
|
+
#
|
23
|
+
# For a more human readable version of subclasses when using options:
|
24
|
+
#
|
25
|
+
# WMI.subclasses_of(:host => some_computer)
|
26
|
+
# => ["Win32_PrivilegesStatus", "Win32_TSNetworkAdapterSettingError", ...]
|
27
|
+
def subclasses(options ={})
|
28
|
+
Base.set_connection(options)
|
29
|
+
b = Base.send(:connection)
|
30
|
+
b.SubclassesOf.map { |subclass| class_name = subclass.Path_.Class }
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
alias :subclasses_of :subclasses
|
35
|
+
|
36
|
+
extend self
|
37
|
+
|
38
|
+
class Base
|
39
|
+
# Many of the methods in Base are borrowed directly, or with some modification from ActiveRecord
|
40
|
+
# http://api.rubyonrails.org/classes/ActiveRecord/Base.html
|
41
|
+
|
42
|
+
class << self
|
43
|
+
|
44
|
+
# #find_by_wql currently only works when called through #find
|
45
|
+
# it may stay like that too. I haven't decided.
|
46
|
+
def find_by_wql(query)
|
47
|
+
d = connection.ExecQuery(query)
|
48
|
+
begin
|
49
|
+
d.count # needed to check for errors. Weird, but it works.
|
50
|
+
rescue => error
|
51
|
+
case error.to_s
|
52
|
+
when /Invalid class/i ; raise InvalidClass
|
53
|
+
when /Invalid query/i ; raise InvalidQuery
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
d.to_a
|
58
|
+
end
|
59
|
+
|
60
|
+
# WMI::Win32ComputerSystem.find(:all)
|
61
|
+
# returns an array of Win32ComputerSystem objects
|
62
|
+
#
|
63
|
+
# WMI::Win32ComputerSystem.find(:first)
|
64
|
+
# returns the first Win32ComputerSystem object
|
65
|
+
#
|
66
|
+
# WMI::Win32ComputerSystem.find(:last)
|
67
|
+
# returns the last Win32ComputerSystem object
|
68
|
+
#
|
69
|
+
# options:
|
70
|
+
#
|
71
|
+
# :conditions
|
72
|
+
#
|
73
|
+
# Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
|
74
|
+
# The array form is to be used when the condition input is tainted and requires sanitization. The string form can
|
75
|
+
# be used for statements that don't involve tainted data. The hash form works much like the array form, except
|
76
|
+
# only equality and range is possible. Examples:
|
77
|
+
#
|
78
|
+
# Win32ComputerSystem.find(:all, :conditions => {:drivetype => 3} ) # Hash
|
79
|
+
# Win32ComputerSystem.find(:all, :conditions => [:drivetype, 3] ) # Array
|
80
|
+
# Win32ComputerSystem.find(:all, :conditions => 'drivetype = 3' ) # String
|
81
|
+
#
|
82
|
+
# :host - computername, defaults to localhost
|
83
|
+
# :class - swebm class , defaults to 'root\\cimv2'
|
84
|
+
# :privileges - see WMI::Privilege for a list of privileges
|
85
|
+
# :user - username (domain\\username)
|
86
|
+
# :password - password
|
87
|
+
def find(arg=:all, options={})
|
88
|
+
set_connection options
|
89
|
+
case arg
|
90
|
+
when :all; find_all(options)
|
91
|
+
when :first; find_first(options)
|
92
|
+
when :last; find_last(options)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# an alias for find(:last)
|
97
|
+
def last(options={})
|
98
|
+
find(:last, options)
|
99
|
+
end
|
100
|
+
|
101
|
+
# an alias for find(:first)
|
102
|
+
def first(options={})
|
103
|
+
find(:first, options)
|
104
|
+
end
|
105
|
+
|
106
|
+
# an alias for find(:all)
|
107
|
+
def all(options={})
|
108
|
+
find(:all, options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def set_connection(options={})
|
112
|
+
@host = options[:host]
|
113
|
+
@klass = options[:class] || 'root\\cimv2'
|
114
|
+
@user,@password = options[:user], options[:password]
|
115
|
+
@privileges = options[:privileges]
|
116
|
+
end
|
117
|
+
|
118
|
+
def set_wmi_class_name(name)
|
119
|
+
@subclass_name = name
|
120
|
+
end
|
121
|
+
|
122
|
+
def subclass_name
|
123
|
+
@subclass_name ||= self.name.split('::').last
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def connection
|
129
|
+
@c ||= WIN32OLE.new("WbemScripting.SWbemLocator")
|
130
|
+
@privileges.each { |priv| @c.security_.privileges.add(priv, true) } if @privileges
|
131
|
+
@c.ConnectServer(@host,@klass,@user,@password)
|
132
|
+
end
|
133
|
+
|
134
|
+
def find_first(options={})
|
135
|
+
find_all(options).first
|
136
|
+
end
|
137
|
+
|
138
|
+
def find_last(options={})
|
139
|
+
find_all(options).last
|
140
|
+
end
|
141
|
+
|
142
|
+
def find_all(options={})
|
143
|
+
find_by_wql(construct_finder_sql(options))
|
144
|
+
end
|
145
|
+
|
146
|
+
def construct_finder_sql(options)
|
147
|
+
#~ scope = scope(:find)
|
148
|
+
sql = "SELECT #{options[:select] || '*'} "
|
149
|
+
sql << "FROM #{options[:from] || subclass_name} "
|
150
|
+
|
151
|
+
#~ add_joins!(sql, options, scope)
|
152
|
+
add_conditions!(sql, options[:conditions], nil)
|
153
|
+
|
154
|
+
sql << " GROUP BY #{options[:group]} " if options[:group]
|
155
|
+
|
156
|
+
#~ add_order!(sql, options[:order], scope)
|
157
|
+
#~ add_limit!(sql, options, scope)
|
158
|
+
#~ add_lock!(sql, options, scope)
|
159
|
+
|
160
|
+
sql
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_conditions!(sql, conditions, scope = :auto)
|
164
|
+
#~ scope = scope(:find) if :auto == scope
|
165
|
+
segments = []
|
166
|
+
segments << sanitize_sql(conditions) unless conditions.nil?
|
167
|
+
#~ segments << conditions unless conditions.nil?
|
168
|
+
#~ segments << type_condition unless descends_from_active_record?
|
169
|
+
segments.compact!
|
170
|
+
sql << "WHERE #{segments.join(") AND (")} " unless segments.empty?
|
171
|
+
sql.gsub!("\\","\\\\\\")
|
172
|
+
end
|
173
|
+
|
174
|
+
# Accepts an array, hash, or string of sql conditions and sanitizes
|
175
|
+
# them into a valid SQL fragment.
|
176
|
+
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
|
177
|
+
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
|
178
|
+
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
|
179
|
+
def sanitize_sql(condition)
|
180
|
+
case condition
|
181
|
+
when Array; sanitize_sql_array(condition)
|
182
|
+
when Hash; sanitize_sql_hash(condition)
|
183
|
+
else condition
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Sanitizes a hash of attribute/value pairs into SQL conditions.
|
188
|
+
# { :name => "foo'bar", :group_id => 4 }
|
189
|
+
# # => "name='foo''bar' and group_id= 4"
|
190
|
+
# { :status => nil, :group_id => [1,2,3] }
|
191
|
+
# # => "status IS NULL and group_id IN (1,2,3)"
|
192
|
+
def sanitize_sql_hash(attrs)
|
193
|
+
conditions = attrs.map do |attr, value|
|
194
|
+
#~ "#{table_name}.#{connection.quote_column_name(attr)} #{attribute_condition(value)}"
|
195
|
+
"#{attr} = '#{value}'"
|
196
|
+
end.join(' AND ')
|
197
|
+
|
198
|
+
#~ replace_bind_variables(conditions, attrs.values)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
def const_missing(name)
|
206
|
+
self.const_set(name, Class.new(self::Base))
|
207
|
+
end
|
208
|
+
|
209
|
+
# allow for "WMI.Win32_Disk" style access
|
210
|
+
def self.method_missing(m, *args)
|
211
|
+
eval("WMI::" + m)
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module WMI
|
2
|
+
module Privilege
|
3
|
+
# Required to create a primary token.
|
4
|
+
CreateToken = 1
|
5
|
+
|
6
|
+
# Required to assign the primary token of a process.
|
7
|
+
PrimaryToken = 2
|
8
|
+
|
9
|
+
# Required to lock physical pages in memory.
|
10
|
+
LockMemory = 3
|
11
|
+
|
12
|
+
# Required to increase the quota assigned to a process.
|
13
|
+
IncreaseQuota = 4
|
14
|
+
|
15
|
+
# Required to create a machine account.
|
16
|
+
MachineAccount = 5
|
17
|
+
|
18
|
+
# Identifies its holder as part of the trusted computer base. Some trusted, protected
|
19
|
+
# subsystems are granted this privilege.
|
20
|
+
Tcb = 6
|
21
|
+
|
22
|
+
# Required to perform a number of security-related functions, such as controlling and
|
23
|
+
# viewing audit messages. This privilege identifies its holder as a security operator.
|
24
|
+
#
|
25
|
+
Security = 7
|
26
|
+
|
27
|
+
# Required to take ownership of an object without being granted discretionary access.
|
28
|
+
# This privilege allows the owner value to be set only to those values that the holder
|
29
|
+
# may legitimately assign as the owner of an object.
|
30
|
+
TakeOwnership = 8
|
31
|
+
|
32
|
+
# Required to load or unload a device driver.
|
33
|
+
LoadDriver = 9
|
34
|
+
|
35
|
+
# Required to gather profiling information for the entire system.
|
36
|
+
SystemProfile = 10
|
37
|
+
|
38
|
+
# Required to modify the system time.
|
39
|
+
Systemtime = 11
|
40
|
+
|
41
|
+
# Required to gather profiling information for a single process.
|
42
|
+
ProfileSingleProcess = 12
|
43
|
+
|
44
|
+
# Required to increase the base priority of a process.
|
45
|
+
IncreaseBasePriority = 13
|
46
|
+
|
47
|
+
# Required to create a paging file.
|
48
|
+
CreatePagefile = 14
|
49
|
+
|
50
|
+
# Required to create a permanent object.
|
51
|
+
CreatePermanent = 15
|
52
|
+
|
53
|
+
# Required to perform backup operations.
|
54
|
+
Backup = 16
|
55
|
+
|
56
|
+
# Required to perform restore operations. This privilege enables you to set any valid
|
57
|
+
# user or group security identifier (SID) as the owner of an object.
|
58
|
+
Restore = 17
|
59
|
+
|
60
|
+
# Required to shut down a local system.
|
61
|
+
Shutdown = 18
|
62
|
+
|
63
|
+
# Required to debug a process.
|
64
|
+
Debug = 19
|
65
|
+
|
66
|
+
# Required to generate audit-log entries.
|
67
|
+
Audit = 20
|
68
|
+
|
69
|
+
# Required to modify the nonvolatile RAM of systems that use this type of memory to store
|
70
|
+
# configuration information.
|
71
|
+
SystemEnvironment = 21
|
72
|
+
|
73
|
+
# Required to receive notifications of changes to files or directories. This privilege
|
74
|
+
# also causes the system to skip all traversal access checks. It is enabled by default
|
75
|
+
# for all users.
|
76
|
+
ChangeNotify = 22
|
77
|
+
|
78
|
+
# Required to shut down a system using a network request.
|
79
|
+
RemoteShutdown = 23
|
80
|
+
|
81
|
+
# Required to remove a computer from a docking station.
|
82
|
+
Undock = 24
|
83
|
+
|
84
|
+
# Required to synchronize directory service data.
|
85
|
+
SyncAgent = 25
|
86
|
+
|
87
|
+
# Required to enable computer and user accounts to be trusted for delegation.
|
88
|
+
EnableDelegation = 26
|
89
|
+
|
90
|
+
# Required to perform volume maintenance tasks. Windows 2000, Windows NT 4.0, and Windows
|
91
|
+
# Me/98/95: This privilege is not available.
|
92
|
+
ManageVolume = 27
|
93
|
+
end
|
94
|
+
end
|