?
Solved

Copy a list of AD user accounts in a single group into a text editor

Posted on 2011-10-27
7
Medium Priority
?
384 Views
Last Modified: 2012-05-12
How can I copy a list of users name listed in a single AD group into a text editor (notepad)?
0
Comment
Question by:CTCRM
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 33

Accepted Solution

by:
jppinto earned 300 total points
ID: 37037016
0
 
LVL 6

Expert Comment

by:morpheios
ID: 37037028
' EnumGroup.vbs
' VBScript program to document members of a group.
' Reveals nested group and primary group membership.
'
' ----------------------------------------------------------------------
' Copyright (c) 2002-2010 Richard L. Mueller
' Hilltop Lab web site - http://www.rlmueller.net
' Version 1.0 - December 10, 2002
' Version 1.1 - January 24, 2003 - Include users whose Primary Group is
'                                  any nested group.
' Version 1.2 - February 19, 2003 - Standardize Hungarian notation.
' Version 1.3 - March 11, 2003 - Remove SearchScope property.
' Version 1.4 - April 30, 2003 - Use GetInfoEx to retrieve group
'                                primaryGroupToken.
' Version 1.5 - January 25, 2004 - Modify error trapping.
' Version 1.6 - November 6, 2010 - No need to set objects to Nothing.
' Version 1.7 - March 26, 2011 - Output DN instead of sAMAccountName.
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.

Option Explicit

Dim objGroup, strDN, objMemberList
Dim adoConnection, adoCommand, objRootDSE, strDNSDomain

' Dictionary object to track group membership.
Set objMemberList = CreateObject("Scripting.Dictionary")
objMemberList.CompareMode = vbTextCompare

' Check for required argument.
If (Wscript.Arguments.Count < 1) Then
    Wscript.Echo "Required argument <Distinguished Name> " _
        & "of group missing."
    Wscript.Echo "For example:" & vbCrLf _
        & "cscript //nologo EnumGroup.vbs " _
        & """cn=Test Group,ou=Sales,dc=MyDomain,dc=com"""
    Wscript.Quit(0)
End If

' Bind to the group object with the LDAP provider.
strDN = Wscript.Arguments(0)
On Error Resume Next
Set objGroup = GetObject("LDAP://" & strDN)
If (Err.Number <> 0) Then
    On Error GoTo 0
    Wscript.Echo "Group not found" & vbCrLf & strDN
    Wscript.Quit(1)
End If
On Error GoTo 0

' Retrieve DNS domain name from RootDSE.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Setup ADO.
Set adoConnection = CreateObject("ADODB.Connection")
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Enumerate group membership.
Wscript.Echo "Members of group " & objGroup.distinguishedName
Call EnumGroup(objGroup, "  ")

' Clean Up.
adoConnection.Close

