sys-admin 1.3.1-mswin32
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/CHANGES +31 -0
- data/MANIFEST +17 -0
- data/README +174 -0
- data/lib/sys/admin.rb +403 -0
- data/test/tc_admin.rb +14 -0
- metadata +51 -0
data/CHANGES
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
== 1.3.1 - 29-Jun-2005
|
2
|
+
* Fixed a bug where the inability to read the lastlog file caused an error.
|
3
|
+
From now on that error is ignored, and the lastlog attributes of the User
|
4
|
+
object are set to nil.
|
5
|
+
* Added a beta version of Admin.delete_user (Windows only).
|
6
|
+
|
7
|
+
== 1.3.0 - 3-Jun-2005
|
8
|
+
* Bug fixes for Linux.
|
9
|
+
* Removed the version.h file - no longer needed since the Win32 version is
|
10
|
+
pure Ruby.
|
11
|
+
|
12
|
+
== 1.2.0 - 30-Apr-2005
|
13
|
+
* Replaced the Win32 version with a pure Ruby version that uses Win32API and
|
14
|
+
win32ole + WMI.
|
15
|
+
* The LocalGroup class no longer exists in the Win32 version. Instead, it is
|
16
|
+
now an attribute of a Group object. The issue was forced by WMI.
|
17
|
+
* The default for users and groups on Win32 systems is now local rather than
|
18
|
+
global. See the documentation for why you probably don't want to iterate
|
19
|
+
over global accounts.
|
20
|
+
* Corresponding doc changes and test suite changes.
|
21
|
+
|
22
|
+
== 1.1.0 - 1-Apr-2005
|
23
|
+
* Fixed bug where a segfault could occur when trying to retrieve a user or
|
24
|
+
group by an ID that didn't exist (Unix).
|
25
|
+
* Added tests for intentional failures.
|
26
|
+
* Added lastlog information tothe User class (Unix).
|
27
|
+
* Modified the way User objects are created internally (Unix).
|
28
|
+
* Fixed a bug in the User#shell attribute (Unix).
|
29
|
+
|
30
|
+
== 1.0.0 - 25-Mar-2005
|
31
|
+
* Initial release
|
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
== Description
|
2
|
+
The sys-admin package is a unified, cross platform replacement for the
|
3
|
+
Etc module.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
=== Win32
|
7
|
+
ruby test\tc_admin.rb # optional
|
8
|
+
ruby install.rb
|
9
|
+
|
10
|
+
=== Unix
|
11
|
+
ruby extconf.rb
|
12
|
+
nmake
|
13
|
+
ruby test\tc_admin.rb # optional
|
14
|
+
nmake site-install
|
15
|
+
|
16
|
+
== Synopsis
|
17
|
+
require "sys/admin"
|
18
|
+
include Sys
|
19
|
+
|
20
|
+
# Yields a User object for each user
|
21
|
+
Admin.users{ |user|
|
22
|
+
p user
|
23
|
+
}
|
24
|
+
|
25
|
+
# Returns an Array of User objects
|
26
|
+
a = Admin.users
|
27
|
+
|
28
|
+
# Yields a Group object for each group
|
29
|
+
Admin.groups{ |group|
|
30
|
+
p group
|
31
|
+
}
|
32
|
+
|
33
|
+
# Returns an Array of Group objects
|
34
|
+
g = Admin.groups
|
35
|
+
|
36
|
+
# Get information about a particular user
|
37
|
+
p Admin.get_user("nobody")
|
38
|
+
|
39
|
+
# Get information about a particular group
|
40
|
+
p Admin.get_group("adm")
|
41
|
+
|
42
|
+
== Admin
|
43
|
+
Admin.get_login
|
44
|
+
Returns the user name (only) of the current login.
|
45
|
+
|
46
|
+
Admin.get_user(name, host=localhost)
|
47
|
+
Admin.get_user(uid, host=localhost, local=true)
|
48
|
+
Returns a User object based on +name+ or +uid+.
|
49
|
+
|
50
|
+
Win32 only: you may specify a host from which information is retrieved.
|
51
|
+
The default is the local machine. You may also specify whether to
|
52
|
+
retrieve a local or global account. The default is local.
|
53
|
+
|
54
|
+
Admin.get_group(name, host=localhost, local=true)
|
55
|
+
Admin.get_group(gid, host=localhost, local=true)
|
56
|
+
Returns a Group object based on +name+ or +uid+.
|
57
|
+
|
58
|
+
Win32 only: you may specify a host from which information is retrieved.
|
59
|
+
The default is the local machine. You can retrieve either a global or
|
60
|
+
local group, depending on the value of the +local+ argument.
|
61
|
+
|
62
|
+
Admin.groups(host=localhost, local=true)
|
63
|
+
Admin.groups(host=localhost, local=true){ |group| ... }
|
64
|
+
In block form, yields a Group object for each user on the system. In
|
65
|
+
non-block form, returns an Array of Group objects.
|
66
|
+
|
67
|
+
Win32 only: you may specify a host from which information is retrieved.
|
68
|
+
The default is the local machine. You can retrieve either a global or
|
69
|
+
local group, depending on the value of the +local+ argument.
|
70
|
+
|
71
|
+
Admin.users(host=localhost, local=true)
|
72
|
+
Admin.users(host=localhost, local=true){ |user| ... }
|
73
|
+
In block form, yields a User object for each user on the system. In
|
74
|
+
non-block form, returns an Array of User objects.
|
75
|
+
|
76
|
+
Win32 only: you may specify a host from which information is retrieved.
|
77
|
+
The default is the local machine. You can retrieve either a global or
|
78
|
+
local group, depending on the value of the +local+ argument.
|
79
|
+
|
80
|
+
== User class
|
81
|
+
=== User (Win32)
|
82
|
+
The User class has the following attributes on Win32 systems:
|
83
|
+
|
84
|
+
* account_type
|
85
|
+
* caption
|
86
|
+
* description
|
87
|
+
* domain
|
88
|
+
* password
|
89
|
+
* full_name
|
90
|
+
* install_date
|
91
|
+
* name
|
92
|
+
* sid
|
93
|
+
* status
|
94
|
+
* disabled?
|
95
|
+
* local?
|
96
|
+
* lockout?
|
97
|
+
* password_changeable?
|
98
|
+
* password_expires?
|
99
|
+
* password_required?
|
100
|
+
|
101
|
+
=== User (Unix)
|
102
|
+
The User class has the following attributes on Unix systems:
|
103
|
+
|
104
|
+
* name
|
105
|
+
* passwd
|
106
|
+
* uid
|
107
|
+
* gid
|
108
|
+
* dir
|
109
|
+
* shell
|
110
|
+
* gecos
|
111
|
+
* quota
|
112
|
+
* age
|
113
|
+
* class
|
114
|
+
* comment
|
115
|
+
* expire
|
116
|
+
|
117
|
+
== Group Classes
|
118
|
+
=== Group (Win32)
|
119
|
+
The Group class has the following attributes on Win32 systems:
|
120
|
+
|
121
|
+
* caption
|
122
|
+
* description
|
123
|
+
* domain
|
124
|
+
* install_date
|
125
|
+
* name
|
126
|
+
* sid
|
127
|
+
* status
|
128
|
+
* gid
|
129
|
+
* local?
|
130
|
+
|
131
|
+
=== Group (Unix)
|
132
|
+
The Group class has the following attributes on Unix systems:
|
133
|
+
|
134
|
+
* name
|
135
|
+
* gid
|
136
|
+
* members
|
137
|
+
* passwd
|
138
|
+
|
139
|
+
== Error Classes
|
140
|
+
AdminError < StandardError
|
141
|
+
Raised if anything goes wrong with any of the above methods.
|
142
|
+
|
143
|
+
== Developer's Notes
|
144
|
+
=== Win32
|
145
|
+
The Win32 version now uses a win32ole + WMI approach to getting
|
146
|
+
information. This means that the WMI service must be running on the
|
147
|
+
target machine in order to work (which it is, by default).
|
148
|
+
|
149
|
+
Note that, by default, local user and group information is retrieved
|
150
|
+
instead of global. You probably do NOT want to iterate over global users
|
151
|
+
or groups because there can be quite a few on your domain.
|
152
|
+
|
153
|
+
== Future Plans
|
154
|
+
The following methods will be added for both platforms:
|
155
|
+
|
156
|
+
* Admin.add_user
|
157
|
+
* Admin.config_user
|
158
|
+
* Admin.delete_user
|
159
|
+
|
160
|
+
== Known Bugs
|
161
|
+
None that I'm aware of. If you find any, please log them on the project
|
162
|
+
page at http://www.rubyforge.org/projects/sysutils.
|
163
|
+
|
164
|
+
== License
|
165
|
+
Ruby's
|
166
|
+
|
167
|
+
== Copyright
|
168
|
+
(C) 2005, Daniel J. Berger
|
169
|
+
All Rights Reserved
|
170
|
+
|
171
|
+
== Author
|
172
|
+
Daniel J. Berger
|
173
|
+
djberg96@yahoo.com
|
174
|
+
IRC nickname: imperator/mok/rubyhacker1
|
data/lib/sys/admin.rb
ADDED
@@ -0,0 +1,403 @@
|
|
1
|
+
require "win32ole"
|
2
|
+
require "Win32API"
|
3
|
+
require "socket"
|
4
|
+
|
5
|
+
module Sys
|
6
|
+
class AdminError < StandardError; end
|
7
|
+
|
8
|
+
class Group
|
9
|
+
attr_accessor :caption, :description, :domain, :install_date
|
10
|
+
attr_accessor :name, :sid, :status, :gid
|
11
|
+
attr_writer :local
|
12
|
+
def initialize
|
13
|
+
yield self if block_given?
|
14
|
+
end
|
15
|
+
|
16
|
+
def local?
|
17
|
+
@local
|
18
|
+
end
|
19
|
+
|
20
|
+
def sid_type
|
21
|
+
@sid_type
|
22
|
+
end
|
23
|
+
|
24
|
+
def sid_type=(stype)
|
25
|
+
case stype
|
26
|
+
when 1
|
27
|
+
@sid_type = "user"
|
28
|
+
when 2
|
29
|
+
@sid_type = "group"
|
30
|
+
when 3
|
31
|
+
@sid_type = "domain"
|
32
|
+
when 4
|
33
|
+
@sid_type = "alias"
|
34
|
+
when 5
|
35
|
+
@sid_type = "well_known_group"
|
36
|
+
when 6
|
37
|
+
@sid_type = "deleted_account"
|
38
|
+
when 7
|
39
|
+
@sid_type = "invalid"
|
40
|
+
when 8
|
41
|
+
@sid_type = "unknown"
|
42
|
+
when 9
|
43
|
+
@sid_type = "computer"
|
44
|
+
else
|
45
|
+
@sid_type = "unknown"
|
46
|
+
end
|
47
|
+
@sid_type
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class User
|
52
|
+
|
53
|
+
attr_accessor :caption, :description, :domain, :password
|
54
|
+
attr_accessor :full_name, :install_date, :name, :sid, :status
|
55
|
+
attr_writer :disabled, :local, :lockout, :password_changeable
|
56
|
+
attr_writer :password_expires, :password_required
|
57
|
+
attr_reader :account_type
|
58
|
+
|
59
|
+
def initialize
|
60
|
+
yield self if block_given?
|
61
|
+
end
|
62
|
+
|
63
|
+
def account_type=(type)
|
64
|
+
case type
|
65
|
+
when 256
|
66
|
+
@account_type = "duplicate"
|
67
|
+
when 512
|
68
|
+
@account_type = "normal"
|
69
|
+
when 2048
|
70
|
+
@account_type = "interdomain_trust"
|
71
|
+
when 4096
|
72
|
+
@account_type = "workstation_trust"
|
73
|
+
when 8192
|
74
|
+
@account_type = "server_trust"
|
75
|
+
else
|
76
|
+
@account_type = "unknown"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def sid_type
|
81
|
+
@sid_type
|
82
|
+
end
|
83
|
+
|
84
|
+
def sid_type=(stype)
|
85
|
+
case stype
|
86
|
+
when 1
|
87
|
+
@sid_type = "user"
|
88
|
+
when 2
|
89
|
+
@sid_type = "group"
|
90
|
+
when 3
|
91
|
+
@sid_type = "domain"
|
92
|
+
when 4
|
93
|
+
@sid_type = "alias"
|
94
|
+
when 5
|
95
|
+
@sid_type = "well_known_group"
|
96
|
+
when 6
|
97
|
+
@sid_type = "deleted_account"
|
98
|
+
when 7
|
99
|
+
@sid_type = "invalid"
|
100
|
+
when 8
|
101
|
+
@sid_type = "unknown"
|
102
|
+
when 9
|
103
|
+
@sid_type = "computer"
|
104
|
+
else
|
105
|
+
@sid_type = "unknown"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def disabled?
|
110
|
+
@disabled
|
111
|
+
end
|
112
|
+
|
113
|
+
def local?
|
114
|
+
@local
|
115
|
+
end
|
116
|
+
|
117
|
+
def lockout?
|
118
|
+
@lockout
|
119
|
+
end
|
120
|
+
|
121
|
+
def password_changeable?
|
122
|
+
@password_changeable
|
123
|
+
end
|
124
|
+
|
125
|
+
def password_expires?
|
126
|
+
@password_expires
|
127
|
+
end
|
128
|
+
|
129
|
+
def password_required?
|
130
|
+
@password_required
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Admin
|
135
|
+
VERSION = "1.3.1"
|
136
|
+
|
137
|
+
# Deletes +userid+ from the given +host+, or the local host if no host
|
138
|
+
# is specified.
|
139
|
+
#
|
140
|
+
def self.delete_user(userid=nil, host=Socket.gethostname)
|
141
|
+
begin
|
142
|
+
adsi = WIN32OLE.connect("WinNT://#{host},Computer")
|
143
|
+
rescue WIN32OLERuntimeError => err
|
144
|
+
raise AdminError, err
|
145
|
+
end
|
146
|
+
|
147
|
+
begin
|
148
|
+
adsi.delete("user", userid)
|
149
|
+
rescue WIN32OLERuntimeError => err
|
150
|
+
raise AdminError, err
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Returns the user name (only) of the current login.
|
155
|
+
#
|
156
|
+
def self.get_login
|
157
|
+
getlogin = Win32API.new("advapi32","GetUserName",['P','P'],'L')
|
158
|
+
buffer = "\0" * 256;
|
159
|
+
nsize = [256].pack("L")
|
160
|
+
getlogin.call(buffer,nsize)
|
161
|
+
len = nsize.unpack("L")[0]
|
162
|
+
username = buffer[0 ... len].chop
|
163
|
+
username
|
164
|
+
end
|
165
|
+
|
166
|
+
# Returns a User object based on either +name+ or +uid+.
|
167
|
+
#
|
168
|
+
# call-seq:
|
169
|
+
# get_user(name, host=localhost)
|
170
|
+
# get_user(uid, host=localhost, local=true)
|
171
|
+
#
|
172
|
+
# You may specify a +host+ from which information is retrieved. The
|
173
|
+
# default is the local machine. You may also specify whether to
|
174
|
+
# retrieve a local or global account. The default is local.
|
175
|
+
#
|
176
|
+
def self.get_user(uid, host=Socket.gethostname, local=true)
|
177
|
+
host = Socket.gethostname if host.nil?
|
178
|
+
cs = "winmgmts:{impersonationLevel=impersonate}!"
|
179
|
+
cs << "//#{host}/root/cimv2"
|
180
|
+
|
181
|
+
begin
|
182
|
+
wmi = WIN32OLE.connect(cs)
|
183
|
+
rescue WIN32OLERuntimeError => e
|
184
|
+
raise AdminError, e
|
185
|
+
end
|
186
|
+
|
187
|
+
query = "select * from win32_useraccount"
|
188
|
+
query << " where localaccount = true" if local
|
189
|
+
|
190
|
+
if uid.kind_of?(Fixnum)
|
191
|
+
if local
|
192
|
+
query << " and sid like '%-#{uid}'"
|
193
|
+
else
|
194
|
+
query << " where sid like '%-#{uid}'"
|
195
|
+
end
|
196
|
+
else
|
197
|
+
if local
|
198
|
+
query << " and name = '#{uid}'"
|
199
|
+
else
|
200
|
+
query << " where name = '#{uid}'"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
wmi.execquery(query).each{ |user|
|
205
|
+
# Because our 'like' query isn't fulproof, let's parse
|
206
|
+
# the SID again to make sure
|
207
|
+
if uid.kind_of?(Fixnum)
|
208
|
+
if user.sid.split("-").last.to_i != uid
|
209
|
+
next
|
210
|
+
end
|
211
|
+
end
|
212
|
+
usr = User.new do |u|
|
213
|
+
u.account_type = user.accounttype
|
214
|
+
u.caption = user.caption
|
215
|
+
u.description = user.description
|
216
|
+
u.disabled = user.disabled
|
217
|
+
u.domain = user.domain
|
218
|
+
u.full_name = user.fullname
|
219
|
+
u.install_date = user.installdate
|
220
|
+
u.local = user.localaccount
|
221
|
+
u.lockout = user.lockout
|
222
|
+
u.name = user.name
|
223
|
+
u.password_changeable = user.passwordchangeable
|
224
|
+
u.password_expires = user.passwordexpires
|
225
|
+
u.password_required = user.passwordrequired
|
226
|
+
u.sid = user.sid
|
227
|
+
u.sid_type = user.sidtype
|
228
|
+
u.status = user.status
|
229
|
+
end
|
230
|
+
return usr
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
# In block form, yields a User object for each user on the system. In
|
235
|
+
# non-block form, returns an Array of User objects.
|
236
|
+
#
|
237
|
+
# call-seq:
|
238
|
+
# users(host=localhost, local=true)
|
239
|
+
# users(host=localhost, local=true){ |user| ... }
|
240
|
+
#
|
241
|
+
# You may specify a host from which information is retrieved. The
|
242
|
+
# default is the local machine. You can retrieve either a global or
|
243
|
+
# group, depending on the value of the +local+ argument.
|
244
|
+
#
|
245
|
+
def self.users(host=Socket.gethostname, local=true)
|
246
|
+
host = Socket.gethostname if host.nil?
|
247
|
+
cs = "winmgmts:{impersonationLevel=impersonate}!"
|
248
|
+
cs << "//#{host}/root/cimv2"
|
249
|
+
|
250
|
+
begin
|
251
|
+
wmi = WIN32OLE.connect(cs)
|
252
|
+
rescue WIN32OLERuntimeError => e
|
253
|
+
raise AdminError, e
|
254
|
+
end
|
255
|
+
|
256
|
+
query = "select * from win32_useraccount"
|
257
|
+
query << " where localaccount = true" if local
|
258
|
+
array = []
|
259
|
+
|
260
|
+
wmi.execquery(query).each{ |user|
|
261
|
+
usr = User.new do |u|
|
262
|
+
u.account_type = user.accounttype
|
263
|
+
u.caption = user.caption
|
264
|
+
u.description = user.description
|
265
|
+
u.disabled = user.disabled
|
266
|
+
u.domain = user.domain
|
267
|
+
u.full_name = user.fullname
|
268
|
+
u.install_date = user.installdate
|
269
|
+
u.local = user.localaccount
|
270
|
+
u.lockout = user.lockout
|
271
|
+
u.name = user.name
|
272
|
+
u.password_changeable = user.passwordchangeable
|
273
|
+
u.password_expires = user.passwordexpires
|
274
|
+
u.password_required = user.passwordrequired
|
275
|
+
u.sid = user.sid
|
276
|
+
u.sid_type = user.sidtype
|
277
|
+
u.status = user.status
|
278
|
+
end
|
279
|
+
|
280
|
+
if block_given?
|
281
|
+
yield usr
|
282
|
+
else
|
283
|
+
array.push(usr)
|
284
|
+
end
|
285
|
+
}
|
286
|
+
return array unless block_given?
|
287
|
+
end
|
288
|
+
|
289
|
+
# Returns a Group object based on either +name+ or +uid+.
|
290
|
+
#
|
291
|
+
# call-seq:
|
292
|
+
# get_group(name, host=localhost, local=true)
|
293
|
+
# get_group(gid, host=localhost, local=true)
|
294
|
+
#
|
295
|
+
# You may specify a host from which information is retrieved.
|
296
|
+
# The default is the local machine. You can retrieve either a global or
|
297
|
+
# local group, depending on the value of the +local+ argument.
|
298
|
+
#
|
299
|
+
def self.get_group(grp, host=Socket.gethostname, local=true)
|
300
|
+
host = Socket.gethostname if host.nil?
|
301
|
+
cs = "winmgmts:{impersonationLevel=impersonate}!"
|
302
|
+
cs << "//#{host}/root/cimv2"
|
303
|
+
gid = nil
|
304
|
+
|
305
|
+
begin
|
306
|
+
wmi = WIN32OLE.connect(cs)
|
307
|
+
rescue WIN32OLERuntimeError => e
|
308
|
+
raise AdminError, e
|
309
|
+
end
|
310
|
+
|
311
|
+
query = "select * from win32_group"
|
312
|
+
query << " where localaccount = true" if local
|
313
|
+
|
314
|
+
if grp.kind_of?(Fixnum)
|
315
|
+
if local
|
316
|
+
query << " and sid like '%-#{grp}'"
|
317
|
+
else
|
318
|
+
query << " where sid like '%-#{grp}'"
|
319
|
+
end
|
320
|
+
else
|
321
|
+
if local
|
322
|
+
query << " and name = '#{grp}'"
|
323
|
+
else
|
324
|
+
query << " where name = '#{grp}'"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
wmi.execquery(query).each{ |group|
|
329
|
+
gid = group.sid.split("-").last.to_i
|
330
|
+
|
331
|
+
# Because our 'like' query isn't fulproof, let's parse
|
332
|
+
# the SID again to make sure
|
333
|
+
if grp.kind_of?(Fixnum)
|
334
|
+
next if grp != gid
|
335
|
+
end
|
336
|
+
|
337
|
+
grp = Group.new do |g|
|
338
|
+
g.caption = group.caption
|
339
|
+
g.description = group.description
|
340
|
+
g.domain = group.domain
|
341
|
+
g.gid = gid
|
342
|
+
g.install_date = group.installdate
|
343
|
+
g.local = group.localaccount
|
344
|
+
g.name = group.name
|
345
|
+
g.sid = group.sid
|
346
|
+
g.sid_type = group.sidtype
|
347
|
+
g.status = group.status
|
348
|
+
end
|
349
|
+
return grp
|
350
|
+
}
|
351
|
+
# If we're here, it means it wasn't found.
|
352
|
+
raise AdminError, "no group found for '#{grp}'"
|
353
|
+
end
|
354
|
+
|
355
|
+
# In block form, yields a Group object for each user on the system. In
|
356
|
+
# non-block form, returns an Array of Group objects.
|
357
|
+
#
|
358
|
+
# call-seq:
|
359
|
+
# groups(host=localhost, local=true)
|
360
|
+
# groups(host=localhost, local=true){ |group| ... }
|
361
|
+
#
|
362
|
+
# You may specify a host from which information is retrieved.
|
363
|
+
# The default is the local machine. You can retrieve either a global or
|
364
|
+
# local group, depending on the value of the +local+ argument.
|
365
|
+
#
|
366
|
+
def self.groups(host=Socket.gethostname, local=true)
|
367
|
+
host = Socket.gethostname if host.nil?
|
368
|
+
cs = "winmgmts:{impersonationLevel=impersonate}!"
|
369
|
+
cs << "//#{host}/root/cimv2"
|
370
|
+
|
371
|
+
begin
|
372
|
+
wmi = WIN32OLE.connect(cs)
|
373
|
+
rescue WIN32OLERuntimeError => e
|
374
|
+
raise AdminError, e
|
375
|
+
end
|
376
|
+
|
377
|
+
query = "select * from win32_group"
|
378
|
+
query << " where localaccount = true" if local
|
379
|
+
|
380
|
+
array = []
|
381
|
+
wmi.execquery(query).each{ |group|
|
382
|
+
grp = Group.new do |g|
|
383
|
+
g.caption = group.caption
|
384
|
+
g.description = group.description
|
385
|
+
g.domain = group.domain
|
386
|
+
g.gid = group.sid.split("-").last.to_i
|
387
|
+
g.install_date = group.installdate
|
388
|
+
g.local = group.localaccount
|
389
|
+
g.name = group.name
|
390
|
+
g.sid = group.sid
|
391
|
+
g.sid_type = group.sidtype
|
392
|
+
g.status = group.status
|
393
|
+
end
|
394
|
+
if block_given?
|
395
|
+
yield grp
|
396
|
+
else
|
397
|
+
array.push(grp)
|
398
|
+
end
|
399
|
+
}
|
400
|
+
return array unless block_given?
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
data/test/tc_admin.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
###############################################################################
|
2
|
+
# tc_admin.rb
|
3
|
+
#
|
4
|
+
# This exists mostly for the sake of the gemspec, so that it calls the right
|
5
|
+
# test suite based on the platform.
|
6
|
+
###############################################################################
|
7
|
+
$LOAD_PATH.unshift Dir.pwd
|
8
|
+
$LOAD_PATH.unshift Dir.pwd + "/test"
|
9
|
+
|
10
|
+
if File::ALT_SEPARATOR
|
11
|
+
require "tc_win32"
|
12
|
+
else
|
13
|
+
require "tc_unix"
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: sys-admin
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.3.1
|
7
|
+
date: 2006-11-19 00:00:00 -07:00
|
8
|
+
summary: A unified, cross platform replacement for the 'etc' package.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: djberg96@gmail.com
|
12
|
+
homepage: http://www.rubyforge.org/projects/sysutils
|
13
|
+
rubyforge_project: sysutils
|
14
|
+
description: A unified, cross platform replacement for the 'etc' package.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
24
|
+
version:
|
25
|
+
platform: mswin32
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Daniel J. Berger
|
31
|
+
files:
|
32
|
+
- lib/sys/admin.rb
|
33
|
+
- CHANGES
|
34
|
+
- README
|
35
|
+
- MANIFEST
|
36
|
+
test_files:
|
37
|
+
- test/tc_admin.rb
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- CHANGES
|
42
|
+
- README
|
43
|
+
- MANIFEST
|
44
|
+
executables: []
|
45
|
+
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
dependencies: []
|
51
|
+
|