2014-09-30 44 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