ruby-wmi 0.2.1 → 0.2.2

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.
@@ -1,3 +1,16 @@
1
+ == 0.2.2 / 2008-01-11
2
+
3
+ * 1 major enhancemenet
4
+ * supports privileges
5
+ <code>
6
+ events = WMI::Win32_NTLogEvent.find(
7
+ :all, :privileges => [WMI::Privilege::Security],
8
+ :conditions => {:logfile => 'Security', :eventcode => '517'} )
9
+ </code>
10
+ * minor enhancements
11
+ * added error handling for invalid queries and class name typos
12
+ * better documentation
13
+
1
14
  == 0.2.1 / 2007-07-19
2
15
 
3
16
  * minor enhancements
@@ -4,11 +4,10 @@ README.txt
4
4
  Rakefile
5
5
  lib/ruby-wmi.rb
6
6
  lib/ruby-wmi/base.rb
7
- lib/ruby-wmi/cim.rb
7
+ lib/ruby-wmi/constants.rb
8
8
  lib/ruby-wmi/core_ext.rb
9
9
  lib/ruby-wmi/core_ext/time_ext.rb
10
10
  lib/ruby-wmi/core_ext/win32ole_ext.rb
11
- lib/ruby-wmi/win32.rb
12
11
  samples/disk.rb
13
12
  samples/logoff.rb
14
13
  samples/memory.rb
data/README.txt CHANGED
@@ -1,24 +1,40 @@
1
1
  ruby-wmi
2
2
  by Gordon Thiesfeld
3
3
  http://ruby-wmi.rubyforge.org/
4
+ gthiesfeld@gmail.com
4
5
 
5
6
  == DESCRIPTION:
6
-
7
- ruby-wmi is an ActiveRecord style interface for Microsoft's Windows Management Instrumentation provider.
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.
8
19
 
9
20
  == SYNOPSIS:
10
21
 
11
- # The following code sample kills all processes of a given name, except the oldest (in this case, Notepad)
22
+ # The following code sample kills all processes of a given name
23
+ # (in this case, Notepad), except the oldest.
12
24
 
13
25
  require 'ruby-wmi'
14
26
 
15
- processes = Win32::Process.find(:all, :conditions => { :name => 'Notepad.exe' })
16
- morituri = processes.sort_by{|p| p.CreationDate } #those who are about to die
17
- morituri.shift
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
18
32
  morituri.each{|p| p.terminate }
19
33
 
20
34
  == REQUIREMENTS:
21
35
 
36
+ Windows 2000 or newer
37
+ Ruby 1.8
22
38
 
23
39
  == INSTALL:
24
40
 
data/Rakefile CHANGED
@@ -4,15 +4,59 @@ require 'rubygems'
4
4
  require 'hoe'
5
5
  require './lib/ruby-wmi.rb'
6
6
 
7
- Hoe.new('ruby-wmi', Ruby_wmi::VERSION) do |p|
7
+ class Hoe
8
+ attr_accessor :download_url
9
+ attr_accessor :title
10
+ attr_accessor :tagline
11
+
12
+ alias_method :old_define_tasks, :define_tasks
13
+ def define_tasks
14
+ old_define_tasks
15
+
16
+ desc "Generate webpage"
17
+ task :generate_web do
18
+ require 'uv'
19
+ require 'erubis'
20
+
21
+ @samples = Dir['samples/*.rb'].map do |file|
22
+ html = Uv.parse( File.read(file), "xhtml", "ruby", false, "lazy")
23
+ [file, html]
24
+ end
25
+
26
+ input = File.read('web/templates/index.html.erb')
27
+ eruby = Erubis::Eruby.new(input) # create Eruby object
28
+ File.open('web/public/index.html', 'w+'){|f| f.puts eruby.result(binding()) }
29
+ end
30
+ end
31
+ end
32
+
33
+ Hoe.new('ruby-wmi', RubyWMI::VERSION) do |p|
8
34
  p.rubyforge_name = 'ruby-wmi'
35
+ p.tagline = 'WMI queries, easier'
36
+ p.title = "#{p.name} -- #{p.tagline}"
9
37
  p.author = 'Gordon Thiesfeld'
10
38
  p.email = 'gthiesfeld@gmail.com'
11
39
  p.summary = "ruby-wmi is an ActiveRecord style interface for Microsoft\'s Windows Management Instrumentation provider."
12
- # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
13
- # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
40
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
41
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
14
42
  p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
43
  p.need_tar = false
44
+ p.spec_extras = {
45
+ :requirements => ['allison', '>= 2.0.2'],
46
+ :rdoc_options => ['--title' , p.title ,
47
+ '--main' , 'README.txt' ,
48
+ '--line-numbers', '--template', File.join(Gem::GemPathSearcher.new.find('allison').full_gem_path,'lib','allison')]
49
+ }
50
+ p.download_url = 'http://rubyforge.org/projects/ruby-wmi/'
51
+
16
52
  end
17
53
 
