kamagra how much to take

AccountManagement, PrincipalContext, Principals, And Performance

Often times in trivial AD operations using the *.AccountManagement namespace there is a performance hit in comparison to using ASQ approaches. This has been pretty frustrating to me in the past, as detailed here. In my journeys with these objects though I have determined a better approach. Let’s take the examples from the previous post two methods, GetUser and Get Group. To make these more efficient, we are going to use a combination of PrincipalContext, *Principal, and PrincipalSearcher objects along with a materialized Dictionary object in order to speed things up a bit.

Enough with the filler, let’s look at some code. What we are going to do is create a new PrincipalContext (the static method to hydrate this is discussed in the aforementioned post), then create a new *Principal object consuming the hydrated PrincipalContext in the constructor. The *Principal object will subsequently use the SamAccountName property with a wild card as a search parameter. This *Principal object is then passed into the constructor of a new PrincipalSearcher object so the principal search results can be returned using stuff like FindAll and FindOne. Once the PrincipalSearcher is well formed, we execute a FindAll, ToList to a strongly typed collection with IQueryable support, which allows us to execute a Where clause. The clause leveraged a Regular Expression (ala Regex.IsMatch), and the results are collated in a Dictionary(Of TKey, TValue) according to a specified key selector function. Once the Dictionary is built, a simple if clause is inserted which allows us to find, and return, the object we want! Comparative times of query have shown this cuts down on query time BY 5 TIMES!!!!!!! 

Firstly, the modified GetUser method:

  1. public static UserPrincipal GetUser(string userName)
  2. {
  3. UserPrincipal userPrincipal = null;
  4. SPSecurity.RunWithElevatedPrivileges(() =>
  5. {
  6. PrincipalContext principalContext = GetUserPrincipalContext();
  7. var search = new UserPrincipal(principalContext);
  8. search.SamAccountName = userName + '*';
  9. var ps = new PrincipalSearcher(search);
  10. var pr = ps.FindAll().ToList().Where(a =>
  11. Regex.IsMatch(a.SamAccountName, String.Format(@"{0}\D", userName))).
  12. ToDictionary(a => a.SamAccountName);
  13. pr.Add(userName, Principal.FindByIdentity(principalContext, IdentityType.SamAccountName, userName));
  14. if (pr.ContainsKey(userName))
  15. {
  16. userPrincipal = (UserPrincipal)pr[userName];
  17. }
  18. });
  19. return userPrincipal;
  20. }

And the GetGroup method:

  1. public static GroupPrincipal GetGroup(string groupName)
  2. {
  3. GroupPrincipal groupPrincipal = null;
  4. SPSecurity.RunWithElevatedPrivileges(() =>
  5. {
  6. PrincipalContext principalContext = GetGroupPrincipalContext();
  7. var search = new GroupPrincipal(principalContext);
  8. search.SamAccountName = groupName + '*';
  9. var ps = new PrincipalSearcher(search);
  10. var pr = ps.FindAll().ToList().Where(a =>
  11. Regex.IsMatch(a.SamAccountName, String.Format(@"{0}\D", groupName))).
  12. ToDictionary(a => a.SamAccountName);
  13. pr.Add(groupName, Principal.FindByIdentity(principalContext, IdentityType.SamAccountName, groupName));
  14. if (pr.ContainsKey(groupName))
  15. {
  16. groupPrincipal = (GroupPrincipal) pr[groupName];
  17. }
  18. });
  19. return groupPrincipal;
  20. }

The first thing you should notice is that these could be placed in a static method of the PrincipalContext as an extension, which would be a whole lot more succint, but I was just happy I got it to work. I’ll leave that up to someone else.

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>