I have added custom attribute lastLogonTime
syntax: UTC Coded Time
. I extended UserPrincipal
class to GET/SET that custom attribute.
...
[DirectoryProperty("lastLogonTime")]
public DateTime? LastLogonTime
{
get
{
object[] result = this.ExtensionGet("lastLogonTime");
if (result != null && result.Count() > 0) return (DateTime?)result[0];
return null;
}
set
{
this.ExtensionSet("lastLogonTime", value);
}
}
...
I have also extended AdvancedFilters
to be able to search by this custom attribute.
MyUserPrincipalSearch searchFilter;
new public MyUserPrincipalSearch AdvancedSearchFilter
{
get
{
if (null == searchFilter)
searchFilter = new MyUserPrincipalSearch(this);
return searchFilter;
}
}
public class MyUserPrincipalSearch: AdvancedFilters
{
public MyUserPrincipalSearch(Principal p) : base(p) { }
public void LastLogonTime (DateTime? lastLogonTime, MatchType mt)
{
this.AdvancedFilterSet("lastLogonTime", lastLogonTime.Value, typeof(DateTime?), mt);
}
}
Now, I would like to search through all users who has lastLogonTime
less than a day
.
using (PrincipalContext ctx = ADLDSUtility.Users)
{
MyUserPrincipal filter = new MyUserPrincipal(ctx);
filter.AdvancedSearchFilter.LastLogonTime((DateTime.Now - new TimeSpan(1,0,0,0,0)), MatchType.LessThan);
PrincipalSearcher ps = new PrincipalSearcher(filter);
foreach (MyUserPrincipal p in ps.FindAll())
{
//my custom code
}
}
The above search is not returning me any results. I have test users who have not logged in in the last couple days.
I have tried MatchType.GreaterThan
, MatchType.Equals
. None of them are returning any results, yet there're users who match those criteria.
The only filter that does work is
filter.AdvancedSearchFilter.LastLogonTime(DateTime.Now , MatchType.NotEquals);
But this is basically returning all users. Any ideas why my search result is not returning any results?
My goal is to search for all users who's last logon time is less than X
days.
I'm open to other solutions as long as I get those users.
P.S. I do know a way around this. Loop through all users, get their lastLogonTime
and then do a comparison, but that's just an overkill for what I'm doing.
After spending sometimes on this issue, I found the problem.
As I mentioned on my post the custom attribute lastLogonTime
has syntax: UTC Coded Time
. However, the date and time is not getting stored as DateTime
. It's actually getting stored as string
in this format:
yyyyMMddHHmmss.0Z
How I ended up solving this issue is by modifying my AdvancedSearchFilter.LastLogonTime
to search using formatted string.
public void LastLogonTime (DateTime? lastLogonTime, MatchType mt)
{
const string lastLogonTimeFormat = "yyyyMMddHHmmss.0Z";
this.AdvancedFilterSet("lastLogonTime", lastLogonTime.Value.ToUniversalTime().ToString(lastLogonTimeFormat), typeof(string), mt);
}
Hope this helps someone.