Skip to main content

Trouble using the AdvancedFilterSet with the “whenCreated” active directory property

Over the last couple of days on my current project I have been working with the new account management API found in .NET 3.5 for communicating with active directory. This API is a massive improvement over the features provided by the older directory services and really does make creating, deleting, updating and finding users a lot simpler (for more information checkout http://msdn.microsoft.com/en-us/library/bb299745%28v=VS.100%29.aspx).

As part of the work I needed to provide the ability to find users based on the date they were created so following the approach on MSDN (see http://msdn.microsoft.com/en-us/library/bb384372.aspx) I extended the “AdvancedFilters” class and added my own method for setting a filter for a query using the active directory property “whenCreated”. I should say this property stores the date and time a user is created with AD. Now the code shown below is what I first came up with and it looks like it will do the job right?

  1: public class SearchFilter : AdvancedFilters
  2: {
  3:     /// <summary>
  4:     /// Initializes a new instance of the <see cref="SearchFilter"/> class.
  5:     /// </summary>
  6:     /// <param name="p"></param>
  7:     public SearchFilter(Principal p) : base(p)
  8:     {
  9:     }
 10: 
 11:     public void Created(DateTime? created, MatchType matchType)
 12:     {
 13:        if (!created.HasValue) return;
 14:          AdvancedFilterSet("whenCreated", created.Value, typeof(DateTime), matchType);
 15:     }
 16: }
 17: 

Well sadly no. As it turns out the “whenCreated” property in AD is stored as a string in the generalised time format (see http://msdn.microsoft.com/en-us/library/ms680924%28VS.85%29.aspx). Because of this telling the advanced filter set that it’s a date just doesn’t work and you will find as I did no results are returned. So how do you get this to work then? Well all we need to do is update our “Created” method a bit so the advanced filter set thinks it is dealing with a string and then just pass in the date in the correct generalised date format which is “yyyyMMddHHmmss.0Z”.

[Updated code which now correctly sets the type and formats it]
  1: public void Created(DateTime? created, MatchType matchType)
  2: {
  3:    const string WhenCreatedDateFormat = "yyyyMMddHHmmss.0Z";
  4: 
  5:    if (!created.HasValue) return;
  6:    AdvancedFilterSet(ClientUser.WhenCreatedPropertyName,
  7:    created.Value.ToUniversalTime().ToString(WhenCreatedDateFormat), typeof (string), matchType);
  8: }

Once you do this your query filter will spring into life and happily return you results. Well that’s it for now.

Comments

Popular posts from this blog

Shouldn’t validating a checkbox be easier than this?

  Well it's been a while since I have done a post but with changing jobs recently and life in general getting in the way I just couldn’t seem to find the time. However, now I have a spare five minutes I thought I would fire off a post :) So what's the post about? Validating a checkbox web control. Now I know your reading this thinking that's easy all you need is a custom validator and a event handler in your code behind and job done? Well in most cases yes I would agree with you. However, my latest project (a legacy application) uses code generation to create the vast majority of the ASP.NET pages and user controls. Therefore it’s difficult for me to include anything other than the standard set of ASP.NET validators or something which inherits off the “ BaseValidator ” and get it working correctly in the XSLT templates generating the code. Because of this I decided to create my own validator for the checkbox web control. So how do we get started? Well first off you ne...

X509 certificate encryption fun :-)

Recently I needed to encrypt data on a server and allow a limited number of service accounts the ability to decrypt that data so it was as safe as possible. The approach I took to achieve this was by using a X509 certificate and it's ability to allow you to encrypt information via it's public key and decrypt that information through the private key. The key parts of this approach are: - Create a certificate - Ensure the KeySpec of the certificate is set up correctly to allow for encryption e.g. "KeyExchange" or "None" if you are doing this via PowerShell - Set the security on the private keys so only specific user accounts can access it and decrypt information encrypted via the public key. Step 1 - Create a certificate to use The easiest way to get a quick example going is via PowerShell to create a dummy root certificate and the one we will use for encrypting and decrypting. $rootCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Dns...

SharePoint - Search Service Application (SSA) - Attempted to perform an unauthorized operation

On my current project I needed to adjust and add some search mapping via SharePoint's Central Administration web site. This should have been very straight forward as you have the ability to add managed properties and mappings easily via the UI. However, when I went to save my changes I got the error "The settings could not be saved because of an internal error: Attempted to perform an unauthorized operation". Now this was very confusing as I am administrator on the server and added into all of the correct SharePoint groups. I also tried the same action via PowerShell and got the same error.   After a few hours of research and head scratching I managed to get to the bottom of the problem which is the way my user account had been added as an administrator to the server. In the company I work for to make it easier to manage the administrators on a server a group is created in active directory called " servername_admins ". This group is added to the local administra...