1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
|
const ROOT_OU = "cn=users"
const REPOSITORY_FILE = "c:\temp\repository.log"
const REPOSITORY_COMPARE_FILE = "c:\temp\repository_comp.log"
const RESULT_FILE = "c:\temp\result.log"
const USER_PROPS = "Name,AccountDisabled,AccountExpirationDate,GroupMembership"
Set usersPropsDict = CreateObject("Scripting.Dictionary")
set objFSO = createobject("scripting.filesystemobject")
GetUsersProps
if objFSO.FileExists(REPOSITORY_FILE) then
objFSO.CopyFile REPOSITORY_FILE, REPOSITORY_COMPARE_FILE, TRUE
LogUsersProps
CheckUserChanges
else
LogUsersProps
end if
wscript.echo "Complete"
function CheckUsersStatus(prevStateArr, curStateArr)
dim strResult
Set usersDict = CreateObject("Scripting.Dictionary")
for each line in prevStateArr
if Trim(line) <> "" then
user = Split(line, ",")(0)
usersDict.Add user, 0
end if
next
for each line in curStateArr
if Trim(line) <> "" then
user = Split(line, ",")(0)
if usersDict.Exists(user) then
usersDict.Item(user) = 2
else
usersDict.Add user, 1
end if
end if
next
for each key in usersDict
select case usersDict.Item(key)
case 0: 'user was deleted
strResult = strResult & "User [" & key & "] was deleted" & vbNewLine
case 1: 'new created user
strResult = strResult & "New user [" & key & "] was created" & vbNewLine
case 2: 'user wasn't changed
end select
next
CheckUsersStatus = strResult
end function
sub CheckUserChanges
curStateData = objFSO.OpenTextFile(REPOSITORY_FILE, 1).ReadAll
prevStateData = objFSO.OpenTextFile(REPOSITORY_COMPARE_FILE, 1).ReadAll
curStateArr = Split(curStateData, vbNewLine)
prevStateArr = Split(prevStateData, vbNewLine)
strSubject = "AD User Changes Result Log - " & Date & " " & Time
strResult = CheckUsersStatus(prevStateArr, curStateArr)
for i=1 to UBound(curStateArr)
line = curStateArr(i)
if InStr(prevStateData, Trim(line) & vbNewLine) = 0 then
matchLine = FindUserChangeDelta(line, prevStateArr)
if matchLine <> "" then
changeResult = LogUserPropertiesChange(matchLine, line)
if changeResult <> "" then
strResult = strResult & changeResult
end if
end if
end if
next
if objFSO.FileExists(RESULT_FILE) then
set objResFile = objFSO.OpenTextFile(RESULT_FILE, 8)
else
set objResFile = objFSO.CreateTextFile(RESULT_FILE, 2)
end if
objResFile.WriteLine strSubject
if strResult <> "" then
objResFile.WriteLine strResult
NotifyByEmail strSubject, strResult
else
objResFile.WriteLine "No changes were monitored."
end if
objResFile.Close
end sub
sub NotifyByEmail(strSubject, strResult)
Dim ToAddress
Dim MessageSubject
Dim MessageBody
Dim MessageAttachment
Dim ol, ns, newMail
ToAddress = "[email protected]"
MessageSubject = strSubject
MessageBody = strResult
Set ol = WScript.CreateObject("Outlook.Application")
Set ns = ol.getNamespace("MAPI")
ns.logon "","",true,false
Set newMail = ol.CreateItem(olMailItem)
newMail.Subject = MessageSubject
newMail.Body = MessageBody & vbCrLf
' validate the recipient, just in case...
Set myRecipient = ns.CreateRecipient(ToAddress)
myRecipient.Resolve
If Not myRecipient.Resolved Then
MsgBox "unknown recipient"
Else
newMail.Recipients.Add(myRecipient)
newMail.Send
End If
Set ol = Nothing
end sub
function LogUserPropertiesChange(matchLine, line)
changeResult = false
arr1 = Split(matchLine, ",")
arr2 = Split(line, ",")
userPropsArr = Split(USER_PROPS, ",")
strResult = "[" & arr1(0) & "]" & vbNewLine
for i=1 to UBound(userPropsArr)
'special handling for GroupMembership
if userPropsArr(i) = "GroupMembership" then
if UBound(arr1) < i then
strResult = strResult & "Groups [" & Replace(arr2(i), ";",",") & "] were removed" & vbNewLine
changeResult =true
else
if UBound(arr2) < i then
strResult = strResult & "Groups [" & Replace(arr1(i), ";",",") & "] were added" & vbNewLine
changeResult =true
else
arrMembers1 = Split(arr1(i), ";")
arrMembers2 = Split(arr2(i), ";")
strResult = strResult & userPropsArr(i) & ": " & vbNewLine
Set dictmembers2 = CreateObject("Scripting.Dictionary")
Set dictmembers1 = CreateObject("Scripting.Dictionary")
for each mem2 in arrMembers2
dictmembers2.Add mem2, nothing
next
for each mem1 in arrMembers1
if dictmembers2.Exists(mem1) = false then
strResult = strResult & "Group [" & mem1 & "] was removed" & vbNewLine
end if
dictmembers1.Add mem1, nothing
next
for each mem2 in arrMembers2
if dictmembers1.Exists(mem2) = false then
strResult = strResult & "Group [" & mem2 & "] was added" & vbNewLine
end if
next
changeResult =true
end if
end if
else
if UBound(arr1) >= i and UBound(arr2) >= i then
if arr1(i) <> arr2(i) then
strLine = userPropsArr(i) & ": " & vbNewLine
strLine = strLine & "Before = " & arr1(i) & vbNewLine
strLine = strLine & "After = " & arr2(i) & vbNewLine
strResult = strResult & strLine & vbNewLine
changeResult = true
end if
else
if UBound(arr1) >= i and UBound(arr2) < i then
strLine = userPropsArr(i) & ": " & vbNewLine
strLine = strLine & "Before = " & arr1(i) & vbNewLine
strLine = strLine & "After = No Property" & vbNewLine
strResult = strResult & strLine & vbNewLine
changeResult = true
else
if UBound(arr1) < i and UBound(arr2) >= i then
strLine = userPropsArr(i) & ": " & vbNewLine
strLine = strLine & "Before = No Property" & vbNewLine
strLine = strLine & "After = " & arr2(i) & vbNewLine
strResult = strResult & strLine & vbNewLine
changeResult = true
end if
end if
end if
end if
next
if changeResult = true then
LogUserPropertiesChange = strResult & vbNewLine
else
LogUserPropertiesChange = ""
end if
end function
function FindUserChangeDelta(line, prevStateArr)
dim user,matchLine
user = Split(line, ",")(0)
for each prevLine in prevStateArr
if Trim(prevLine) <> "" then
if Split(prevLine, ",")(0) = user then
matchLine = prevLine
exit for
end if
end if
next
FindUserChangeDelta = matchLine
end function
sub LogUsersProps
on error resume next
dim userProp
set objLog = objFSO.CreateTextFile(REPOSITORY_FILE, 2)
objLog.WriteLine USER_PROPS
for each objKey in usersPropsDict
userProp = objKey
for each objInnerKey in usersPropsDict(objKey)
userProp = userProp & "," & usersPropsDict(objKey)(objInnerKey)
next
objLog.WriteLine userProp
next
objLog.Close
end sub
sub GetUsersProps
dim user
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
if ROOT_OU <> "" then
ldaproot = "LDAP://" & ROOT_OU & "," & strDNSDomain
else
ldaproot = "LDAP://" & strDNSDomain
end if
objCommand.CommandText = "SELECT distinguishedName,sAMAccountName FROM '" & ldaproot & "' WHERE objectCategory='user'"
Set objRecordSet = objCommand.Execute
While Not objRecordSet.EOF
user = objRecordSet.Fields("sAMAccountName").Value
if usersPropsDict.Exists(user) = false then
on error resume next
Set propsDict = CreateObject("Scripting.Dictionary")
usersPropsDict.Add user, propsDict
Set ObjUser = GetObject("LDAP://" & objRecordSet.Fields("distinguishedName").Value)
propsDict.Add "AccountDisabled", ObjUser.AccountDisabled
propsDict.Add "AccountExpirationDate", ObjUser.AccountExpirationDate
end if
objRecordSet.MoveNext
WEnd
getUsersGroups
end sub
sub getUsersGroups
dim group
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
if ROOT_OU <> "" then
ldaproot = "LDAP://" & ROOT_OU & "," & strDNSDomain
else
ldaproot = "LDAP://" & strDNSDomain
end if
objCommand.CommandText = "SELECT distinguishedName,sAMAccountName FROM '" & ldaproot & "' WHERE objectCategory='group'"
Set objRecordSet = objCommand.Execute
While Not objRecordSet.EOF
group = objRecordSet.Fields("distinguishedName").Value
Set ObjGroup = GetObject("LDAP://" & group)
for each objMember in objGroup.Members
if usersPropsDict.Exists(objmember.samaccountname) then
if usersPropsDict.Item(objmember.samaccountname).Exists("groupMembership") then
groupMembership = usersPropsDict.Item(objmember.samaccountname).Item("groupMembership")
groupMembership = groupMembership & ";" & objGroup.samaccountname
usersPropsDict.Item(objmember.samaccountname).Item("groupMembership") = groupMembership
else
usersPropsDict.Item(objmember.samaccountname).Add "groupMembership", objGroup.samaccountname
end if
end if
next
objRecordSet.MoveNext
WEnd
end sub
|