using Disco.Data.Repository; using Disco.Models.Repository; using Disco.Plugins.ADCompare.Models; using Disco.Services.Interop.ActiveDirectory; using System; using System.Collections.Generic; using System.Linq; namespace Disco.Plugins.ADCompare.Features { public class DeviceCompareService { private readonly DiscoDataContext database; public DeviceCompareService(DiscoDataContext database) { this.database = database; } public DeviceComparisonSummary CompareAllDevices() { var summary = new DeviceComparisonSummary(); var devices = database.Devices .Include("AssignedUser") .Where(d => d.DeviceDomainId != null && d.DecommissionedDate == null) .ToList(); summary.TotalDevices = devices.Count; foreach (var device in devices) { var result = CompareDevice(device); summary.Results.Add(result); } summary.DevicesWithAssignment = summary.Results.Count(r => r.HasAssignment); summary.DevicesNotInAD = summary.Results.Count(r => !r.FoundInAD); summary.DevicesMatched = summary.Results.Count(r => r.IsMatch); summary.DevicesMismatched = summary.Results.Count(r => !r.IsMatch && r.FoundInAD); summary.DevicesNoAssignment = summary.Results.Count(r => !r.HasAssignment); summary.DevicesNoManagedBy = summary.Results.Count(r => r.FoundInAD && !r.HasManagedBy); summary.DevicesADDisabled = summary.Results.Count(r => r.ADAccountDisabled); return summary; } public DeviceComparisonResult CompareDevice(Device device) { var result = new DeviceComparisonResult(); result.SerialNumber = device.SerialNumber; result.DeviceDomainId = device.DeviceDomainId; result.ComputerName = device.ComputerName; result.DiscoAssignedUserId = device.AssignedUserId; result.DiscoAssignedUserDisplayName = device.AssignedUser != null ? device.AssignedUser.DisplayName : null; result.HasAssignment = !string.IsNullOrEmpty(device.AssignedUserId); try { var adAccount = ActiveDirectory.RetrieveADMachineAccount(device.DeviceDomainId, new[] { "managedBy" }); if (adAccount == null) { result.FoundInAD = false; result.MismatchReason = "Computer not found in AD"; return result; } result.FoundInAD = true; result.ADAccountDisabled = adAccount.IsDisabled; var managedByDN = adAccount.GetPropertyValue("managedBy"); result.ADManagedByDN = managedByDN; result.HasManagedBy = !string.IsNullOrEmpty(managedByDN); if (result.HasManagedBy) { try { var managedByUser = ActiveDirectory.RetrieveADUserAccount(managedByDN); if (managedByUser != null) { result.ADManagedByUserId = managedByUser.Id; result.ADManagedByDisplayName = managedByUser.DisplayName; } else { result.ADManagedByUserId = managedByDN; } } catch { result.ADManagedByUserId = managedByDN; } } result.IsMatch = DetermineMatch(result); if (!result.IsMatch) { result.MismatchReason = DetermineMismatchReason(result); } } catch (Exception ex) { result.FoundInAD = false; result.MismatchReason = "AD lookup error: " + ex.Message; } return result; } private bool DetermineMatch(DeviceComparisonResult result) { if (!result.HasAssignment && !result.HasManagedBy) return true; if (result.HasAssignment != result.HasManagedBy) return false; return string.Equals( result.DiscoAssignedUserId, result.ADManagedByUserId, StringComparison.OrdinalIgnoreCase); } private string DetermineMismatchReason(DeviceComparisonResult result) { if (!result.FoundInAD) return "Computer not found in AD"; if (result.HasAssignment && !result.HasManagedBy) return "Assigned in Disco but AD managedBy is empty"; if (!result.HasAssignment && result.HasManagedBy) return "Not assigned in Disco but AD managedBy is set"; if (result.HasAssignment && result.HasManagedBy) return string.Format("Different users: Disco={0}, AD managedBy={1}", result.DiscoAssignedUserId, result.ADManagedByUserId); return "Unknown mismatch"; } } }