54
+
55
+
56
+ # pscp -r -load rubyforge web/public/images vertiginal@rubyforge.org:/var/www/gforge-projects/ruby-wmi/images
57
+ # needed tasks
58
+ # * rdoc fixed.
59
+ # * clobber_webpage
60
+ # * publish_website
61
+
18
62
  # vim: syntax=Ruby
@@ -1,11 +1,10 @@
1
- class Ruby_wmi
2
- VERSION = '0.2.1'
1
+ class RubyWMI
2
+ VERSION = '0.2.2'
3
3
  end
4
4
 
5
5
  $:.unshift(File.dirname(__FILE__)) unless
6
6
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
7
7
 
8
8
  require 'ruby-wmi/core_ext'
9
+ require 'ruby-wmi/constants'
9
10
  require 'ruby-wmi/base'
10
- require 'ruby-wmi/cim'
11
- require 'ruby-wmi/win32'
@@ -2,43 +2,84 @@ require 'win32ole'
2
2
 
3
3
  module WMI
4
4
 
5
- def subclasses(options ={})
6
- Base.set_connection(options)
7
- b = Base.connection
8
- b.SubclassesOf.map { |subclass| class_name = subclass.Path_.Class }
9
- end
10
-
11
- alias :subclasses_of :subclasses
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
12
37
 
13
- def const_missing(name)
14
- self.const_set(name, Class.new(self::Base))
15
- end
16
- extend self
17
-
18
38
  class Base
19
-
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
+
20
42
  class << self
21
- def subclass_name
22
- self.name.split('::').last
23
- end
24
43
 
25
- def connection
26
- c = WIN32OLE.new("WbemScripting.SWbemLocator")
27
- c.ConnectServer(@host,@klass,@credentials[:user],@credentials[:passwd])
28
- end
29
-
30
- def set_connection(options)
31
- @host = options[:host] || nil
32
- @klass = options[:class] || 'root/cimv2'
33
- @credentials = options[:credentials] || {:user => nil,:passwd => nil}
34
- end
35
-
44
+ # #find_by_wql currently only works when called through #find
45
+ # it may stay like that too. I haven't decided.
36
46
  def find_by_wql(query)
37
47
  d = connection.ExecQuery(query)
38
- d.count # needed to check for errors. Weird, but it works.
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
+ end
55
+ end
39
56
  d.to_a
40
57
  end
41
58
 
59
+ # WMI::Win32ComputerSystem.find(:all)
60
+ # returns an array of Win32ComputerSystem objects
61
+ #
62
+ # WMI::Win32ComputerSystem.find(:first)
63
+ # returns a Win32ComputerSystem object
64
+ #
65
+ # options:
66
+ #
67
+ # :conditions
68
+ #
69
+ # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
70
+ # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
71
+ # be used for statements that don't involve tainted data. The hash form works much like the array form, except
72
+ # only equality and range is possible. Examples:
73
+ #
74
+ # Win32ComputerSystem.find(:all, :conditions => {:drivetype => 3} ) # Hash
75
+ # Win32ComputerSystem.find(:all, :conditions => [:drivetype, 3] ) # Array
76
+ # Win32ComputerSystem.find(:all, :conditions => 'drivetype = 3' ) # String
77
+ #
78
+ # :host - computername, defaults to localhost
79
+ # :class - swebm class , defaults to 'root\\cimv2'
80
+ # :privileges - see WMI::Privilege for a list of privileges
81
+ # :user - username (domain\\username)
82
+ # :password - password
42
83
  def find(arg=:all, options={})
43
84
  set_connection options
44
85
  case arg
@@ -46,7 +87,7 @@ module WMI
46
87
  when :first; find_first(options)
47
88
  end
48
89
  end
49
-
90
+
50
91
  def find_first(options={})
51
92
  find_all(options).first
52
93
  end
@@ -54,7 +95,26 @@ module WMI
54
95
  def find_all(options={})
55
96
  find_by_wql(construct_finder_sql(options))
56
97
  end
57
-
98
+
99
+ def set_connection(options)
100
+ @host = options[:host]
101
+ @klass = options[:class] || 'root\\cimv2'
102
+ @user,@password = options[:user], options[:password]
103
+ @privileges = options[:privileges]
104
+ end
105
+
106
+ private
107
+
108
+ def subclass_name
109
+ self.name.split('::').last
110
+ end
111
+
112
+ def connection
113
+ @c ||= WIN32OLE.new("WbemScripting.SWbemLocator")
114
+ @privileges.each { |priv| @c.security_.privileges.add(priv, true) } if @privileges
115
+ @c.ConnectServer(@host,@klass,@user,@password)
116
+ end
117
+
58
118
  def construct_finder_sql(options)
59
119
  #~ scope = scope(:find)
60
120
  sql = "SELECT #{options[:select] || '*'} "
@@ -71,7 +131,7 @@ module WMI
71
131
 
72
132
  sql
73
133
  end
