2014-09-30 45 views
1

对于我的工作,我必须在VBScript中编写一个脚本,检索用户所属的所有组的列表,包括嵌套组,并取出嵌套组在整个列表中重复(以及缩进嵌套组,进一步缩进嵌套组嵌套组等)VBScript - 检索用户的嵌套组并摆脱重复

我发现了一个脚本,通过gallery.technet获取Monimoy Sanyal提供的用户所属组的全部列表.microsoft.com,并试图使其适应我的需求。这里是由我编辑的脚本:

Option Explicit 

Const ForReading = 1, ForWriting = 2, ForAppend = 8 

Dim ObjUser, ObjRootDSE, ObjConn, ObjRS 
Dim GroupCollection, ObjGroup 
Dim StrUserName, StrDomName, StrSQL 
Dim GroupsList 
Dim WriteFile 

GroupsList = "" 

Set ObjRootDSE = GetObject("LDAP://RootDSE") 
StrDomName = Trim(ObjRootDSE.Get("DefaultNamingContext")) 
Set ObjRootDSE = Nothing 

StrUserName = InputBox("Enter user login", "Info needed", "") 
StrSQL = "Select ADsPath From 'LDAP://" & StrDomName & "' Where ObjectCategory = 'User' AND SAMAccountName = '" & StrUserName & "'" 

Set ObjConn = CreateObject("ADODB.Connection") 
ObjConn.Provider = "ADsDSOObject": ObjConn.Open "Active Directory Provider" 
Set ObjRS = CreateObject("ADODB.Recordset") 
ObjRS.Open StrSQL, ObjConn 
If Not ObjRS.EOF Then 
    ObjRS.MoveLast: ObjRS.MoveFirst 
    Set ObjUser = GetObject (Trim(ObjRS.Fields("ADsPath").Value)) 
    Set GroupCollection = ObjUser.Groups 
    WScript.Echo "Looking for groups " & StrUserName & " is member of. This may take some time..." 
    'Groups with direct membership, and calling recursive function for nested groups 
    For Each ObjGroup In GroupCollection 
     GroupsList = GroupsList + ObjGroup.CN + VbCrLf 
     CheckForNestedGroup ObjGroup 
    Next 
    Set ObjGroup = Nothing: Set GroupCollection = Nothing: Set ObjUser = Nothing 
    'Writing list in a file named Groups <username>.txt 
    Set WriteFile = WScript.CreateObject("WScript.Shell") 
     Dim fso, f 
     Set fso = CreateObject("Scripting.FileSystemObject") 
     Set f = fso.OpenTextFile("Groups " & StrUserName & ".txt", ForWriting,true) 
     f.write(GroupsList) 
     f.Close 
     WScript.Echo "You can find the list in the Groups " &StrUserName & ".txt file that has just been created." 
Else 
    WScript.Echo "Couldn't find user " & StrUserName & " in AD." 
End If 
ObjRS.Close: Set ObjRS = Nothing 
ObjConn.Close: Set ObjConn = Nothing 

'Recursive fucntion 
Private Sub CheckForNestedGroup(ObjThisGroupNestingCheck) 
    On Error Resume Next 
    Dim AllMembersCollection, StrMember, StrADsPath, ObjThisIsNestedGroup 
    AllMembersCollection = ObjThisGroupNestingCheck.GetEx("MemberOf") 
    For Each StrMember in AllMembersCollection 
     StrADsPath = "LDAP://" & StrMember 
     Set ObjThisIsNestedGroup = GetObject(StrADsPath) 
     'Not include a group in the list if it is already in the list (does not work for some reason?) 
     If InStr(GroupsList, ObjThisIsNestedGroup.CN) = 0 Then 
      GroupsList = GroupsList + vbTab + ObjThisIsNestedGroup.CN + VbCrLf 
     End If 
     'Recursion to look for nested groups and nested groups of nested groups and nested groups of nested groups of nested groups and... 
     CheckForNestedGroup ObjThisIsNestedGroup 
    Next 
    Set ObjThisIsNestedGroup = Nothing: Set StrMember = Nothing: Set AllMembersCollection = Nothing 
