291 lines
12 KiB
C#
291 lines
12 KiB
C#
using Disco.Models.Interop.ActiveDirectory;
|
|
using Disco.Models.Repository;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.DirectoryServices;
|
|
using System.Text;
|
|
using System.Net.NetworkInformation;
|
|
using System.Management;
|
|
|
|
namespace Disco.BI.Interop.ActiveDirectory
|
|
{
|
|
public static class ActiveDirectoryMachineAccountExtensions
|
|
{
|
|
public static void DeleteAccount(this ActiveDirectoryMachineAccount account)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
using (DirectoryEntry machineDE = new DirectoryEntry(account.Path))
|
|
{
|
|
DeleteAccountRecursive(machineDE);
|
|
|
|
using (var machineDEParent = machineDE.Parent)
|
|
{
|
|
machineDEParent.Children.Remove(machineDE);
|
|
}
|
|
}
|
|
}
|
|
private static void DeleteAccountRecursive(DirectoryEntry parent)
|
|
{
|
|
List<DirectoryEntry> children = new List<DirectoryEntry>();
|
|
foreach (DirectoryEntry child in parent.Children)
|
|
children.Add(child);
|
|
|
|
foreach (var child in children)
|
|
{
|
|
DeleteAccountRecursive(child);
|
|
parent.Children.Remove(child);
|
|
child.Dispose();
|
|
}
|
|
}
|
|
private static void SetNetbootGUID(this ActiveDirectoryMachineAccount account, System.Guid updatedNetbootGUID)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
using (DirectoryEntry machineDE = new DirectoryEntry(account.Path))
|
|
{
|
|
PropertyValueCollection netbootGUIDProp = machineDE.Properties["netbootGUID"];
|
|
bool flag = netbootGUIDProp.Count > 0;
|
|
if (flag)
|
|
{
|
|
netbootGUIDProp.Clear();
|
|
}
|
|
netbootGUIDProp.Add(updatedNetbootGUID.ToByteArray());
|
|
machineDE.CommitChanges();
|
|
}
|
|
}
|
|
public static void SetDescription(this ActiveDirectoryMachineAccount account, string Description)
|
|
{
|
|
using (DirectoryEntry machineDE = new DirectoryEntry(account.Path))
|
|
{
|
|
PropertyValueCollection descriptionProp = machineDE.Properties["description"];
|
|
if (descriptionProp.Count > 0)
|
|
{
|
|
descriptionProp.Clear();
|
|
}
|
|
if (!string.IsNullOrEmpty(Description))
|
|
{
|
|
descriptionProp.Add(Description);
|
|
}
|
|
machineDE.CommitChanges();
|
|
}
|
|
}
|
|
public static void SetDescription(this ActiveDirectoryMachineAccount account, Device Device)
|
|
{
|
|
System.Text.StringBuilder descriptionBuilder = new System.Text.StringBuilder();
|
|
|
|
if (Device.AssignedUserId != null)
|
|
{
|
|
descriptionBuilder.Append(Device.AssignedUser.Id).Append(" (").Append(Device.AssignedUser.DisplayName).Append("); ");
|
|
}
|
|
|
|
if (Device.DeviceModelId.HasValue)
|
|
{
|
|
descriptionBuilder.Append(Device.DeviceModel.Description).Append("; ");
|
|
}
|
|
|
|
descriptionBuilder.Append(Device.DeviceProfile.Description).Append(";");
|
|
|
|
string description = descriptionBuilder.ToString().Trim();
|
|
if (description.Length > 1024)
|
|
{
|
|
description = description.Substring(0, 1024);
|
|
}
|
|
account.SetDescription(description);
|
|
}
|
|
|
|
public static void DisableAccount(this ActiveDirectoryMachineAccount account)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
using (DirectoryEntry machineDE = new DirectoryEntry(account.Path))
|
|
{
|
|
int accountControl = (int)machineDE.Properties["userAccountControl"][0];
|
|
int updatedAccountControl = (accountControl | 2);
|
|
if (accountControl != updatedAccountControl)
|
|
{
|
|
machineDE.Properties["userAccountControl"][0] = updatedAccountControl;
|
|
machineDE.CommitChanges();
|
|
}
|
|
}
|
|
}
|
|
public static void EnableAccount(this ActiveDirectoryMachineAccount account)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
using (DirectoryEntry machineDE = new DirectoryEntry(account.Path))
|
|
{
|
|
int accountControl = (int)machineDE.Properties["userAccountControl"][0];
|
|
if ((accountControl & 2) == 2)
|
|
{
|
|
int updatedAccountControl = (accountControl ^ 2);
|
|
machineDE.Properties["userAccountControl"][0] = updatedAccountControl;
|
|
machineDE.CommitChanges();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool UpdateNetbootGUID(this ActiveDirectoryMachineAccount account, string UUID, string MACAddress)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
System.Guid netbootGUID = System.Guid.Empty;
|
|
bool flag = !string.IsNullOrWhiteSpace(UUID);
|
|
if (flag)
|
|
{
|
|
netbootGUID = ActiveDirectoryMachineAccountExtensions.NetbootGUIDFromUUID(UUID);
|
|
}
|
|
else
|
|
{
|
|
flag = !string.IsNullOrWhiteSpace(MACAddress);
|
|
if (flag)
|
|
{
|
|
netbootGUID = ActiveDirectoryMachineAccountExtensions.NetbootGUIDFromMACAddress(MACAddress);
|
|
}
|
|
}
|
|
flag = (netbootGUID != System.Guid.Empty && netbootGUID != account.NetbootGUID);
|
|
bool UpdateNetbootGUID;
|
|
if (flag)
|
|
{
|
|
account.SetNetbootGUID(netbootGUID);
|
|
UpdateNetbootGUID = true;
|
|
}
|
|
else
|
|
{
|
|
UpdateNetbootGUID = false;
|
|
}
|
|
return UpdateNetbootGUID;
|
|
}
|
|
internal static System.Guid NetbootGUIDFromMACAddress(string MACAddress)
|
|
{
|
|
string strippedMACAddress = MACAddress.Trim().Replace(":", string.Empty).Replace("-", string.Empty);
|
|
bool flag = strippedMACAddress.Length == 12;
|
|
System.Guid NetbootGUIDFromMACAddress;
|
|
if (flag)
|
|
{
|
|
System.Guid guid = new System.Guid(string.Format("00000000-0000-0000-0000-{0}", strippedMACAddress));
|
|
NetbootGUIDFromMACAddress = guid;
|
|
}
|
|
else
|
|
{
|
|
NetbootGUIDFromMACAddress = System.Guid.Empty;
|
|
}
|
|
return NetbootGUIDFromMACAddress;
|
|
}
|
|
internal static System.Guid NetbootGUIDFromUUID(string UUID)
|
|
{
|
|
System.Guid result = new System.Guid(UUID);
|
|
return result;
|
|
}
|
|
|
|
public static object GetPropertyValue(this ActiveDirectoryMachineAccount account, string PropertyName, int Index = 0)
|
|
{
|
|
switch (PropertyName.ToLower())
|
|
{
|
|
case "name":
|
|
return account.Name;
|
|
case "samaccountname":
|
|
return account.sAMAccountName;
|
|
case "distinguishedname":
|
|
return account.DistinguishedName;
|
|
case "objectsid":
|
|
return account.ObjectSid;
|
|
case "netbootguid":
|
|
return account.NetbootGUID;
|
|
default:
|
|
object[] adProperty;
|
|
if (account.LoadedProperties.TryGetValue(PropertyName, out adProperty) && Index <= adProperty.Length)
|
|
return adProperty[Index];
|
|
else
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static IPStatus PingComputer(this ActiveDirectoryMachineAccount account, int Timeout = 2000)
|
|
{
|
|
using (var p = new Ping())
|
|
{
|
|
PingReply reply = p.Send(account.DnsName, Timeout);
|
|
return reply.Status;
|
|
}
|
|
}
|
|
|
|
// Didn't Work - WMI Limitation?
|
|
// G# - 2012-06-18
|
|
//public static void OnlineRenameComputer(this ActiveDirectoryMachineAccount account, string NewComputerName)
|
|
//{
|
|
// if (account.IsCriticalSystemObject)
|
|
// throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
// try
|
|
// {
|
|
// IPStatus pingResult = account.PingComputer();
|
|
// if (pingResult != IPStatus.Success)
|
|
// throw new Exception(string.Format("Ping Error Result: {0}", pingResult.ToString()));
|
|
// }
|
|
// catch (Exception ex)
|
|
// {
|
|
// throw new Exception(string.Format("Error trying to Ping the Device: {0}; {1}", account.DnsName, ex.Message), ex);
|
|
// }
|
|
|
|
// ConnectionOptions wmiConnectionOptions = new ConnectionOptions()
|
|
// {
|
|
// Authentication = AuthenticationLevel.PacketPrivacy,
|
|
// Impersonation = ImpersonationLevel.Impersonate,
|
|
// EnablePrivileges = true,
|
|
// Timeout = new TimeSpan(0, 0, 6)
|
|
// };
|
|
// ManagementPath wmiPath = new ManagementPath()
|
|
// {
|
|
// Server = account.DnsName,
|
|
// NamespacePath = @"root\cimv2",
|
|
// ClassName = "Win32_ComputerSystem"
|
|
// };
|
|
|
|
// ManagementScope wmiScope = new ManagementScope(wmiPath, wmiConnectionOptions);
|
|
|
|
// ObjectGetOptions wmiGetOptions = new ObjectGetOptions() { Timeout = new TimeSpan(0, 1, 0) };
|
|
|
|
// using (ManagementClass wmiClass = new ManagementClass(wmiScope, wmiPath, wmiGetOptions))
|
|
// {
|
|
// foreach (ManagementObject wmiWin32ComputerSystem in wmiClass.GetInstances())
|
|
// {
|
|
// UInt32 result = (UInt32)wmiWin32ComputerSystem.InvokeMethod("Rename", new object[] { NewComputerName });
|
|
// if (result != 0)
|
|
// throw new Exception(string.Format("Error Renaming Computer; WMI Remote Method 'Rename' returned: {0}", result));
|
|
// }
|
|
// }
|
|
//}
|
|
|
|
public static void MoveOrganisationUnit(this ActiveDirectoryMachineAccount account, string NewOrganisationUnit)
|
|
{
|
|
if (account.IsCriticalSystemObject)
|
|
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco refuses to modify it", account.DistinguishedName));
|
|
|
|
if (!account.ParentDistinguishedName.Equals(NewOrganisationUnit, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
string ouPath;
|
|
if (string.IsNullOrWhiteSpace(NewOrganisationUnit))
|
|
ouPath = string.Format("{0}CN=Computers,{1}", ActiveDirectoryHelpers.DefaultLdapPath, ActiveDirectoryHelpers.DefaultDomainQualifiedName);
|
|
else
|
|
ouPath = string.Format("{0}{1},{2}", ActiveDirectoryHelpers.DefaultLdapPath, NewOrganisationUnit, ActiveDirectoryHelpers.DefaultDomainQualifiedName);
|
|
|
|
using (DirectoryEntry ou = new DirectoryEntry(ouPath))
|
|
{
|
|
using (DirectoryEntry i = new DirectoryEntry(account.Path) { UsePropertyCache = false })
|
|
{
|
|
i.MoveTo(ou);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|