74
-
134
+
75
135
  def add_conditions!(sql, conditions, scope = :auto)
76
136
  #~ scope = scope(:find) if :auto == scope
77
137
  segments = []
@@ -79,10 +139,10 @@ module WMI
79
139
  #~ segments << conditions unless conditions.nil?
80
140
  #~ segments << type_condition unless descends_from_active_record?
81
141
  segments.compact!
82
- sql << "WHERE (#{segments.join(") AND (")}) " unless segments.empty?
142
+ sql << "WHERE #{segments.join(") AND (")} " unless segments.empty?
83
143
  sql.gsub!("\\","\\\\\\")
84
144
  end
85
-
145
+
86
146
  # Accepts an array, hash, or string of sql conditions and sanitizes
87
147
  # them into a valid SQL fragment.
88
148
  # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
@@ -108,7 +168,13 @@ module WMI
108
168
  end.join(' AND ')
109
169
 
110
170
  #~ replace_bind_variables(conditions, attrs.values)
111
- end
171
+ end
112
172
  end
113
173
  end
174
+
175
+ private
176
+
177
+ def const_missing(name)
178
+ self.const_set(name, Class.new(self::Base))
179
+ end
114
180
  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
@@ -6,9 +6,6 @@ properties = ['Description','MaxCapacity','MemoryDevices','MemoryErrorCorrection
6
6
  mem = WMI::Win32_PhysicalMemoryArray.find(:all, :host => 'server1')
7
7
  mem.each{|i| puts properties.map{|p| "#{p}: #{i[p]}"}}
8
8
 
9
- mem2 = WMI::Win32_PhysicalMemoryArray.find(:all, {:host => 'server2', :credentials =>
10
- {:user => 'domain\\gordon', :passwd => 'password'}
11
- }
12
- )
9
+ mem2 = WMI::Win32_PhysicalMemoryArray.find(:all, {:host => 'server2', :user => 'domain\\gordon', :passwd => 'password'} )
13
10
  mem2.each{|i| puts properties.map{|p| "#{p}: #{i[p]}"}}
14
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-wmi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gordon Thiesfeld
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-10 00:00:00 -06:00
12
+ date: 2008-01-14 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.4.0
23
23
  version:
24
- description: The author was too lazy to write a description
24
+ description: "ruby-wmi is an ActiveRecord style interface for Microsoft's Windows Management Instrumentation provider. Many of the methods in WMI::Base are borrowed directly, or with some modification from ActiveRecord. http://api.rubyonrails.org/classes/ActiveRecord/Base.html The major tool in this library is the #find method. For more information, see WMI::Base. There is also a WMI.sublasses method included for reflection."
25
25
  email: gthiesfeld@gmail.com
26
26
  executables: []
27
27
 
@@ -38,21 +38,25 @@ files:
38
38
  - Rakefile
39
39
  - lib/ruby-wmi.rb
40
40
  - lib/ruby-wmi/base.rb
41
- - lib/ruby-wmi/cim.rb
41
+ - lib/ruby-wmi/constants.rb
42
42
  - lib/ruby-wmi/core_ext.rb
43
43
  - lib/ruby-wmi/core_ext/time_ext.rb
44
44
  - lib/ruby-wmi/core_ext/win32ole_ext.rb
45
- - lib/ruby-wmi/win32.rb
46
45
  - samples/disk.rb
47
46
  - samples/logoff.rb
48
47
  - samples/memory.rb
49
48
  - test/test_ruby-wmi.rb
50
49
  has_rdoc: true
51
- homepage: http://www.zenspider.com/ZSS/Products/ruby-wmi/
50
+ homepage: " by Gordon Thiesfeld"
52
51
  post_install_message:
53
52
  rdoc_options:
53
+ - --title
54
+ - ruby-wmi -- WMI queries, easier
54
55
  - --main
55
56
  - README.txt
57
+ - --line-numbers
58
+ - --template
59
+ - c:/ruby/ruby186/lib/ruby/gems/1.8/gems/allison-2.0.2/lib/allison
56
60
  require_paths:
57
61
  - lib
58
62
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -67,8 +71,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
71
  - !ruby/object:Gem::Version
68
72
  version: "0"
69
73
  version:
70
- requirements: []
71
-
74
+ requirements:
75
+ - allison
76
+ - ">= 2.0.2"
72
77
  rubyforge_project: ruby-wmi
73
78
  rubygems_version: 1.0.1
74
79
  signing_key:
@@ -1,12 +0,0 @@
1
- module CIM
2
- extend WMI
3
-
4
- class Base < WMI::Base
5
- class << self
6
- def subclass_name
7
- self.name.gsub('::', '_')
8
- end
9
- end
10
- end
11
-
12
- end
@@ -1,11 +0,0 @@
1
- module Win32
2
- extend WMI
3
-
4
- class Base < WMI::Base
5
- class << self
6
- def subclass_name
7
- self.name.gsub('::', '_')
8
- end
9
- end
10
- end
11
- end