End Sub 

而不是显示每组的弹出发现像原来的剧本一样,我整个列表存储在一个字符串(GroupsList = GroupsList + ObjGroup.CN + VbCrLf直接组,GroupsList = GroupsList + vbTab + ObjThisIsNestedGroup.CN + VbCrLf在嵌套组递归函数),并且一旦脚本完成查找组,它就将字符串保存到一个文件中。 (f.write(GroupsList)

我的问题是,尽管在递归函数的If "InStr(GroupsList, ObjThisIsNestedGroup.CN) = 0,我仍然觉得自己在整个结果吨重复的(我们的广告是一种以群体的臃肿,它与许多嵌套组和一个巨大的结构在其他嵌套组中的嵌套组等),并且该检查似乎没有注意到ObjThisIsNestedGroup.CN已在GroupsList中找到。 而我不知道如何正确实施缩进。

任何想法?我在编写脚本方面比较陌生,所以如果答案很明显,请原谅我。

回答

0

我发现这两个问题的解决方案。那么,第一个问题我不确定我是如何修复的,因为我只是在修改代码之后恢复了代码,然后才奇迹般地工作。 对于不断增加的缩进,我声明了一个名为RecurCount的全局变量,每次调用递归过程时都会增加该变量,并在过程之后减少。然后,在该过程中,我添加了For i = 0到RecurCount,根据RecurCount添加不同数量的vbTabs。

这里的工作过程:

Private Sub CheckForNestedGroup(ObjThisGroupNestingCheck) 
    On Error Resume Next 
    Dim AllMembersCollection, StrMember, StrADsPath, ObjThisIsNestedGroup, TabAdd, i 
    AllMembersCollection = ObjThisGroupNestingCheck.GetEx("MemberOf") 
    For Each StrMember in AllMembersCollection 
     If StrMember <> "" Then 
      StrADsPath = "LDAP://" & StrMember 
      Set ObjThisIsNestedGroup = GetObject(StrADsPath) 
      'If InStr(GroupsList, ObjThisIsNestedGroup.CN) = 0 Then (Uncomment this If and indent lines below to remove groups already in the list) 
      TabAdd = "" 
      For i = 0 to Recurcount 
       TabAdd = TabAdd & vbTab 
      Next 
      GroupsList = GroupsList & TabAdd & " " & ObjThisIsNestedGroup.CN & VbCrLf 
      'End If 
      'Recursion to include nested groups of nested groups 
      Recurcount = Recurcount + 1 
      CheckForNestedGroup ObjThisIsNestedGroup 
      Recurcount = Recurcount - 1 
     End If 
    Next 
    Set ObjThisIsNestedGroup = Nothing: Set StrMember = Nothing: Set AllMembersCollection = Nothing 
End Sub 

不要忘了昏暗Recurcount在主脚本,并使其0正确调用CheckForNestedGroup首次之前。

0

添加组作为键为Dictionary,因此列表中只包含唯一的名称,并Join()Keys阵列输出:

Set GroupsList = CreateObject("Scripting.Dictionary") 
GroupsList.CompareMode = vbTextCompare 'make keys case-insensitive 
... 
GroupsList(ObjGroup.CN) = True 
... 
f.Write Join(GroupsList.Keys, vbNewLine) 
+0

嘿, 我在Dims之后添加了前两行,中间行代替了GroupsList = GroupsList + ObjGroup.CN + VbCrLf(和递归相同),而f.write代替了前一个。 现在它给了我一个错误未定义的变量'ObjGroup.CN'800A01F4在34行(你的回应的中间线)。 我不知道我做错了什么。 – 2014-09-30 09:18:57

+0

@RinNagamine对不起,我的错。您需要在该行中使用括号而不是方括号。 – 2014-09-30 09:36:56

+0

啊,我明白了。我做了修改,然后用括号运行它,但现在它只返回直接成员组,而不是单个嵌套组。 – 2014-09-30 09:48:47