Learn about Windows PowerShell
Hey, Scripting Guy! How can I enumerate all the objects in an Active Directory OU?-- RB
Hey, RB. By the way, thanks: it’s always nice to get an easy question every once in awhile! Enumerating all the objects in an OU is almost embarrassingly-simple: by default, any time you bind to an OU using ADSI you automatically get back a collection of all the objects in that OU. To enumerate those objects, all you have to do is create a For Each loop that walks through the collection.
Don’t believe us? Well, here’s a script that binds to the Servers OU in a domain named fabrikam.com. After making the connection, the script enters a For Each loop that displays the CN (common name) of every item in that collection, and thus every object in the OU:
Set colItems = GetObject _ ("LDAP://ou=Servers, dc=fabrikam, dc=com") For Each objItem in colItems Wscript.Echo objItem.CN Next
It really is that simple. To adapt this script for use in your domain, just change the binding string accordingly. For example, suppose you want to connect to the Finance OU in contoso.com. Your script would look like this:
Set colItems = GetObject _ ("LDAP://ou=Finance, dc=contoso, dc=com") For Each objItem in colItems Wscript.Echo objItem.CN Next
Two things to keep in mind here. First, remember that neither Users nor Computers (the default locations for user and computer accounts) are actually OUs; technically, these two entities are known as “containers.” That means you can’t bind to either of these containers using a binding string like thus:
ou=Users, dc=fabrikam, dc=com
That’s not going to work. Instead, you’ll have to reference the CN, like so:
cn=Users, dc=fabrikam, dc=com
Second, there will often be times when you want to enumerate only a subset of items found in an OU; for example, you might want to get back a list of just the user accounts or just the computer accounts. To do that, bind to the OU, then add a filter. For example, this script returns only a list of the computer objects found in the Servers OU. How do we know that it returns only computer objects? Note the Filter, which specifies just one item: Computer.
Set colItems = GetObject _ ("LDAP://ou=Servers, dc=fabrikam, dc=com") colItems.Filter = Array("Computer") For Each objItem in colItems Wscript.Echo objItem.CN Next
Notice, too, that items included in the Filter have to be passed as an array, even if (as is the case here) you’re only filtering on one thing. Because items are passed as an array, this means you can filter on multiple items. Need a script that returns both user and computer accounts? All you had to do was ask:
Set colItems = GetObject _ ("LDAP://ou=Servers, dc=fabrikam, dc=com") colItems.Filter = Array(“User”, "Computer") For Each objItem in colItems Wscript.Echo objItem.CN Next
this is great to know. however i would like to know if i skip few OU's while enumerating Users. For example, i would not like users from CN=Users container and other OU's that i would not like to scan.
Is there a VBscript method to emurate all users in AD except a few OU's
thanks much
Anand Rao
We had Microsoft add two fields to Active Directory. One called Emp-IDType and one called physicalDeliveryOfficeName. No matter what I try I cannot get the code below to return the data contained in Emp-IDType container. Is this due to the fact that the name contains a "-" symbol? Or is my coding incorrect? Field not being returned is the "Test" field at the end. LDAP browser show the field as existing in AD as Emp-IDType and various LDAP browser have no problem displaying the contents of the field, but I can't get it to export to a CSV file so I can load an Oracle table with the data.
Below is the Code
' ===============================================================
' This VBS script reads the Avista Corp Active Directory and extracts the
' data for Users and creates an output file called 'AVISTAUSERS.TXT'
' on the output of drive "D" in the apps\pervasive\intmgr_Temp_Files
'
' Data Integration task will then take the temp file and create the oracle
' table for importing into Cognos
On Error Resume Next
Dim oContainer
Dim OutPutFile
Dim FileSystem
' Initialize global variables
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set OutPutFile = FileSystem.CreateTextFile("D:\apps\pervasive\intmgr_temp_files\AvistaUsers1.txt", True)
Set oContainer=GetObject("LDAP://CN=users,DC=c00,DC=corp,DC=com")
' Enumerate Container
EnumerateUsers oContainer
' Clean up
OutPutFile.Close
Set FileSystem = Nothing
Set oContainer = Nothing
' WScript.Echo "Finished Exporting AD Entries"
WScript.Quit(0)
Sub EnumerateUsers(oCont)
Dim oUser
For Each oUser In oCont
Select Case LCase(oUser.Class)
Case "user"
' Account Name (UserID)
If Not IsEmpty(oUser.sAMAccountName) Then
OutPutFile.Write oUser.sAMAccountName & "|"
else
OutPutFile.Write " " & "|"
End If
' GivenName (First Name)
If Not IsEmpty(oUser.givenName) Then
OutPutFile.Write oUser.givenName & "|"
' SN (Last Name)
If Not IsEmpty(oUser.sn) Then
OutPutFile.Write oUser.Get ("sn") & "|"
' Title
If Not IsEmpty(oUser.title) Then
OutPutFile.Write oUser.title & "|"
' Department
If Not IsEmpty(oUser.department) Then
OutPutFile.Write oUser.department & "|"
' Location
' MailStop
' Manager
If Not IsEmpty(oUser.manager) Then
OutPutFile.Write oUser.manager & "|"
' Company
If Not IsEmpty(oUser.company) Then
OutPutFile.Write oUser.company & "|"
' Telephone Number (Business Phone)
If Not IsEmpty(oUser.telephoneNumber) Then
OutPutFile.Write oUser.telephoneNumber & "|"
' Mobile Phone
If Not IsEmpty(oUser.mobile) Then
OutPutFile.Write oUser.mobile & "|"
' Pager
If Not IsEmpty(oUser.pager) Then
OutPutFile.Write oUser.pager & "|"
' Fax Number
If Not IsEmpty(oUser.facsimileTelephoneNumber) Then
OutPutFile.Write oUser.facsimileTelephoneNumber & "|"
' Home Phone
If Not IsEmpty(oUser.homePhone) Then
OutPutFile.Write oUser.homePhone & "|"
' Email
If Not IsEmpty(oUser.Mail) Then
OutPutFile.Write oUser.Mail & "|"
' Other Pager ()
If Not IsEmpty(oUser.otherPager) Then
OutPutFile.Write oUser.otherPager & "|"
' User Account Control ()
If Not IsEmpty(oUser.UserAccountControl) Then
OutPutFile.Write oUser.UserAccountControl & "|"
' Physical Delivery Office ()
If Not IsEmpty(oUser.physicalDeliveryOfficeName) Then
OutPutFile.Write oUser.physicalDeliveryOfficeName & "|"
' Other Employee Number()
If Not IsEmpty(oUser.EmployeeID) Then
OutPutFile.Write oUser.EmployeeID & "|"
' Test
If Not IsEmpty(oUser.Emp-IDType) Then
OutPutFile.Write oUser.Emp-IDType & "|"
Outputfile.writeline
Case "organizationalunit", "container"
EnumerateUsers oUser
End Select
' OutPutFile.WriteLine
Next
End Sub
Any suggestions would be appreciated as I can't seem to get the contents of this container to work. If I comment out the TEST segment, it extracts all data for all Users currently in AD.
@raoan04 you can change the search location target, or you can use an if ... then statement to skip the OU you do not want to scan.
@chuck I do not see emp-idtype in the AD schema, nor in adsiedit. I do, however, see employeeType.