开发者

Network utilization - AccountManagement vs. DirectoryServices

I spend more than a day to find out that the Principal object is using way more bandwidth than the using the DirectoryServices. The scenario is like this. I have a group with ~3000 computer objects in it. To check if a computer is in this group I retrieved the GroupPrincipal and searched for the ComputerPrincipal.

        Boolean _retVal = false;
        PrincipalContext _principalContext = null;
        using (_principalContext = new PrincipalContext(ContextType.Domain, domainController, srv_user, srv_password)) {
            ComputerPrincipal _computer = ComputerPrincipal.FindByIdentity(_principalContext, accountName);

            GroupPrincipal _grp = GroupPrincipal.FindByIdentity(_principalContext, groupName);
            if (_computer != null && _grp != null) {
                // get the members
                PrincipalSearchResult<Principal> _allGrps = _grp.GetMembers(false);
                if (_allGrps.Contains(_computer)) {
                    _retVal = true;
                }
                else {
                    _retVal = false;
                }
            }
        }
        return _retVal;

Actually very nice interface but this creates around 12MB traffic per request. If you're domain controller is in the LAN this is no issue. If you access the domain controller using the WAN it kills your connection/application.

After I noticed this I re-implemented the same functionality using DirectoryServices

Boolean _retVal = false;
DirectoryContext _ctx = null;
try {
    _ctx = new DirectoryContext(DirectoryContextType.DirectoryServer, domainController, srv_user, srv_password);
} catch (Exception ex) {
    // do something useful
}
if (_ctx != null) {
    try {
        using (DomainController _dc = DomainController.GetDomainController(_ctx)) {
            using (DirectorySearcher _search = _dc.GetDirectorySearcher()) {
                String _groupToSearchFor = String.Format("CN={0},", groupName);
                _search.PropertiesToLoad.Clear();
                _search.PropertiesToLoad.Add("memberOf");
                _search.Filter = String.Format("(&(objectCategory=computer)(name={0}))", accountName); ;
                SearchResult _one = nul开发者_开发知识库l;
                _one = _search.FindOne();
                if (_one != null) {
                    int _count = _one.Properties["memberOf"].Count;
                    for (int i = 0; i < _count; i++) {
                        string _m = (_one.Properties["memberOf"][i] as string);
                        if (_m.Contains(groupName)) { _retVal = true; }
                    }
                }
            }
        }
    } catch (Exception ex) {
        // do something useful
    }
}
return _retVal;

This implementation will use around 12K of network traffic. Which is maybe not as nice but saves a lot of bandwith.

My questions is now if somebody has an idea what the AccountManagement object is doing that it uses so much bandwith?

THANKS!


I would guess including the following lines will do a lot to save bandwidth:

_search.PropertiesToLoad.Clear();
_search.PropertiesToLoad.Add("memberOf");
_search.Filter = String.Format("(&(objectCategory=computer)(name={0}))", accountName);

The first two are telling the DirectorySearcher to only load a single property instead of who knows how many, of arbitrary size.

The second is passing a filter into the DirectorySearcher, which I guess is probably processed server side, further limiting the size of your result set.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