View Single Post
Old 07-04-2009   #8 (permalink)
Richard Mueller [MVP]


 
 

Re: Map network printers based on OU user is in within Active Dire

I often suggest binding to the group object and using the IsMember method
because it is the most straightforward approach. It is not the most
efficient unless you have only one or two groups to check.

The slowest step in any script is binding to objects in AD. Binding to local
objects, like the dictionary object, is much faster. The method that binds
to the fewest objects in AD should be the fastest.

Using the Groups method of the user object is very convenient. You get an
object reference for every group, so you can retrieve any attribute desired.
However, the method must bind to each group object.

Also, using the WinNT provider has the following disadvantages:

1. It is slower (I don't know why).
2. It cannot reveal nested domain group membership.
3. It reveals fewer attributes (although that generally doesn't matter in
logon scripts).

A better approach is to enumerate the memberOf attribute exposed by the LDAP
provider. This is a collection of group DN's (Distinguished Names) the user
belongs to (direct group membership). It does not include the "primary"
group of the user. You must compare the group DN, but you only bind to the
user object, not to the group objects. I keep track of the group DN's in a
dictionary object, so they only need to be enumerated once. If you want to
compare with group sAMAccountName's (pre-Windows 2000 names), use the
NameTranslate object. This is much more efficient than binding to the group
object so you can retrieve sAMAccountName. For information on NameTranslate
see this link:

http://www.rlmueller.net/NameTranslateFAQ.htm

If you enumerate memberOf and need to account for group nesting, you still
need to bind to the group objects. In that case, it might be more efficient
to use ADO to retrieve all group objects where the member attribute matches
the DN of the user. You can retrieve the group DN or sAMAccountName. You can
search with ADO recursively to retrieve all memberships due to nesting. I
have an example linked here:

http://www.rlmueller.net/IsMember7.htm

One query is required for each level of group nesting, but the server
returns all of the information requested in each query in one operation.

Another method if you need to check nested groups is the tokenGroups
attribute of the user. This is a collection of group SID's. It includes all
security group memberships, including the "primary" group and all
memberships due to group nesting. It does not include security groups. The
problem is that you must bind to the corresponding objects to retrieve the
group names. This method is marginally more efficient that enumerating the
memberOf attribute and binding to each group.

--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--

"Mark D. MacLachlan" <markdmac@xxxxxx> wrote in message
news:OEKV5JI$JHA.1608@xxxxxx
Quote:

> Hi Richard,
>
> We have a similar approach in both favoring using groups to assign
> printers. I've noticed though that you seem to prefer to bind to each
> group so you can use IsMember where I prefer to bind to the user and
> enumerate the groups they are a member of.
>
> http://www.tek-tips.com/faqs.cfm?fid=5798
>
> I'm wondering if you have any opinion on which might perform faster.
> I'm thinking that binding to a single object and then iterating through
> the array of groups would be quicker but that will really depend on how
> many groups a user is a member of. Coding wise, I think using a Select
> Case is easier than a whole bunch of If Then statements.
>
> So, I see advantages to both approaches and welcome your expert opinion.
>
> Regards,
>
> Mark D. MacLachlan

My System SpecsSystem Spec