Learn about Windows PowerShell
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! 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...
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.
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).
New-PSDrive -PSProvider activedirectory -Name charlotte -Root "AD:\ou=Charlotte,DC=Iammred,DC=net"
dir | ? objectclass -eq user
The commands and the output associated with the commands are shown in the image that follows.
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
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 *
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 *
Teresa Wilson user CN=Teresa Wilson,ou=Charlotte,DC=Iammre...
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
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 firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
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 -_-
how to check if I can enumerate an AD object property, usually if I don't access no error code is generated
Lars Panzerbjørn: try this
$search = [System.DirectoryServices.DirectorySearcher]$root
$search.Filter = "(SAMACCOUNTNAME=$User)"
$result1 = $search.FindOne()
$arr= $UserDN -split $thestring
Instead of using older and more error proneVBScript methods try using PowerShell native techniques. Thisis easier andmuch more powerful.
$user = ($searcher.FindOne()).GetDirectoryEntry()
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.
for more info about manipulating AD objects try this
$ADSIObject.PSBase | gm