Sub EnumGroup(ByVal objADGroup, ByVal strOffset)
    ' Recursive subroutine to enumerate group membership.
    ' objMemberList is a dictionary object with global scope.
    ' objADGroup is a group object bound with the LDAP provider.
    ' This subroutine outputs a list of group members, one member
    ' per line. Nested group members are included. Users are also
    ' included if their primary group is objADGroup. objMemberList
    ' prevents an infinite loop if nested groups are circular.

    Dim strFilter, strAttributes, adoRecordset, intGroupToken
    Dim objMember, strQuery, strDN

    ' Retrieve "primaryGroupToken" of group.
    objADGroup.GetInfoEx Array("primaryGroupToken"), 0
    intGroupToken = objADGroup.Get("primaryGroupToken")

    ' Use ADO to search for users whose "primaryGroupID" matches the
    ' group "primaryGroupToken".
    strFilter = "(primaryGroupID=" & intGroupToken & ")"
    strAttributes = "distinguishedName"
    strQuery = "<LDAP://" & strDNSDomain & ">;" & strFilter & ";" _
        & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    Set adoRecordset = adoCommand.Execute
    Do Until adoRecordset.EOF
        strDN = adoRecordset.Fields("distinguishedName").Value
        If (objMemberList.Exists(strDN) = False) Then
            objMemberList.Add strDN, True
            Wscript.Echo strOffset & strDN & " (Primary)"
        Else
            Wscript.Echo strOffset & strDN & " (Primary, Duplicate)"
        End If
        adoRecordset.MoveNext
    Loop
    adoRecordset.Close

    For Each objMember In objADGroup.Members
        If (objMemberList.Exists(objMember.distinguishedName) = False) Then
            objMemberList.Add objMember.distinguishedName, True
            If (UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP") Then
                Wscript.Echo strOffset & objMember.distinguishedName & " (Group)"
                Call EnumGroup(objMember, strOffset & "  ")
            Else
                Wscript.Echo strOffset & objMember.distinguishedName
            End If
        Else
            Wscript.Echo strOffset & objMember.distinguishedName & " (Duplicate)"
        End If
    Next
End Sub

Open in new window

0
 
LVL 6

Expert Comment

by:morpheios
ID: 37037041
If tere are more than 100 mebers:
' EnumGroup2.vbs
' VBScript program to enumerate members of a group by retrieving the
' "member" multivalued attribute of the group. Uses ADO range limits
' to handle groups with more than 1000 members. Uses a recursive
' subroutine to handle nested groups. Uses a dictionary object to
' recognize duplicate group members (due to nesting).
'
' ----------------------------------------------------------------------
' Copyright (c) 2003 Richard L. Mueller
' Hilltop Lab web site - http://www.rlmueller.net
' Version 1.0 - March 28, 2003
' Version 1.1 - October 29, 2003 - Use dictionary object.
' Version 1.2 - July 31, 2007 - Escape any "/" characters in DN's.
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.

Option Explicit

Dim strNTName, objRootDSE, strDNSDomain, adoCommand
Dim adoConnection, strBase, strAttributes, objGroupList

' Check for required argument.
If (Wscript.Arguments.Count <> 1) Then
    Wscript.Echo "Required argument <NT Name> missing. " _
        & "For example:" & vbCrLf _
        & "cscript //nologo EnumGroup.vbs ""GroupNTName"""
    Wscript.Quit(0)
End If

strNTName = Wscript.Arguments(0)

' Determine DNS domain name.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("DefaultNamingContext")

' Use dictionary object to track unique group members.
Set objGroupList = CreateObject("Scripting.Dictionary")
objGroupList.CompareMode = vbTextCompare

' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open = "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Specify base of search and "member" attribute to retrieve.
strBase = "<LDAP://" & strDNSDomain & ">"
strAttributes = "member"

' Enumerate group members.
Call EnumMembers(strNTName, "")

Sub EnumMembers(ByVal strName, ByVal strOffset)
    ' Recursive subroutine to enumerate members of a group,
    ' including nested group memberships.
    ' Uses range limits to handle groups with more than 1000 members.

    Dim strFilter, strQuery, adoRecordset, objMember
    Dim strDN, intCount, blnLast, intLowRange
    Dim intHighRange, intRangeStep, objField

    ' Filter on objects of class "group" and specified name.
    strFilter = "(&(ObjectCategory=group)" _
        & "(ObjectClass=group)" _
        & "(sAMAccountName=" & strName & "))"

    ' Setup to retrieve 1000 members at a time.
    blnLast = False
    intRangeStep = 999
    intLowRange = 0
    IntHighRange = intLowRange + intRangeStep

    Do While True

        If (blnLast = True) Then
            ' If last query, retrieve remaining members.
            strQuery = strBase & ";" & strFilter & ";" _
                & strAttributes & ";range=" & intLowRange _
                & "-*;subtree"
        Else
            ' If not last query, retrieve 1000 members.
            strQuery = strBase & ";" & strFilter & ";" _
              & strAttributes & ";range=" & intLowRange & "-" _
              & intHighRange & ";subtree"
        End If
        adoCommand.CommandText = strQuery
        Set adoRecordset = adoCommand.Execute
        intCount = 0

        Do Until adoRecordset.EOF
            For Each objField In adoRecordset.Fields
                If (VarType(objField) = (vbArray + vbVariant)) _
                        Then
                    For Each strDN In objField.Value
                        ' Escape any forward slash characters, "/", with the backslash
                        ' escape character. All other characters that should be escaped are.
                        strDN = Replace(strDN, "/", "\/")
                        ' Check dictionary object for duplicates.
                        If (objGroupList.Exists(strDN) = False) Then
                            ' Add to dictionary object.
                            objGroupList.Add strDN, True

                            ' Bind to each group member, to find "class" of member.
                            Set objMember = GetObject("LDAP://" & strDN)
                            ' Output group member.
                            Wscript.Echo strOffset & "Member of " _
                                & strName & ": " & strDN
                            intCount = intCount + 1
                            If (UCase(objMember.Class) = "GROUP") Then
                                ' If the member is class "group",
                                ' call subroutine recursively.
                                Call _
                                    EnumMembers(objMember.sAMAccountName, _
                                    strOffset & "--")
                            End If
                        Else
                            ' Duplicate member. Output group member.
                            Wscript.Echo strOffset & "Member of " _
                                & strName & ": " & strDN & " (Duplicate)"
                        End If
                    Next
                End If
            Next
            adoRecordset.MoveNext
        Loop
        adoRecordset.Close

        ' If this is the last query, exit the Do While loop.
        If (blnLast = True) Then
            Exit Do
        End If

        ' If the previous query returned no members, then the previous
        ' query for the next 1000 members failed. Perform one more
        ' query to retrieve remaining members (less than 1000).
        If (intCount = 0) Then
            blnLast = True
        Else
            ' Setup to retrieve next 1000 members.
            intLowRange = intHighRange + 1
            intHighRange = intLowRange + intRangeStep
        End If
    Loop
End Sub

Open in new window


save code as EnumGroup2.vbs
to run type

cscript //nologo EnumGroup2.vbs "GroupNTName" > file.txt

Open in new window

0
Easily manage email signatures in Office 365

Managing email signatures in Office 365 can be a challenging task if you don't have the right tool. CodeTwo Email Signatures for Office 365 will help you implement a unified email signature look, no matter what email client is used by users. Test it for free!

 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 37037044
You can use for that Microsoft DS Tools on a DC or any workstation with Administrative Tools installed. Try this syntax

dsquery group -name "GroupName" | dsget group -members -expand | dsget user -fn -ln -samid >>c:\users.txt

If you're interested with DS Tools, I would recommend my blog as startup of using them at
http://kpytko.wordpress.com

Regards,
Krzysztof
0
 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 37037621
or one more way if you wish, is to use Quest PowerShell module for AD. It's completely free and much more flexible in management. First, download it from
http://www.quest.com/powershell/activeroles-server.aspx

and then use thi syntax to do that

Get-QADGroup -name "GroupName" | Get-QADGroupMember -Indirect -SizeLimit 0 | Get-QADUser | Select sAMAccountName,givenName,sn | Export-CSV c:\group-members.csv

Krzysztof
0
 
LVL 2

Author Comment

by:CTCRM
ID: 37037801
ippinto - The script has extracted a complete list of AD accounts which is good but how can I extract a list of users in a single AD Group?
0
 
LVL 2

Author Closing Comment

by:CTCRM
ID: 37055580
Very good advice, I just needed to granulate the extraction a little more.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Compliance and data security require steps be taken to prevent unauthorized users from copying data.  Here's one method to prevent data theft via USB drives (and writable optical media).
Microsoft Office 365 is a subscriptions based service which includes services like Exchange Online and Skype for business Online. These services integrate with Microsoft's online version of Active Directory called Azure Active Directory.
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Suggested Courses

616 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question