Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to grab out some information from Active Directory using Powershell, but I get some strange behavior. Here's my script:

$toFind = ( 'bobjones', 'samsmith' )

filter Get-AdUser {
    $strFilter = "(&(objectCategory=User)(sAMAccountName=$_))"

    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.PageSize = 1000
    $objSearcher.Filter = $strFilter

    $colProplist = ("name", "department")
    foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

    ($objSearcher.FindAll() | %{$_.Properties})
}

"paul" | get-aduser # Works
$toFind | get-aduser # Doesn't work?!

The former prints out what I expect, a table of properties; the latter ends up just printing "0 1" repeatedly though I'm not sure why. Why would the single case work but not the array?

share|improve this question

5 Answers 5

up vote 0 down vote accepted

What you want to do is query the Global Catalog since you want to search across the entire forest. There are a couple of approaches but the simplest is to change your search root to the GC. e.g.

$objSearcher.SearchRoot = [ADSI]"GC://$($objDomain.Name)"

Alternatively you can query the forest and then ask it for a list of Global Catalogs and use one of those as the initial Directory Entry but this is a simple enough change that will do what you want provided the fields you are searching are in the GC. The search part shouldn't be a problem in your case as you are searching by Username which is global by default but you wont get the Department field back from the search result result because Department is not global by default. To get it you will need to use the Distinguished Name from the search result to do a subsequent AD lookup against the users domain for the full AD user object and then pull the Department out of that. You could change your schema so that Department is global but that would be a bit radical IMO.

You can find the comprehensive list of the default global attributes here.

share|improve this answer

FYI, the reason you get the output of 0 and 1 is because the call to $objSearcher.PropertiesToLoad.Add() returns the index of the property that was added (0 for the first property, 1 for the second). This will happen once for each user in your script. You can suppress the return value by piping it to Out-Null.

share|improve this answer

Figured it out, it has nothing to do with PowerShell. When you create the DirectoryEntry:

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

It will return results for your domain only (i.e. if you have an AD forest like "NorthAmerica" and "Europe", it'll only query the one you're in). It just happened that all of the names I was searching for were in another domain.

If you use the constructor to manually specify the Domain, it works pretty well (still haven't figured out how to query all domains yet though...)

share|improve this answer
    
No wonder my single domain returned proper results. I didn't know you were browsing a forest. –  Marcus Jul 10 '09 at 22:12

Just a sidenote: I would heavily recommend looking into the Quest AD cmdlets package (http://www.quest.com/powershell/activeroles-server.aspx) for all AD-related powershell things. It fills a hole as the builtin AD Support in powershell is pretty crappy. It will save you lots of development time.

share|improve this answer
    
Agreed. Quest's AD cmdlets are awesome for obfuscating all the .NET calls and getting to the meat of what you want like "get-qaduser jdoe". They do have some drawbacks in that they don't expose every property of the object. However, the properties that it does grab are sufficient for most administrative tasks. –  Marcus Jul 10 '09 at 22:15

You may have to specify a foreach loop like foreach ($user in $toFind) { get-aduser $user }

What happens if you simply type $toFind at the prompt? I'm assuming it would list both names, one per line, like it should.

I tried running this same code against my AD and got the following results: 0 1

Name Value ---- ----- name {Sahnti L. Aphil} adspath {LDAP://CN=Sahnti L. Aphil,OU=Users,OU=Jackson,DC=company,DC=local} 0 1 name {Hamong Justice} adspath {LDAP://CN=Hamong Justice,OU=Users,OU=Jackson,DC=company,DC=local}

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.