Files
Disco/Disco.BI/BI/Interop/ActiveDirectory/ActiveDirectoryUpdateLastNetworkLogonDateJob.cs
T
Gary Sharp a099d68915 Permissions & Authorization for Users #24
Initial Release; Includes Database and MVC refactoring
2013-10-10 19:13:16 +11:00

265 lines
13 KiB
C#

using Disco.Data.Repository;
using Disco.Services.Logging;
using Disco.Models.Repository;
using Quartz;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.DirectoryServices;
using System.Linq;
using System.Linq.Expressions;
using System.Net.NetworkInformation;
using System.Reflection;
using Disco.Services.Tasks;
namespace Disco.BI.Interop.ActiveDirectory
{
public class ActiveDirectoryUpdateLastNetworkLogonDateJob : ScheduledTask
{
public override string TaskName { get { return "Active Directory - Update Last Network Logon Dates Task"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
// ActiveDirectoryUpdateLastNetworkLogonDateJob @ 11:30pm
TriggerBuilder triggerBuilder = TriggerBuilder.Create().
WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(23, 30));
this.ScheduleTask(triggerBuilder);
}
protected override void ExecuteTask()
{
int changeCount;
this.Status.UpdateStatus(1, "Starting", "Connecting to the Database and initializing the environment");
using (DiscoDataContext database = new DiscoDataContext())
{
UpdateLastNetworkLogonDates(database, this.Status);
this.Status.UpdateStatus(95, "Updating Database", "Writing last network logon dates to the Database");
changeCount = database.SaveChanges();
this.Status.Finished(string.Format("{0} Device last network logon dates updated", changeCount), "/Config/SystemConfig");
}
SystemLog.LogInformation(new string[]
{
"Updated LastNetworkLogon Device Property for Device/s",
changeCount.ToString()
});
}
public static ScheduledTaskStatus ScheduleImmediately()
{
var existingTask = ScheduledTasks.GetTaskStatuses(typeof(ActiveDirectoryUpdateLastNetworkLogonDateJob)).Where(s => s.IsRunning).FirstOrDefault();
if (existingTask != null)
return existingTask;
var instance = new ActiveDirectoryUpdateLastNetworkLogonDateJob();
return instance.ScheduleTask();
}
public static bool UpdateLastNetworkLogonDate(Device Device)
{
System.DateTime? computerLastLogonDate = Device.LastNetworkLogonDate;
if (!string.IsNullOrEmpty(Device.ComputerName))
{
foreach (var dcName in ActiveDirectoryHelpers.DefaultDomainDCNames)
{
try
{
Ping p = new Ping();
PingReply pr;
try
{
pr = p.Send(dcName, 500);
}
finally
{
if (p != null)
{
((System.IDisposable)p).Dispose();
}
}
if (pr.Status == IPStatus.Success)
{
using (DirectoryEntry dRootEntry = ActiveDirectoryHelpers.DefaultDCLdapRoot(dcName))
{
DirectorySearcher dSearcher = new DirectorySearcher(dRootEntry, string.Format("(&(objectCategory=Computer)(sAMAccountName={0}$))", ActiveDirectoryHelpers.EscapeLdapQuery(Device.ComputerName)), new string[]
{
"lastLogon"
}, SearchScope.Subtree);
SearchResult dResult = dSearcher.FindOne();
if (dResult != null)
{
ResultPropertyValueCollection dProp = dResult.Properties["lastLogon"];
if (dProp != null && dProp.Count > 0)
{
long lastLogonInt = (long)dProp[0];
if (lastLogonInt > 0L)
{
System.DateTime computerNameDate = System.DateTime.FromFileTime(lastLogonInt);
if (computerLastLogonDate.HasValue)
{
if (System.DateTime.Compare(computerLastLogonDate.Value, computerNameDate) < 0)
{
computerLastLogonDate = computerNameDate;
}
}
else
{
computerLastLogonDate = computerNameDate;
}
}
}
}
}
}
else
{
SystemLog.LogError(new string[]
{
string.Format("Unable to ping Domain Controller: '{0}' (ref: Disco.BI.Interop.ActiveDirectory.ActiveDirectoryUpdateLastNetworkLogonDateJob.UpdateDeviceLastNetworkLogonDate)", dcName)
});
}
}
catch (System.Exception ex)
{
SystemLog.LogException("UpdateDeviceLastNetworkLogonDate", ex);
}
}
}
bool UpdateLastNetworkLogonDate;
if (computerLastLogonDate.HasValue)
{
if (!Device.LastNetworkLogonDate.HasValue)
{
Device.LastNetworkLogonDate = computerLastLogonDate;
UpdateLastNetworkLogonDate = true;
return UpdateLastNetworkLogonDate;
}
if (System.DateTime.Compare(computerLastLogonDate.Value, Device.LastNetworkLogonDate.Value) > 0)
{
Device.LastNetworkLogonDate = computerLastLogonDate;
UpdateLastNetworkLogonDate = true;
return UpdateLastNetworkLogonDate;
}
}
UpdateLastNetworkLogonDate = false;
return UpdateLastNetworkLogonDate;
}
private static void UpdateLastNetworkLogonDates(DiscoDataContext Database, ScheduledTaskStatus status)
{
System.Collections.Generic.Dictionary<string, System.DateTime> computerLastLogonDates = new System.Collections.Generic.Dictionary<string, System.DateTime>();
int progressDCCountTotal = ActiveDirectoryHelpers.DefaultDomainDCNames.Count;
int progressDCCount = 0;
double progressDCProgress = 0;
if (progressDCCountTotal > 0)
progressDCProgress = 90 / progressDCCountTotal;
foreach (var dcName in ActiveDirectoryHelpers.DefaultDomainDCNames)
{
try
{
PingReply pr;
using (Ping p = new Ping())
{
pr = p.Send(dcName, 2000);
}
if (pr.Status == IPStatus.Success)
{
using (DirectoryEntry dRootEntry = ActiveDirectoryHelpers.DefaultDCLdapRoot(dcName))
{
double progressDCStart = 5 + (progressDCCount * progressDCProgress);
status.UpdateStatus(progressDCStart, string.Format("Querying Domain Controller: {0}", dcName), "Searching...");
using (DirectorySearcher dSearcher = new DirectorySearcher(dRootEntry, "(objectCategory=Computer)", new string[] { "sAMAccountName", "lastLogon" }, SearchScope.Subtree))
{
using (SearchResultCollection dResults = dSearcher.FindAll())
{
int progressItemCount = 0;
double progressItemProgress = dResults.Count == 0 ? 0 : (progressDCProgress / dResults.Count);
foreach (SearchResult dResult in dResults)
{
ResultPropertyValueCollection dProp = dResult.Properties["sAMAccountName"];
if (dProp != null && dProp.Count > 0)
{
string computerName = ((string)dProp[0]).TrimEnd(new char[] { '$' }).ToUpper();
if (progressItemCount % 150 == 0) // Only Update Status every 150 devices
status.UpdateStatus(progressDCStart + (progressItemProgress * progressItemCount), string.Format("Analysing Device: {0}", computerName));
dProp = dResult.Properties["lastLogon"];
if (dProp != null && dProp.Count > 0)
{
long lastLogonInt = (long)dProp[0];
if (lastLogonInt > 0L)
{
System.DateTime computerNameDate = System.DateTime.FromFileTime(lastLogonInt);
System.DateTime existingDate;
if (computerLastLogonDates.TryGetValue(computerName, out existingDate))
{
if (System.DateTime.Compare(existingDate, computerNameDate) < 0)
{
computerLastLogonDates[computerName] = computerNameDate;
}
}
else
{
computerLastLogonDates[computerName] = computerNameDate;
}
}
}
}
progressItemCount++;
}
}
}
}
}
else
{
SystemLog.LogError(new string[]
{
string.Format("Unable to ping Domain Controller: '{0}' (ref: Disco.BI.Interop.ActiveDirectory.ActiveDirectoryUpdateLastNetworkLogonDateJob.UpdateLastNetworkLogonDates)", dcName)
});
}
}
catch (System.Exception ex)
{
SystemLog.LogException("UpdateLastNetworkLogonDates", ex);
}
progressDCCount++;
}
foreach (Device d in Database.Devices.Where(device => device.ComputerName != null))
{
DateTime computerLastLogonDate;
if (computerLastLogonDates.TryGetValue(d.ComputerName.ToUpper(), out computerLastLogonDate))
{
if (d.LastNetworkLogonDate.HasValue)
{
// Change accuracy to the second
computerLastLogonDate = new DateTime((computerLastLogonDate.Ticks / 10000000L) * 10000000L);
if (System.DateTime.Compare(d.LastNetworkLogonDate.Value, computerLastLogonDate) < 0)
{
d.LastNetworkLogonDate = computerLastLogonDate;
}
}
else
{
d.LastNetworkLogonDate = computerLastLogonDate;
}
}
}
}
}
}