Summary: Search Active Directory for user and office locations by using Windows PowerShell and no scripting.
Hey, Scripting Guy! I am looking for an easy way to search Active Directory. For example, I need to find information out about users. We are moving offices in our city, and I need to find users who are in specific offices in specific cities. As soon as I know this information, I will be able to update the users to reflect the new office locations. I know this is probably too much to be asking, but hey, I am busy.
—AC
Hello AC,
Microsoft Scripting Guy Ed Wilson here. I am completely at home with busy. Luckily, the Scripting Wife is very understanding, and shares my interest in Windows PowerShell and community. Windows PowerShell is a very powerful tool, but it can also be extremely fun to use.
When I am working from my local computer, I like to use Windows PowerShell remoting to make a connection to the domain controller. In this way, I do not have to install the Remote Server Administrator Tools (RSAT) on my Windows 7 desktop. The first thing I do is enter a Windows PowerShell session on my remote computer by using the Enter-PSSession cmdlet. Next, I set my location to the C: drive so that I free up some command-line space. The final thing to do is to import the ActiveDirectory module. This is done using the Import-Module cmdlet, and using a wildcard character to shorten the module name. The commands I type to do all this are shown here:
PS C:\Users\Administrator.NWTRADERS> Enter-PSSession dc1
[dc1]: PS C:\Users\Administrator\Documents> sl c:\
[dc1]: PS C:\> Import-Module act*
After I have connected to my domain controller and loaded the ActiveDirectory module, I decide I want to find users who have an office in Charlotte. To do this, I use the Get-ADUser cmdlet and I specify the LDAPFilter parameter and provide an LDAP dialect query to the cmdlet. The advantage of the LDAP dialect queries is that it was commonly used with VBScript and Windows PowerShell 1.0 scripts to search Active Directory. There are thousands of scripts on the Internet providing samples of query syntax. After I type my query, nothing is returned. The command is shown here:
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(office=charlotte)"
The command and associated output are shown in the following figure.
I use ADSI Edit to check the attribute name. As shown in the following figure, the actual name of the attribute is PhysicalDeliveryOfficeName, and not office. The attribute page from ADSI Edit is shown in the following figure.
When I have the actual user attribute name, the LDAPFilter is easy to use. I use the syntax attribute = value. The key is that there must be no space between the attribute name and the equal sign. It is okay to have a space between the equal sign and the value, but I do not do this because it looks funny, and it is a bad habit to add spaces when not needed in LDAPFilters. The command and associated output are shown here:
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(PhysicalDeliveryOfficeName=charlotte)"
DistinguishedName : CN=Test1User1,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName : test1
Name : Test1User1
ObjectClass : user
ObjectGUID : 21c7a4d1-74a7-4f4e-a132-8f2b3e2f91ca
SamAccountName : Test1User1
SID : S-1-5-21-909705514-2746778377-2082649206-3717
Surname : user1
UserPrincipalName :
DistinguishedName : CN=Test1User2,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName :
Name : Test1User2
ObjectClass : user
ObjectGUID : a4818269-9630-42f3-83a8-4052b7630b01
SamAccountName : Test1User2
SID : S-1-5-21-909705514-2746778377-2082649206-3718
Surname :
UserPrincipalName :
Suppose I want to find users in the city of Atlanta. The ADSI attribute for city is the letter L. The following command shows how to find users in the city of Atlanta:
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(L=Atlanta)"
DistinguishedName : CN=Test1User7,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName : test1
Name : Test1User7
ObjectClass : user
ObjectGUID : ef4ef5b1-21c9-46ec-82fa-5754e11db1e5
SamAccountName : Test1User7
SID : S-1-5-21-909705514-2746778377-2082649206-3723
Surname : user7
UserPrincipalName :
DistinguishedName : CN=Test1User8,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName : Test1
Name : Test1User8
ObjectClass : user
ObjectGUID : f45123e7-9cad-49cc-830f-138c6d5b3c02
SamAccountName : Test1User8
SID : S-1-5-21-909705514-2746778377-2082649206-3724
Surname : User8
UserPrincipalName :
DistinguishedName : CN=Test1User9,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName : Test1
Name : Test1User9
ObjectClass : user
ObjectGUID : b688c597-3b1b-4a73-9e67-36b671db9774
SamAccountName : Test1User9
SID : S-1-5-21-909705514-2746778377-2082649206-3725
Surname : User9
UserPrincipalName :
I do not want all the output from my command to find users in Atlanta. I only want to see user names, the city, and their physical office locations. To do this, I decide to pipe the command output to the Select-Object cmdlet and choose the desired attributes. As shown in the following output, the city is not shown:
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(L=Atlanta)" -Properties PhysicalDeliveryOfficeName | select name, PhysicalDeliveryOfficeName, L
Name PhysicalDeliveryOfficeName L
Test1User7 alpharetta
Test1User8 Duluth
Test1User9 Alpharetta
The problem is I did not add the L attribute to the list of properties I wanted to return from Active Directory. I must add the attribute to the properties I choose to return, even if I use the attribute in my LDAPFilter.
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(L=Atlanta)" -Properties PhysicalDeliveryOfficeName, l | select name, PhysicalDeliveryOfficeName, l
Name PhysicalDeliveryOfficeName l
Test1User7 alpharetta Atlanta
Test1User8 Duluth Atlanta
Test1User9 Alpharetta Atlanta
I can change my query to return only users who have the city of Atlanta and their office in Duluth. To do this, I need to create a compound LDAP filter. As shown earlier, each attribute equals value pairing is placed inside a pair of parentheses. When I add another attribute equals value pair, I must also put that inside a pair of parentheses. To state I want to look for one attribute value pair and another attribute value pair, I use an ampersand before the first pair, and surround the entire set with another pair of parentheses. The following query illustrates this technique:
[dc1]: PS C:\> Get-ADUser -LDAPFilter "(&(L=Atlanta)(PhysicalDeliveryOfficeName=Duluth))"
DistinguishedName : CN=Test1User8,OU=test1,DC=nwtraders,DC=com
Enabled : False
GivenName : Test1
Name : Test1User8
ObjectClass : user
ObjectGUID : f45123e7-9cad-49cc-830f-138c6d5b3c02
SamAccountName : Test1User8
SID : S-1-5-21-909705514-2746778377-2082649206-3724
Surname : User8
UserPrincipalName :
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy