Find Active Directory User Info with the PowerShell Provider


Summary: Microsoft Scripting Guy, Ed Wilson, talks about how to use the Windows PowerShell provider to find user information in Active Directory.

Hey, Scripting Guy! Question Hey, Scripting Guy! I often need to find information in Active Directory, but I do not like having to write LDAP queries. To me, it is soooo last century—I mean, Fred Flintstone used to write LDAP queries. I love the way that…

—CH

Hey, Scripting Guy! Answer Hello CH,

Microsoft Scripting Guy, Ed Wilson, is here. CH, I know what you mean. I loved my first computer, but I have no desire to go back to using the CPM operating system. Luckily, with the Active Directory module provider, I have direct access to an AD: drive. This makes it easy to use Windows PowerShell to explore. Because of the Active Directory module provider, and the way that Windows PowerShell providers work, I need no special Active Directory Domain Services (AD DS) knowledge. In fact, I can use the same commands that I would use if I was exploring the file system, the registry, the environmental variables, or even the variable drive. Windows PowerShell abstracts the underlying data and permits me to use a file system analogy to work with the data.

Note   This is the second in a series of blogs about working with the Active Directory module provider. You should definitely read Playing with the AD: Drive for Fun and Profit prior to reading today’s blog because I am going to build on everything that went before.

Filtering by using the Where-Object cmdlet

The cool thing about the AD: drive is the ability to use standard Windows PowerShell cmdlets to find and to filter the AD DS data. In the example that follows, I import the Active Directory module, create a Windows PowerShell drive that exposes Charlotte organizational unit (OU) information, and filter out only the users from the OU. The commands is shown here (ipmo is an alias for Import-Module, sl is an alias for Set-Location, dir is an alias for Get-Childitem, and ? is an alias for Where-Object).

ipmo activedirectory

New-PSDrive -PSProvider activedirectory -Name charlotte -Root “AD:\ou=Charlotte,DC=Iammred,DC=net”

sl charlotte:

dir

dir | ? objectclass -eq user

The commands and the output associated with the commands are shown in the image that follows.

Image of command output

Finding a specific user

To find a specific user, I again use Where-Object. I have a couple of choices to use when filtering for the contact. I can use the Name property or the DistinguishedName property. Because the Name property is shorter and requires less typing, I use that one as shown here.

PS charlotte:\> dir | ? name -match ‘ed wilson’

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 CN=ed wilson,OU=Charlotte,DC=iammred,DC…

If I would like to directly access the user object instead of filtering to find the user object, I need to use the DistinguishedName attribute. But it is not as bad as it might sound. This is because the DistinguishedName property becomes the path to the object.

I discovered this when I tried to use Get-Item to access the user object. Normally, a property such as Name would what I would expect to use to find an object. In fact, that is what I did in my Where-Object command–I filtered on a value for the Name attribute. When I use the name of the user in my Get-Item command to retrieve a user, an error message appears. This command and the message are shown here.

PS charlotte:\> Get-Item ‘ed wilson’

Get-Item : Cannot find path ‘charlotte:\ed wilson’ because it does not exist.

At line:1 char:1

+ Get-Item ‘ed wilson’

+ ~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (charlotte:\ed wilson:String) [Get-Item], ItemNotFoundException

    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Note that the error message is ObjectNotFound, and the FullyQualifiedErrorId is PathNotFound. Therefore, Get-Item is attempting to look for a path to an object and is not finding it. In fact, whenever I use Get-Item, I must specify a path to the object. For example, if I want to retrieve a log file, I specify the path. This is shown here.

PS C:\> Get-Item C:\fso\20110314.log

If I am already in the C:\fso folder, a period can be used to take the place of the C:\fso portion of the path—but still, I must specify a path. This is shown here.

PS C:\fso> get-item .\20110314.log

If I think of OU=Charlotte, DC=Iammred, and DC=NET as folders (or directories), the file system analogy works. The DistinguishedName attribute is the full path to the object. Therefore, if I am in the OU=Charlotte folder, I only need to specify the last portion of the DistinguishedName attribute. This technique is shown here.

