0

The following code returns all the computerprincipals that have logon date prior to 3 months ago but does not get those with null for a lastlogontimestamp

PrincipalContext context = new PrincipalContext(ContextType.Domain);
PrincipalSearchResult<ComputerPrincipal> computers = ComputerPrincipal.FindByLogonTime(context, DateTime.Now.AddMonths(-3), MatchType.LessThanOrEquals);

How can I elegantly also add to "computers" those that have null valued "lastlogontimestamp" values?

dragonspeed
  • 255
  • 2
  • 13
  • I am not sure how the LINQ inside of FindByLogonTime is like, but since it looks like your DateTime can be null then all you need to do is just check for null. I assume since you are passing a match type that your method is using an out of date variant of LINQ. – SomeStudent May 22 '19 at 22:00
  • I don't code professionally - more of an "as needed" basis. FindByLogonTime is MS's method, I just use it :) Would be happy to see a better, more "modern" way, if there is... – dragonspeed May 22 '19 at 22:04
  • I see, hmm, in that case since both will return a collection; i assume you could also do something like (i've never used this method before btw): PrincipalSearchResult computers = ComputerPrincipal.FindByLogonTime(context, null, MatchType.Equals); and then join the two – SomeStudent May 22 '19 at 22:06
  • sadly the second parameter is a type [DateTime] and is non-nullable. – dragonspeed May 22 '19 at 22:08

1 Answers1

1

I did away with the ComputerPrincipal.FindByLogonTime, since it can't find null LogonTime and went with the old classic, the DirectorySearcher

DirectorySearcher Computersearcher = new DirectorySearcher
{
    SearchRoot = new DirectoryEntry(baseOU),
    Filter = "(&(whenCreated<=" + WhenCreated + ")(!(userAccountControl=2))(|(lastLogonTimestamp<=" + DateInt + ")(lastLogonTimestamp=0))(objectClass=computer))",
    SearchScope = SearchScope.Subtree,
    PageSize = 1000,
    Sort = new SortOption("Name", SortDirection.Ascending)
        };
    SearchResultCollection ComputerResults = Computersearcher.FindAll();
}

This has the unfortunate side effect that the observable collection that I used to create, no longer displays the Name in my WPF Listbox (despite setting DisplayNamePath).

A whole new issue, but the current one is "solved"

dragonspeed
  • 255
  • 2
  • 13
  • And, for those following along at home, the solution to that problem was this: [Why does WPF support binding to properties of an object, but not fields? ](https://stackoverflow.com/questions/842575/why-does-wpf-support-binding-to-properties-of-an-object-but-not-fields) – dragonspeed May 24 '19 at 00:59
  • I always find `DirectorySearcher` performs faster anyway. You might think about populating the `PropertiesToLoad` collection with only the attributes you need to read, otherwise it will return every attribute with a value, which might be a lot of data you don't need. A while ago I wrote an article about performance when programming against AD that might help: https://www.gabescode.com/active-directory/2018/12/15/better-performance-activedirectory.html – Gabriel Luci May 24 '19 at 12:41