e8e141c9af
Javascript: Warranty Job Details; AD Interop
265 lines
13 KiB
C#
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 dbContext)
|
|
{
|
|
// 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 dbContext = new DiscoDataContext())
|
|
{
|
|
UpdateLastNetworkLogonDates(dbContext, this.Status);
|
|
this.Status.UpdateStatus(95, "Updating Database", "Writing last network logon dates to the Database");
|
|
changeCount = dbContext.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("(&(objectClass=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 context, 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, "(objectClass=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 context.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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|