ADSI Query to filter out machine accounts in the domain

  • Thread starter Thread starter Prasad Karunakaran
  • Start date Start date
P

Prasad Karunakaran

I have the following C# code to enumerate the list of groups in a
domain using ADSI. The problem is if the domain contains machine
accounts ($) it get those accounts too.

Can somebody help me here to filter out the machine accounts so that I
get only the NT group objects.

public ArrayList GetNTGroups()
{
DirectoryEntry ntDirectoryGroups = null;
try
{
ntDirectoryGroups = new DirectoryEntry(bindNTDomainPath,
bindNTUser, bindNTPassword);
ArrayList groupsArray = new ArrayList();
foreach(DirectoryEntry group in ntDirectoryGroups.Children)
{
switch(group.SchemaClassName.ToLower())
{
case "group" :
groupsArray.Add(group.Name);
break;
default :
break;
}
}
groupsArray.Sort();
return groupsArray;
}
catch(COMException ex)
{
return null;
}
finally
{
ntDirectoryGroups.Dispose();
}
}

Thanks,

Prasad
 
Willy,
It is an Active Directory domain. Thanks for your help.

regards,

Prasad
 
Ok just to be sure :-)

Use a directorySearcher with a filter...

ntDirectoryGroups = new DirectoryEntry(bindNTDomainPath,bindNTUser,
bindNTPassword);

src = new DirectorySearcher();
// specify properties to load
string[] props = {"cn", more properties};
src.PropertiesToLoad.AddRange(props);
src.SearchRoot = ntDirectoryGroups;
src.SearchScope = SearchScope.Subtree;
// return all groups except "domain computers" and "domain controllers" and
.......
src.Filter = "(&(objectCategory=group)(!cn=domain computers)(!cn=domain
controllers))";
SearchResultCollection res = src.FindAll();
// process the objects in the collection
foreach(SearchResult sc in res) {
.....

Willy.
 
src = new DirectorySearcher();
// specify properties to load
string[] props = {"cn", more properties};
src.PropertiesToLoad.AddRange(props);
src.SearchRoot = ntDirectoryGroups;
src.SearchScope = SearchScope.Subtree;
// return all groups except "domain computers" and "domain controllers" and
......
src.Filter = "(&(objectCategory=group)(!cn=domain computers)(!cn=domain
controllers))";


You probably didn't really mean to specify !cn= filter, right?
Shouldn't that be !objectCategory= instead??

src.Filter = "(&(objectCategory=group)(!objectCategory=domain
computers)(!objectCategory=domain controllers))";

Marc
================================================================
Marc Scheuner May The Source Be With You!
Bern, Switzerland m.scheuner(at)inova.ch
 
Marc,
Not really, "DomainCoputers" and "Domain controllers" are no
objectCategories.
"computer" is a objectCategory but this won't help to filter on this when
searching on 'group' as they are part of container (just like group).

Willy.

Marc Scheuner said:
src = new DirectorySearcher();
// specify properties to load
string[] props = {"cn", more properties};
src.PropertiesToLoad.AddRange(props);
src.SearchRoot = ntDirectoryGroups;
src.SearchScope = SearchScope.Subtree;
// return all groups except "domain computers" and "domain controllers"
and
......
src.Filter = "(&(objectCategory=group)(!cn=domain computers)(!cn=domain
controllers))";


You probably didn't really mean to specify !cn= filter, right?
Shouldn't that be !objectCategory= instead??

src.Filter = "(&(objectCategory=group)(!objectCategory=domain
computers)(!objectCategory=domain controllers))";

Marc
================================================================
Marc Scheuner May The Source Be With You!
Bern, Switzerland m.scheuner(at)inova.ch
 
Not really, "DomainCoputers" and "Domain controllers" are no
objectCategories.

Okay - there is one for server or domain controllers, no?

Then - what good does the !cn=domain controllers filter really do?
Will this exclude all the subobjects in that container?

Marc
================================================================
Marc Scheuner May The Source Be With You!
Bern, Switzerland m.scheuner(at)inova.ch
 
Marc,
No the objectCategories are:
builtinDomain, computer, contact, container, domain, domainDNS,
lostAndFound,
group,organizationalUnit, organizationalPerson, person, secret, user and a
few more which I can't remember for now), but "domain controllers" and
"domain computers" are account groups ; respectively - 'security enabled
universal group' and 'security enabled account group' types (see, there is
no difference between computer accounts and user accounts in AD).
So, when using group as filter all group types will be returned in the
collection, to exclude some group types you will have to use some constraint
based on a group property like cn.

When using "(&(objectCategory=group)(!cn=domain computers)(!cn=domain
controllers))"; as filter the SearchResultCollection will contain all groups
except the groups cn=domain computers and cn=domain controller.

Willy.
 
Willy,
I tried the code you proposed. The code works great with AD. I use
the LDAP provider ("LDAP://DomainName") in the domain path when I
create the DirectoryEntry() object.

I tried using the same code for a NT domain. I changed the provider to
WinNT
("WinNT://DomainName") in the domain path and use a domain user
account while creating DirectoryEntry() object

I get an expection in the following line

SearchResultCollection res = src.FindAll()

The exception message : "The provider does not support searching and
cannot search WinNT://corp.aspentech.com"
Error Code : 0x80131515

How should I change the code to work for a NT domain ?. Basically I
have to support enumerating NT groups (expect machine accounts) in
both NT Domain and AD domain. As you know WinNT provider is supported
in AD for backward compatibility.


Thanks for your help.

regards,

Prasad
 
I tried the code you proposed. The code works great with AD. I use
the LDAP provider ("LDAP://DomainName") in the domain path when I
create the DirectoryEntry() object.

I tried using the same code for a NT domain. I changed the provider to
WinNT ("WinNT://DomainName") in the domain path and use a domain user
account while creating DirectoryEntry() object

I get an expection in the following line
The exception message : "The provider does not support searching and
cannot search WinNT://corp.aspentech.com"
Error Code : 0x80131515

How should I change the code to work for a NT domain ?.

In short - you can't.

From the MSDN docs:

"Use a DirectorySearcher to search and perform queries against an
Active Directory hierarchy using the Lightweight Directory Access
Protocol (LDAP). LDAP is the only system-supplied Active Directory
Service Interfaces (ADSI) provider that supports directory searching."

DirectorySearcher does *NOT* support WinNT.

Marc
================================================================
Marc Scheuner May The Source Be With You!
Bern, Switzerland m.scheuner(at)inova.ch
 
Marc,
Thanks for your reply. In that case can I use LDAP Provider instead
of WinNT provider to enumerate group objects, filter out machine
accounts for both a NT domain and AD domain. To be specific does LDAP
Provider support NT domains?

regards,

Prasad
 
Prasad,

No the LDAP provider talks to the LDAP server, and NT has no such beast.

Willy.
 
Willy,
If this is the case I have to use WinNT provider in my code as my
application has to support both NT and AD domains.

Could please help me fix my C# code (refer the first thread) which
enumerates groups objects in a domain using WinNT Provider and
filters out machine accounts.

Thanks again for your help.

regards,

Prasad
 
Back
Top