Searching the Active Directory with PowerShell


Hello world



It’s time for my second post and I thought I would talk about searching the active directory.  I ran a PowerShell course yesterday and the delegates were itching to find out a bit more about searching an AD.  So I said I would make sure I posted something on the blog.


 


So let’s get going!  To start with I`m going to introduce a script that I would be lost without: “get-dn.ps1”.  This script takes a SAM account name as input and returns the objects full CN as output.  We can then use this output to then connect directly to the object.  Here’s the code:


 









 


function get-dn ($SAMName)


{


      $root = [ADSI]”


      $searcher = new-object     System.DirectoryServices.DirectorySearcher($root)


$searcher.filter = “(&(objectClass=user)(sAMAccountName= $SAMName))”


$user = $searcher.findall()


     


if ($user.count -gt 1)


      {    


            $count = 0


            foreach($i in $user)


            {


                  write-host $count “: ” $i.path


                  $count = $count + 1


            }


            $selection = Read-Host “Please select item: “


return $user[$selection].path


      }


      else


      {


            return $user[0].path


      }


 


}


 


$Name = $args[0]


$path = get-dn $Name


“‘” + $path + “‘” 


 


 


 


So now let’s look at this code in a bit more detail. 


 


The first bit of the code simply creates a function to do most of the work.  We take an argument in $SAMName that will hold the name of the account we wish to search for


 







 


function get-dn ($SAMName)


{


 


 


The next bit of code creates 2 objects.  $root is a standard ADSI object that connects to the domain we are in.  $searcher is a DirectorySearcher object, and we pass the ADSI object $root in as a constructor.  Effectively we’re saying search the domain we’re in.


 







 


$root = [ADSI]”


$searcher = new-object System.DirectoryServices.DirectorySearcher($root)


 


 


Now we have created a DirectorySearcher object we need to set the search criteria.  To do his we use the filter property of $searcher.  See the LDAP Search Strings section below for more information.  Once we have the criteria, we simply use the findall() method to find all instances that match the filter in the domain and return the results to $user


 







 


$searcher.filter = “(&(objectClass=user)(sAMAccountName= $SAMName))”


$user = $searcher.findall()


 


 


$user actually contains a collection of objects that match the search criteria.  If we have more than one match, the collection has more than one element.  This bit of code says “If we have more than 1 result, write all the results to screen and allow the user to select which object they mean”.  The shrewd among you may think, “SAMAccountName is unique, we can’t have 2 of them”.  You’re right however, we could implement wildcard searching, or searching by surname which might result in multiple matches making this really useful.  Finally we return the path to the object.  We return the object path because it includes the “LDAP://” which we would need to connect to the object directly.


 


 







 


if ($user.count -gt 1)


{    


      $count = 0


      foreach($i in $user)


      {


            write-host $count “: ” $i.path


            $count = $count + 1


      }


      $selection = Read-Host “Please select item: “


      return $user[$selection].path


}


 


 


The last bit of the if statement simply returns the path of the 1st element, if there is only 1 element in the collection.  Then we finish of the function with a }.


 







 


else


      {


            return $user[0].path


      }


}


 


 


 


The final section simply assigns the passed in argument to the variable $Name.  We then call the get-dn function passing in $Name, and put the result in $path.  At the very end we wrap the path in a ‘ and ‘ so that you can then copy and paste the returned line straight into an [ADSI] constructor. (see the previous post)


 







 


$Name = $args[0]


$path = get-dn $Name


“‘” + $path + “‘” 


 


 


This function is really useful.  Once I have got a hit I can use the output to quickly connect to an object in the Active Directory.  I could for example type the following in PowerShell:


 







 


PS C:\store\ps scripts> .\get-dn.ps1 administrator


‘LDAP://CN=Administrator,CN=Users,DC=umpadom,DC=com’


PS C:\store\ps scripts> $user = [ADSI] ‘LDAP://CN=Administrator,CN=Users,DC=umpadom,DC=com’


PS C:\store\ps scripts> $user


 


distinguishedName


—————–


{CN=Administrator,CN=Users,DC=umpadom,DC=com}


 


 


 


DirectorySearcher Object


 


For more information on the DirectorySearcher object check out MSDN here:


 


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDirectoryServicesDirectorySearcherMembersTopic.asp


 


Some members of DirectorySearcher that you might want to look at in more detail are:


 


PageSize – this limits the amount of results that get returned, and can be really handy when you are searching big domains.


Filter – This is the search criteria that is used to search the Active Directory.  It uses LDAP search strings.  See the below section for more information


 


LDAP Search String’s


 


The DirectorySearcher filter property takes LDAP search strings.  These strings use their own language.  More information can be found here. 


 


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdirectoryservicesdirectorysearcherclassfiltertopic.asp


 


Basically, these are the four things to bear in mind when creating LDAP search strings.


1.       The string must be enclosed in parentheses.


2.       Expressions can use the relational operators: <, <=, =, >=, and >. An example is “(objectClass=user)”. Another example is “(lastName>=Davis)”.


3.       Compound expressions are formed with the prefix operators & (and) and | (or). An example is”(&(objectClass=user)(lastName= Davis))”. Another example is “(&(objectClass=printer)(|(building=42)(building=43)))”.


4.       Wildcards can be used.  Use * operator


 


 


As ever, here are some examples.  Below are some LDAP search strings that could be assigned to the DirectorySearcher.Filter property.


 


Find all users by explicit SAMName


 







 


“(&(objectClass=user)(sAMAccountName= $SAMName))”


 


 


 


Find all users where SAMName begins with xyz


 







 


“(&(objectClass=user)(sAMAccountName= $SAMName*))”


 


 


 


Find all users where Surname begins with xyz


 







 


“(&(objectClass=user)(sn= $Name*))”


 


 


 


Find all computers where computer name starts with xyz


 







 


“(&(objectClass=computer)(sAMAccountName= $ComputerName*))”


 


 


 


Well ladies and gentleman, here endeth the lesson.


 


That is all


 


BenP


 

Comments (10)

  1. Anonymous says:

    How do you search Active Directory? Here’s one way… Benp’s Guide to Stuff : Searching the Active Directory

  2. Anonymous says:

    Ladies + Gents This week I have had the privilege of working at TechEd 2007. I’ve been on the PowerShell

  3. Bob says:

    "return $user[0].path" is great and all but it only gives me the entire path.  How would I just get their name?  Like if I sent "bdb" it would return "Bob Barker"

  4. Jacob Saaby Nielsen says:

    I’m doing a script, because of the introduction of a new e-mail domain we’re going to use.

    Doing a script that needs this particular functionality, so I’m going to steal this, and modify it (I will remember to thank you when I make the script public, of course 🙂 ).

    Thanks Ben, this was just what I needed 🙂

  5. snulleyinheve says:

    Greetings, were born recently a new browser from [url=http://www.google.com/chrome/index.html?hl=en&brand=CHMI&utm_source=ru-et&utm_medium=et&utm_campaign=ru]google.com[/url]
    who it bear tried, how it to you?   Whether there is a intelligibility to vibrating бета the construction or not?  If who tried this origin, define please.

    ————————————————————————————————

    P.S.  acquit if to that sector has written, the seek of administrators to pass on a strut where you examine more correct :).

    P.P.S. On not which forums to me said, that this output apart from on some, that not so, here and has unfaltering to learn from you.

  6. cheap propecia says:

    I want to say – thank you for this!

  7. DutchFrank says:

    Bob,

    You can select the properties of an object by specifying the .properties.<propertyname> extension

    Example:

    return $user[0].properties.name  

    Returns the users name. Same works for any property of another object.

  8. Piotr says:

    Wspaniały wpis. Benp jestes wielki.

  9. Thomas says:

    We wondered what might be the fastet way to LDAP search with PowerShell and compared 3 ways.
    http://activedirectoryfaq.com/?p=1432