【问题标题】:VBScript - Retrieving a user's nested groups and getting rid of repetitionsVBScript - 检索用户的嵌套组并消除重复
【发布时间】:2014-09-30 08:35:57
【问题描述】:

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

我在gallery.technet.microsoft.com 上找到了Monimoy Sanyal 获取用户所属组的整个列表的脚本,并尝试对其进行调整以适应我的需要。这是我编辑的脚本:

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,但我仍然发现自己在整个结果中都有大量重复(我们的 AD 有点臃肿的组,它是一个包含许多嵌套组和嵌套组的巨大结构在其他嵌套组等中)并且检查似乎没有注意到 ObjThisIsNestedGroup.CN 已经在 GroupsList 中找到。 而且我不知道如何正确实现缩进。

有什么想法吗?我是脚本新手,如果答案很明显,请见谅。

【问题讨论】:

    标签: windows recursion vbscript active-directory nested-groups


    【解决方案1】:

    将组作为键添加到 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)
    

    【讨论】:

    • 嘿,我在 Dims 之后添加了前两行,中间行而不是 GroupsList = GroupsList + ObjGroup.CN + VbCrLf (与递归相同),并且 f.write 代替上一个。现在它在第 34 行(您的回复中的中间行)给了我一个错误 undefined variable 'ObjGroup.CN' 800A01F4。我不确定我做错了什么。
    • @RinNagamine 对不起,我的错误。在该行中,您需要括号而不是方括号。
    • 啊,我明白了。我做了更改,并用括号运行它,但现在它只返回直接成员组,而不是单个嵌套组。
    • ...我恢复到我的旧代码,没有进行任何更改,只是取消了注释行并注释了你的行,现在重复的 /are/ 从结果中删除了。我不明白。虽然我仍然无法为嵌套组的嵌套组等获得正确的缩进......
    【解决方案2】:

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

    工作流程如下:

    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,并在第一次调用 CheckForNestedGroup 之前将其设为 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      相关资源
      最近更新 更多