PS charlotte:\> Get-Item .\’cn=ed wilson’

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 cn=ed wilson,ou=Charlotte,DC=Iammred,DC…

Luckily, the Active Directory module provider does not require the .\—therefore, I can drop it as shown in this example.

PS charlotte:\> Get-Item ‘cn=ed wilson’

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 cn=ed wilson,ou=Charlotte,DC=Iammred,DC…

Filtering directly by using Get-Item

Because the Get-Item cmdlet supports the use of the Filter parameter, I can easily create a filter to find a specific user. All I need to do is to specify a value for the Name attribute and use a wildcard character for the path. This technique is shown here when I am on the Charlotte Windows PowerShell drive.

PS charlotte:\> Get-Item -Filter “name=ed wilson” -Path *

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 CN=ed wilson,ou=Charlotte,DC=Iammred,DC…

The cool thing is that I can even filter for properties not normally returned. So for example, I can find users who have a city value of Charlotte (the lowercase L is the LDAP attribute). This technique is shown here.

PS charlotte:\> Get-Item -Filter “l=charlotte” -Path *

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 CN=ed wilson,ou=Charlotte,DC=Iammred,DC…

Teresa Wilson        user                 CN=Teresa Wilson,ou=Charlotte,DC=Iammre…

Performing a recursive search by using Get-ChildItem

Perhaps I want to search for users that have a city value of Charlotte, but I do not know in which OU they reside. To do this, I can use the Get-ChildItem cmdlet and use the Recurse parameter.

PS AD:\dc=iammred,dc=net> Get-ChildItem -Filter “l=charlotte” -Path * -Recurse

 

Name                 ObjectClass          DistinguishedName

—-                 ———–          —————–

ed wilson            user                 CN=ed wilson,OU=Charlotte,dc=iammred,dc…

Teresa Wilson        user                 CN=Teresa Wilson,OU=Charlotte,dc=iammre…

MyNewUser            user                 CN=MyNewUser,OU=MyTestOU,dc=iammred,dc=net

CH, that is all there is to using the Active Directory module provider in Windows PowerShell to find user information. Active Directory Week will continue tomorrow when I will talk about finding and modifying user information.

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 

Comments (9)

  1. jrv says:

    @Lars

    The OU of any object is the "parent" property.  Of course it may also be a "container" or a "folder" or an object.  FOr most users it is an OU unless they are in "User" which is not an OU.

  2. jrv says:

    @samtheman

    Instead of using older and more error proneVBScript methods try using PowerShell native techniques.  Thisis easier andmuch more powerful.

    $accountid="SamTheMan"

    $searcher=[adsisearcher]"(samaccountname=$accountid)"

    $user = ($searcher.FindOne()).GetDirectoryEntry()

    $UserDN=$user.distinguishedName[0]

    $USERCN=$user.cn[0]

    $ou=$User.Parent

  3. Lars Panzerbjørn says:

    That is useful, but how would I get just the OU a user is in so I can pipe it to elsewhere in a script?

    I am trying to make a script that places new users in the same OU as their manager, but I can't figure out how to get that info -_-

  4. Sam The Man says:

    how to check if I can enumerate an AD object property, usually if I don't access no error code is generated

  5. Sam The Man says:

    Lars Panzerbjørn: try this

    $User="SamTheMan"

    $Dom="Company.com"

    $root=[ADSI]"LDAP://$Dom/DC=Company,DC=com"

    $search = [System.DirectoryServices.DirectorySearcher]$root

    $search.Filter = "(SAMACCOUNTNAME=$User)"

    $result1 = $search.FindOne()  

    $useADSI= [adsi]$result1.path

    $UserDN=[string]$useADSI.distinguishedName

    $USERCN=[string]$useADSI.cn

    $thestring=[string]"CN=$USERCN,"

    $arr= $UserDN -split $thestring

    $OU=$arr[1]

  6. SAM The Man says:

    Also:

    $user.PSBase.Parent

    $user.Parent

  7. SAM The Man says:

    for more info about manipulating AD objects try this

    $ADSIObject.PSBase | gm

  8. Steve says:

    Please provide script ti list whole active users list in Active diractory

Skip to main content