This is a Windows Presentation Foundation application that queries active directory and can display lists of users, users by group, groups, and users by manager (direct reports). It operates on whatever active directory server the host computer belongs to, and dynamically builds a TreeView
of all the Organizational Units in the active directory for the user to navigate through.
Once a user has selected an Organizational Unit, they can use one of the buttons to start a query. The results of the query are then displayed in a DataGrid
.
Complete Process:
- Application Launch
- During the launch, the host AD server is contacted and a list of all OUs is retrieved.
- The OU list is parsed into a
TreeView
. Since the OUs are in the form of LDAP paths, this process involves:- Storing the whole path as
Path
to be used later. - Stripping the prefix, domain components, and OU individual prefixes, splitting into an array of individual OUs, and flipping the array (LDAP paths are "backwards").
- Creating an
ActiveDirectoryScope
for each individual OU, and assembling into a tree.
- Storing the whole path as
- Application Use
- User selects a scope from the
TreeView
. - User selects a query.
- View notifies ViewModel that query has been requested.
- ViewModel retrieves current scope, and opens an
ActiveDirectorySearcher
on that scope. - ViewModel retrieves the appropriate query from the searcher.
- ViewModel passes the query results into a
DataPreparer
with the appropriate attributes/fields to load. DataPreparer
iterates through the query results and returns a list of dynamic objects with the appropriate attributes/fields.- ViewModel transforms the list into a
DataView
and hands it to the View'sDataGrid
.
- User selects a scope from the
Notes:
- For now, the attributes are specified in the form of
readonly
arrays. This will be changed later to user input. - The querying process will later be run in a background thread so that the UI doesn't freeze.
- I know my implementation of MVVM is incorrect.
- The get computers feature that appears in several different locations is currently not included, but will be later.
- The blanket exception catch in the UsersGroups search is intentional and necessary to avoid an unknown error in a client's Active Directory.
ActiveDirectoryToolView.xaml
<Window x:Class="ActiveDirectoryToolWpf.ActiveDirectoryToolView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ActiveDirectoryToolWpf"
mc:Ignorable="d"
Title="ActiveDirectoryToolView" Height="576" Width="1024" MinHeight="576" MinWidth="1024">
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="75*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0">
<Grid Grid.Column="0">
<TreeView x:Name="TreeView"
ItemsSource="{Binding Path=Children}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="42px" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Button x:Name="GetUsersButton" Content="Get Users" HorizontalAlignment="Left" Margin="10,10,0,0"
VerticalAlignment="Top" Width="75" Click="GetUsersButton_Click" />
<Button x:Name="GetUsersGroupsButton" Content="Get Users' Groups" HorizontalAlignment="Left"
Margin="90,10,0,0" VerticalAlignment="Top" Width="103" Click="GetUsersGroupsButton_Click" />
<Button x:Name="GetGroupsButton" Content="Get Groups" HorizontalAlignment="Left" Margin="198,10,0,0"
VerticalAlignment="Top" Width="75" Click="GetGroupsButton_Click" />
<Button x:Name="GetDirectReports" Content="Get Direct Reports" HorizontalAlignment="Left"
Margin="278,10,0,0" VerticalAlignment="Top" Width="103" Click="GetDirectReports_Click" />
</Grid>
<Grid Grid.Row="1">
<DataGrid x:Name="DataGrid"
AutoGenerateColumns="True"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
RenderTransformOrigin="2.25,-3.615"
MaxHeight="9001" MaxWidth="90000000"
ItemsSource="{Binding IsAsync=True}" MinHeight="484" MinWidth="742" />
</Grid>
</Grid>
</Grid>
</Window>
ActiveDirectoryToolView.cs
using System;
using System.Data;
using System.Windows;
namespace ActiveDirectoryToolWpf
{
public partial class ActiveDirectoryToolView : IActiveDirectoryToolView
{
public ActiveDirectoryToolView()
{
ViewModel = new ActiveDirectoryToolViewModel(this);
DataContext = new ActiveDirectoryScopeFetcher().Scope;
InitializeComponent();
DataGrid.EnableColumnVirtualization = true;
DataGrid.EnableRowVirtualization = true;
}
public ActiveDirectoryToolViewModel ViewModel { get; }
public event Action GetComputersClicked;
public event Action GetDirectReportsClicked;
public event Action GetGroupsClicked;
public event Action GetUsersClicked;
public event Action GetUsersGroupsClicked;
public ActiveDirectoryScope Scope =>
TreeView.SelectedItem as ActiveDirectoryScope;
public void SetDataGridData(DataView dataView)
{
DataGrid.ItemsSource = dataView;
}
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
public void ToggleEnabled()
{
IsEnabled = !IsEnabled;
}
private void GetDirectReports_Click(object sender, RoutedEventArgs e)
{
if (Scope != null)
GetDirectReportsClicked?.Invoke();
}
private void GetGroupsButton_Click(object sender, RoutedEventArgs e)
{
if (Scope != null)
GetGroupsClicked?.Invoke();
}
private void GetUsersButton_Click(object sender, RoutedEventArgs e)
{
if (Scope != null)
GetUsersClicked?.Invoke();
}
private void GetUsersGroupsButton_Click(object sender, RoutedEventArgs e)
{
if (Scope != null)
GetUsersGroupsClicked?.Invoke();
}
}
}
ActiveDirectoryToolViewModel.cs
using System.Data;
using System.Linq;
namespace ActiveDirectoryToolWpf
{
public class ActiveDirectoryToolViewModel
{
private readonly ActiveDirectoryAttribute[]
_defaultDirectReportsAttributes =
{
ActiveDirectoryAttribute.UserDisplayName,
ActiveDirectoryAttribute.UserSamAccountName,
ActiveDirectoryAttribute.DirectReportDisplayName,
ActiveDirectoryAttribute.DirectReportSamAccountName
};
private readonly ActiveDirectoryAttribute[] _defaultGroupAttributes =
{
ActiveDirectoryAttribute.GroupSamAccountName,
ActiveDirectoryAttribute.GroupManagedBy,
ActiveDirectoryAttribute.GroupDescription,
ActiveDirectoryAttribute.GroupDistinguishedName
};
private readonly ActiveDirectoryAttribute[] _defaultUserAttributes =
{
ActiveDirectoryAttribute.UserSurname,
ActiveDirectoryAttribute.UserGivenName,
ActiveDirectoryAttribute.UserDisplayName,
ActiveDirectoryAttribute.UserSamAccountName,
ActiveDirectoryAttribute.UserIsActive,
ActiveDirectoryAttribute.UserIsAccountLockedOut,
ActiveDirectoryAttribute.UserDescription,
ActiveDirectoryAttribute.UserTitle,
ActiveDirectoryAttribute.UserCompany,
ActiveDirectoryAttribute.UserManager,
ActiveDirectoryAttribute.UserHomeDrive,
ActiveDirectoryAttribute.UserHomeDirectory,
ActiveDirectoryAttribute.UserScriptPath,
ActiveDirectoryAttribute.UserEmailAddress,
ActiveDirectoryAttribute.UserStreetAddress,
ActiveDirectoryAttribute.UserCity,
ActiveDirectoryAttribute.UserState,
ActiveDirectoryAttribute.UserVoiceTelephoneNumber,
ActiveDirectoryAttribute.UserPager,
ActiveDirectoryAttribute.UserMobile,
ActiveDirectoryAttribute.UserFax,
ActiveDirectoryAttribute.UserVoip,
ActiveDirectoryAttribute.UserSip,
ActiveDirectoryAttribute.UserUserPrincipalName,
ActiveDirectoryAttribute.UserDistinguishedName
};
private readonly ActiveDirectoryAttribute[]
_defaultUserGroupsAttributes =
{
ActiveDirectoryAttribute.UserSamAccountName,
ActiveDirectoryAttribute.GroupSamAccountName,
ActiveDirectoryAttribute.UserName,
ActiveDirectoryAttribute.UserDistinguishedName
};
private readonly IActiveDirectoryToolView _view;
private DataPreparer _dataPreparer;
private ActiveDirectorySearcher _searcher;
public ActiveDirectoryToolViewModel(IActiveDirectoryToolView view)
{
_view = view;
_view.GetUsersClicked += OnGetUsers;
_view.GetUsersGroupsClicked += OnGetUsersGroups;
_view.GetDirectReportsClicked += OnGetDirectReports;
_view.GetGroupsClicked += OnGetGroups;
}
private void OnGetDirectReports()
{
_searcher = new ActiveDirectorySearcher(_view.Scope);
_dataPreparer = new DataPreparer
{
Data = _searcher.GetDirectReports(),
Attributes = _defaultDirectReportsAttributes.ToList()
};
_view.SetDataGridData(
_dataPreparer.GetResults().ToDataTable().AsDataView());
}
private void OnGetGroups()
{
_searcher = new ActiveDirectorySearcher(_view.Scope);
_dataPreparer = new DataPreparer
{
Data = _searcher.GetGroups(),
Attributes = _defaultGroupAttributes.ToList()
};
_view.SetDataGridData(
_dataPreparer.GetResults().ToDataTable().AsDataView());
}
private void OnGetUsers()
{
_searcher = new ActiveDirectorySearcher(_view.Scope);
_dataPreparer = new DataPreparer
{
Data = _searcher.GetUsers(),
Attributes = _defaultUserAttributes.ToList()
};
_view.SetDataGridData(
_dataPreparer.GetResults().ToDataTable().AsDataView());
}
private void OnGetUsersGroups()
{
_searcher = new ActiveDirectorySearcher(_view.Scope);
_dataPreparer = new DataPreparer
{
Data = _searcher.GetUsersGroups(),
Attributes = _defaultUserGroupsAttributes.ToList()
};
_view.SetDataGridData(
_dataPreparer.GetResults().ToDataTable().AsDataView());
}
}
}
ActiveDirectoryScope.cs
using System;
using System.Collections.Generic;
using PrimitiveExtensions;
namespace ActiveDirectoryToolWpf
{
public class ActiveDirectoryScope : IEquatable<ActiveDirectoryScope>
{
private const char Comma = ',';
private const string DomainComponentPrefix = "DC=";
private const string LdapProtocolPrefix = "LDAP://";
private const char Period = '.';
internal ActiveDirectoryScope()
{
Children = new List<ActiveDirectoryScope>();
}
public List<ActiveDirectoryScope> Children { get; set; }
internal string Context => Path.Remove(LdapProtocolPrefix);
internal string Domain
=> Path.SubstringAtIndexOfOrdinal(DomainComponentPrefix)
.Remove(DomainComponentPrefix)
.Replace(Comma, Period);
internal string Name { get; set; }
internal string Path { get; set; }
public bool Equals(ActiveDirectoryScope other)
{
return Name == other.Name;
}
public override string ToString()
{
return Name;
}
internal void AddDirectoryScope(OrganizationalUnit organizationalUnit)
{
if (organizationalUnit.Split == null ||
organizationalUnit.Split.Length < 1)
{
throw new ArgumentException(
"The organizational units array is null or empty!");
}
var parent = this;
foreach (var level in organizationalUnit.Split)
{
var lastLevel = organizationalUnit.Split.Length - 1;
if (parent.Children.Contains(new ActiveDirectoryScope
{
Name = level
}))
{
parent = parent.Children.Find(
item => item.Name.Equals(level));
}
else if (level == organizationalUnit.Split[lastLevel])
{
parent.Children.Add(new ActiveDirectoryScope
{
Name = level,
Path = organizationalUnit.Path
});
}
}
}
}
}
ActiveDirectoryScopeFetcher.cs
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
namespace ActiveDirectoryToolWpf
{
public class ActiveDirectoryScopeFetcher
{
internal ActiveDirectoryScopeFetcher()
{
var rootPrincipalContext = new PrincipalContext(
ContextType.Domain);
var rootDirectoryEntry = new DirectoryEntry(
rootPrincipalContext.ConnectedServer);
Scope = new ActiveDirectoryScope
{
Name = rootDirectoryEntry.Path,
Path = "LDAP://" + rootDirectoryEntry.Path
};
FetchScopeList();
}
public ActiveDirectoryScope Scope { get; set; }
private void FetchScopeList()
{
using (var directorySearcher = new DirectorySearcher(Scope.Path))
{
directorySearcher.Filter =
"(objectCategory=organizationalUnit)";
directorySearcher.PageSize = 1;
foreach (SearchResult result in directorySearcher.FindAll())
{
Scope.AddDirectoryScope(new OrganizationalUnit
{
Path = result.Path
});
}
}
Scope.Children.Sort((a, b) => a.Name.CompareTo(b.Name));
}
}
}
ActiveDirectorySearcher.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.DirectoryServices.AccountManagement;
using System.Linq;
namespace ActiveDirectoryToolWpf
{
public class ActiveDirectorySearcher
{
public ActiveDirectorySearcher(ActiveDirectoryScope scope)
{
Scope = scope;
}
private PrincipalContext PrincipalContext => new PrincipalContext(
ContextType.Domain, Scope.Domain, Scope.Context);
private ActiveDirectoryScope Scope { get; }
public static IEnumerable<ComputerPrincipal> GetComputersFromContext(
PrincipalContext context)
{
IEnumerable<ComputerPrincipal> computers;
using (var searcher = new PrincipalSearcher(
new ComputerPrincipal(context)))
{
computers =
searcher.FindAll().OfType<ComputerPrincipal>().ToList();
}
return computers;
}
public static IEnumerable<ComputerPrincipal> GetComputersFromGroup(
GroupPrincipal group)
{
return group.GetMembers().OfType<ComputerPrincipal>();
}
public static IEnumerable<DirectReports> GetDirectReportsFromContext(
PrincipalContext context)
{
return GetDirectReportsFromUsers(GetUsersFromContext(context));
}
public static IEnumerable<DirectReports> GetDirectReportsFromUsers(
IEnumerable<UserPrincipal> users)
{
return users.Select(user => new DirectReports
{
User = user,
Reports = user.GetDirectReports()
}).ToList();
}
public static IEnumerable<GroupPrincipal> GetGroupsFromContext(
PrincipalContext context)
{
return GetGroupsFromUsers(GetUsersFromContext(context));
}
public static IEnumerable<GroupPrincipal> GetGroupsFromUsers(
IEnumerable<UserPrincipal> users)
{
var groups = new HashSet<GroupPrincipal>();
foreach (var user in users)
{
groups.UnionWith(
user.GetGroups().OfType<GroupPrincipal>().ToList());
}
return groups;
}
public static IEnumerable<UserGroups> GetUserGroupsFromContext(
PrincipalContext context)
{
return GetUserGroupsFromUsers(GetUsersFromContext(context));
}
public static IEnumerable<UserGroups> GetUserGroupsFromUsers(
IEnumerable<UserPrincipal> users)
{
var userGroups = new List<UserGroups>();
foreach (var user in users)
{
var groups = new List<GroupPrincipal>();
try
{
groups.AddRange(user.GetGroups().OfType<GroupPrincipal>());
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
userGroups.Add(new UserGroups
{
User = user,
Groups = groups
});
}
return userGroups;
}
public static IEnumerable<UserPrincipal> GetUsersFromContext(
PrincipalContext context)
{
IEnumerable<UserPrincipal> users;
using (var searcher = new PrincipalSearcher(new UserPrincipal(
context)))
{
users = searcher.FindAll().OfType<UserPrincipal>().ToList();
}
return users;
}
public static IEnumerable<UserPrincipal> GetUsersFromGroup(
GroupPrincipal group)
{
return group.GetMembers().OfType<UserPrincipal>().ToList();
}
public IEnumerable<DirectReports> GetDirectReports()
{
return GetDirectReportsFromContext(PrincipalContext);
}
public IEnumerable<GroupPrincipal> GetGroups()
{
return GetGroupsFromContext(PrincipalContext);
}
public IEnumerable<UserPrincipal> GetUsers()
{
return GetUsersFromContext(PrincipalContext);
}
public IEnumerable<UserGroups> GetUsersGroups()
{
return GetUserGroupsFromContext(PrincipalContext);
}
}
public class DirectReports : ExtendedPrincipalBase, IDisposable
{
public IEnumerable<UserPrincipal> Reports { get; set; }
public void Dispose()
{
User?.Dispose();
foreach (var report in Reports)
report?.Dispose();
}
}
public abstract class ExtendedPrincipalBase
{
public UserPrincipal User { get; set; }
}
public class UserGroups : ExtendedPrincipalBase, IDisposable
{
public IEnumerable<GroupPrincipal> Groups { get; set; }
public void Dispose()
{
User?.Dispose();
foreach (var group in Groups)
group?.Dispose();
}
}
}
DataPreparer.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.DirectoryServices.AccountManagement;
using System.Dynamic;
using System.Linq;
using static ActiveDirectoryToolWpf.ActiveDirectoryAttribute;
namespace ActiveDirectoryToolWpf
{
public enum ActiveDirectoryAttribute
{
ComputerAccountExpirationDate,
ComputerAccountLockoutTime,
ComputerAllowReversiblePasswordEncryption,
ComputerBadLogonCount,
ComputerCertificates,
ComputerContext,
ComputerContextType,
ComputerDelegationPermitted,
ComputerDescription,
ComputerDisplayName,
ComputerDistinguishedName,
ComputerEnabled,
ComputerGuid,
ComputerHomeDirectory,
ComputerHomeDrive,
ComputerLastBadPasswordAttempt,
ComputerLastLogon,
ComputerLastPasswordSet,
ComputerName,
ComputerPasswordNeverExpires,
ComputerPasswordNotRequired,
ComputerPermittedLogonTimes,
ComputerPermittedWorkstations,
ComputerSamAccountName,
ComputerScriptPath,
ComputerServicePrincipalNames,
ComputerSid,
ComputerSmartcardLogonRequired,
ComputerStructuralObjectClass,
ComputerUserCannotChangePassword,
ComputerUserPrincipalName,
DirectReportUserAccountControl,
DirectReportAccountExpirationDate,
DirectReportAccountLockoutTime,
DirectReportAllowReversiblePasswordEncryption,
DirectReportAssistant,
DirectReportBadLogonCount,
DirectReportCertificates,
DirectReportCity,
DirectReportComment,
DirectReportCompany,
DirectReportContext,
DirectReportContextType,
DirectReportCountry,
DirectReportDelegationPermitted,
DirectReportDepartment,
DirectReportDescription,
DirectReportDisplayName,
DirectReportDistinguishedName,
DirectReportDivision,
DirectReportEmailAddress,
DirectReportEmployeeId,
DirectReportEnabled,
DirectReportFax,
DirectReportSuffix,
DirectReportGivenName,
DirectReportGuid,
DirectReportHomeAddress,
DirectReportHomeDirectory,
DirectReportHomeDrive,
DirectReportHomePhone,
DirectReportInitials,
DirectReportIsAccountLockedOut,
DirectReportIsActive,
DirectReportLastBadPasswordAttempt,
DirectReportLastLogon,
DirectReportLastPasswordSet,
DirectReportManager,
DirectReportMiddleName,
DirectReportMobile,
DirectReportName,
DirectReportNotes,
DirectReportPager,
DirectReportPasswordNeverExpires,
DirectReportPasswordNotRequired,
DirectReportPermittedLogonTimes,
DirectReportPermittedWorkstations,
DirectReportSamAccountName,
DirectReportScriptPath,
DirectReportSid,
DirectReportSip,
DirectReportSmartcardLogonRequired,
DirectReportState,
DirectReportStreetAddress,
DirectReportStructuralObjectClass,
DirectReportSurname,
DirectReportTitle,
DirectReportUserCannotChangePassword,
DirectReportUserPrincipalName,
DirectReportVoiceTelephoneNumber,
DirectReportVoip,
GroupContext,
GroupContextType,
GroupDescription,
GroupDisplayName,
GroupDistinguishedName,
GroupGuid,
GroupIsSecurityGroup,
GroupManagedBy,
GroupMembers,
GroupName,
GroupSamAccountName,
GroupScope,
GroupSid,
GroupStructuralObjectClass,
GroupUserPrincipalName,
UserUserAccountControl,
UserAccountExpirationDate,
UserAccountLockoutTime,
UserAllowReversiblePasswordEncryption,
UserAssistant,
UserBadLogonCount,
UserCertificates,
UserCity,
UserComment,
UserCompany,
UserContext,
UserContextType,
UserCountry,
UserDelegationPermitted,
UserDepartment,
UserDescription,
UserDisplayName,
UserDistinguishedName,
UserDivision,
UserEmailAddress,
UserEmployeeId,
UserEnabled,
UserFax,
UserSuffix,
UserGivenName,
UserGuid,
UserHomeAddress,
UserHomeDirectory,
UserHomeDrive,
UserHomePhone,
UserInitials,
UserIsAccountLockedOut,
UserIsActive,
UserLastBadPasswordAttempt,
UserLastLogon,
UserLastPasswordSet,
UserManager,
UserMiddleName,
UserMobile,
UserName,
UserNotes,
UserPager,
UserPasswordNeverExpires,
UserPasswordNotRequired,
UserPermittedLogonTimes,
UserPermittedWorkstations,
UserSamAccountName,
UserScriptPath,
UserSid,
UserSip,
UserSmartcardLogonRequired,
UserState,
UserStreetAddress,
UserStructuralObjectClass,
UserSurname,
UserTitle,
UserUserCannotChangePassword,
UserUserPrincipalName,
UserVoiceTelephoneNumber,
UserVoip
}
internal static class Extensions
{
public static DataTable ToDataTable(this IEnumerable<dynamic> items)
{
var data = items.ToArray();
if (!data.Any())
{
return null;
}
var dataTable = new DataTable();
foreach (var key in ((IDictionary<string, object>) data[0]).Keys)
{
dataTable.Columns.Add(key);
}
foreach (var d in data)
{
dataTable.Rows.Add(
((IDictionary<string, object>) d).Values.ToArray());
}
return dataTable;
}
}
internal class DataPreparer
{
internal List<ActiveDirectoryAttribute> Attributes { get; set; }
internal IEnumerable<object> Data { get; set; }
internal List<ExpandoObject> GetResults()
{
var results = new List<ExpandoObject>();
foreach (var data in Data)
{
GroupPrincipal groupPrincipal;
UserPrincipal userPrincipal;
if (data is UserGroups)
{
var userGroups = data as UserGroups;
userPrincipal = userGroups.User;
foreach (var group in userGroups.Groups)
{
groupPrincipal = group;
dynamic result = new ExpandoObject();
AddAttributesToResult(
null, groupPrincipal, null, userPrincipal, result);
results.Add(result);
}
userGroups.Dispose();
}
else if (data is DirectReports)
{
var directReports = data as DirectReports;
if (directReports.Reports == null) continue;
userPrincipal = directReports.User;
foreach (var directReport in directReports.Reports)
{
dynamic result = new ExpandoObject();
AddAttributesToResult(
null, null, directReport, userPrincipal, result);
results.Add(result);
}
directReports.Dispose();
}
else
{
var computerPrincipal = data as ComputerPrincipal;
groupPrincipal = data as GroupPrincipal;
userPrincipal = data as UserPrincipal;
dynamic result = new ExpandoObject();
AddAttributesToResult(
computerPrincipal,
groupPrincipal,
null,
userPrincipal,
result);
results.Add(result);
var principal = data as Principal;
principal?.Dispose();
}
}
return results;
}
private static bool AddComputerAttributeToResult(
ComputerPrincipal principal,
ActiveDirectoryAttribute attribute,
dynamic result)
{
var attributeMapping =
new Dictionary<ActiveDirectoryAttribute, Action>
{
[ComputerAccountExpirationDate] = () =>
result.ComputerAccountExpirationDate =
principal.AccountExpirationDate,
[ComputerAccountLockoutTime] = () =>
result.ComputerAccountLockoutTime =
principal.AccountLockoutTime,
[ComputerAllowReversiblePasswordEncryption] = () =>
result.ComputerAllowReversiblePasswordEncryption =
principal.AllowReversiblePasswordEncryption,
[ComputerBadLogonCount] = () =>
result.ComputerBadLogonCount = principal.BadLogonCount,
[ComputerCertificates] = () =>
result.ComputerCertificates = principal.Certificates,
[ComputerContext] = () =>
result.ComputerContext = principal.Context,
[ComputerContextType] = () =>
result.ComputerContextType = principal.ContextType,
[ComputerDelegationPermitted] = () =>
result.ComputerDelegationPermitted =
principal.DelegationPermitted,
[ComputerDescription] = () =>
result.ComputerDescription = principal.Description,
[ComputerDisplayName] = () =>
result.ComputerDisplayName = principal.DisplayName,
[ComputerDistinguishedName] = () =>
result.ComputerDistinguishedName =
principal.DistinguishedName,
[ComputerEnabled] = () =>
result.ComputerEnabled = principal.Enabled,
[ComputerGuid] = () => result.ComputerGuid =
principal.Guid,
[ComputerHomeDirectory] = () =>
result.ComputerHomeDirectory = principal.HomeDirectory,
[ComputerHomeDrive] = () =>
result.ComputerHomeDrive = principal.HomeDrive,
[ComputerLastBadPasswordAttempt] = () =>
result.ComputerLastBadPasswordAttempt =
principal.LastBadPasswordAttempt,
[ComputerLastLogon] = () =>
result.ComputerLastLogon = principal.LastLogon,
[ComputerLastPasswordSet] = () =>
result.LastPasswordSet = principal.LastPasswordSet,
[ComputerName] = () => result.ComputerName =
principal.Name,
[ComputerPasswordNeverExpires] = () =>
result.ComputerPasswordNeverExpires =
principal.PasswordNeverExpires,
[ComputerPasswordNotRequired] = () =>
result.ComputerPasswordNotRequired =
principal.PasswordNotRequired,
[ComputerPermittedLogonTimes] = () =>
result.ComputerPermittedLogonTimes =
principal.PermittedLogonTimes,
[ComputerPermittedWorkstations] = () =>
result.ComputerPermittedWorkstations =
principal.PermittedWorkstations,
[ComputerSamAccountName] = () =>
result.ComputerSamAccountName =
principal.SamAccountName,
[ComputerScriptPath] = () =>
result.ComputerScriptPath = principal.ScriptPath,
[ComputerServicePrincipalNames] = () =>
result.ComputerServicePrincipalNames =
principal.ServicePrincipalNames,
[ComputerSid] = () => result.ComputerSid = principal.Sid,
[ComputerSmartcardLogonRequired] = () =>
result.ComputerSmartcardLogonRequired =
principal.SmartcardLogonRequired,
[ComputerStructuralObjectClass] = () =>
result.ComputerStructuralObjectClass =
principal.StructuralObjectClass,
[ComputerUserCannotChangePassword] = () =>
result.ComputerUserCannotChangePassword =
principal.UserCannotChangePassword,
[ComputerUserPrincipalName] = () =>
result.ComputerUserPrincipalName =
principal.UserPrincipalName
};
if (!attributeMapping.ContainsKey(attribute)) return false;
attributeMapping[attribute]();
return true;
}
private static bool AddDirectReportAttributeToResult(
UserPrincipal principal,
ActiveDirectoryAttribute attribute,
dynamic result)
{
var attributeMapping =
new Dictionary<ActiveDirectoryAttribute, Action>
{
[DirectReportUserAccountControl] = () =>
result.DirectReportAccountControl =
principal.GetUserAccountControl(),
[DirectReportAccountExpirationDate] = () =>
result.DirectReportAccountExpirationDate =
principal.AccountExpirationDate,
[DirectReportAccountLockoutTime] = () =>
result.DirectReportAccountLockoutTime =
principal.AccountLockoutTime,
[DirectReportAllowReversiblePasswordEncryption] = () =>
result.DirectReportAllowReversiblePasswordEncryption =
principal.AllowReversiblePasswordEncryption,
[DirectReportAssistant] = () =>
result.DirectReportAssistant =
principal.GetAssistant(),
[DirectReportBadLogonCount] = () =>
result.DirectReportBadLogonCount =
principal.BadLogonCount,
[DirectReportCertificates] = () =>
result.DirectReportCertificates =
principal.Certificates,
[DirectReportCity] = () =>
result.DirectReportCity = principal.GetCity(),
[DirectReportComment] = () =>
result.DirectReportComment = principal.GetComment(),
[DirectReportCompany] = () =>
result.DirectReportCompany = principal.GetCompany(),
[DirectReportContext] = () =>
result.DirectReportContext = principal.Context,
[DirectReportContextType] = () =>
result.DirectReportContextType = principal.ContextType,
[DirectReportCountry] = () =>
result.DirectReportCountry = principal.GetCountry(),
[DirectReportDelegationPermitted] = () =>
result.DirectReportDelegationPermitted =
principal.DelegationPermitted,
[DirectReportDepartment] = () =>
result.DirectReportDepartment =
principal.GetDepartment(),
[DirectReportDescription] = () =>
result.DirectReportDescription = principal.Description,
[DirectReportDisplayName] = () =>
result.DirectReportDisplayName = principal.DisplayName,
[DirectReportDistinguishedName] = () =>
result.DirectReportDistinguishedName =
principal.DistinguishedName,
[DirectReportDivision] = () =>
result.DirectReportDivision = principal.GetDivision(),
[DirectReportEmailAddress] = () =>
result.DirectReportEmailAddress =
principal.EmailAddress,
[DirectReportEmployeeId] = () =>
result.DirectReportEmployeeId = principal.EmployeeId,
[DirectReportEnabled] = () =>
result.DirectReportEnabled = principal.Enabled,
[DirectReportFax] = () =>
result.DirectReportFax = principal.GetFax(),
[DirectReportSuffix] = () =>
result.DirectReportSuffix = principal.GetSuffix(),
[DirectReportGivenName] = () =>
result.DirectReportGivenName = principal.GivenName,
[DirectReportGuid] = () =>
result.DirectReportGuid = principal.Guid,
[DirectReportHomeAddress] = () =>
result.DirectReportHomeAddress =
principal.GetHomeAddress(),
[DirectReportHomeDirectory] = () =>
result.DirectReportHomeDirectory =
principal.HomeDirectory,
[DirectReportHomeDrive] = () =>
result.DirectReportHomeDrive = principal.HomeDrive,
[DirectReportHomePhone] = () =>
result.DirectReportHomePhone =
principal.GetHomePhone(),
[DirectReportInitials] = () =>
result.DirectReportInitials = principal.GetInitials(),
[DirectReportIsAccountLockedOut] = () =>
result.DirectReportIsAccountLockedOut =
principal.IsAccountLockedOut(),
[DirectReportIsActive] = () =>
result.DirectReportIsActive = principal.IsActive(),
[DirectReportLastBadPasswordAttempt] = () =>
result.DirectReportLastBadPasswordAttempt =
principal.LastBadPasswordAttempt,
[DirectReportLastLogon] = () =>
result.DirectReportLastLogon = principal.LastLogon,
[DirectReportLastPasswordSet] = () =>
result.DirectReportLastPasswordSet =
principal.LastPasswordSet,
[DirectReportManager] = () =>
result.DirectReportManager = principal.GetManager(),
[DirectReportMiddleName] = () =>
result.DirectReportMiddleName = principal.MiddleName,
[DirectReportMobile] = () =>
result.DirectReportMobile = principal.GetMobile(),
[DirectReportName] = () =>
result.DirectReportName = principal.Name,
[DirectReportNotes] = () =>
result.DirectReportNotes = principal.GetNotes(),
[DirectReportPager] = () =>
result.DirectReportPager = principal.GetPager(),
[DirectReportPasswordNeverExpires] = () =>
result.DirectReportPasswordNeverExpires =
principal.PasswordNeverExpires,
[DirectReportPasswordNotRequired] = () =>
result.DirectReportPasswordNotRequired =
principal.PasswordNotRequired,
[DirectReportPermittedLogonTimes] = () =>
result.DirectReportPermittedLogonTimes =
principal.PermittedLogonTimes,
[DirectReportPermittedWorkstations] = () =>
result.DirectReportPermittedWorkstations =
principal.PermittedWorkstations,
[DirectReportSamAccountName] = () =>
result.DirectReportSamAccountName =
principal.SamAccountName,
[DirectReportScriptPath] = () =>
result.DirectReportScriptPath = principal.ScriptPath,
[DirectReportSid] = () =>
result.DirectReportSid = principal.Sid,
[DirectReportSip] = () =>
result.DirectReportSip = principal.GetSip(),
[DirectReportSmartcardLogonRequired] = () =>
result.DirectReportSmartcardLogonRequired =
principal.SmartcardLogonRequired,
[DirectReportState] = () =>
result.DirectReportState = principal.GetState(),
[DirectReportStreetAddress] = () =>
result.DirectReportStreetAddress =
principal.GetStreetAddress(),
[DirectReportStructuralObjectClass] = () =>
result.DirectReportStructuralObjectClass =
principal.StructuralObjectClass,
[DirectReportSurname] = () =>
result.DirectReportSurname = principal.Surname,
[DirectReportTitle] = () =>
result.DirectReportTitle = principal.GetTitle(),
[DirectReportUserCannotChangePassword] = () =>
result.DirectReportUserCannotChangePassword =
principal.UserCannotChangePassword,
[DirectReportUserPrincipalName] = () =>
result.DirectReportUserPrincipalName =
principal.UserPrincipalName,
[DirectReportVoiceTelephoneNumber] = () =>
result.DirectReportVoiceTelephoneNumber =
principal.VoiceTelephoneNumber,
[DirectReportVoip] = () =>
result.DirectReportVoip = principal.GetVoip()
};
if (!attributeMapping.ContainsKey(attribute)) return false;
attributeMapping[attribute]();
return true;
}
private static bool AddGroupAttributeToResult(
GroupPrincipal principal,
ActiveDirectoryAttribute attribute,
dynamic result)
{
var attributeMapping =
new Dictionary<ActiveDirectoryAttribute, Action>
{
[GroupContext] =
() => result.GroupContext = principal.Context,
[GroupContextType] = () =>
result.GroupContextType = principal.ContextType,
[GroupDescription] = () =>
result.GroupDescription = principal.Description,
[GroupDisplayName] = () =>
result.GroupDisplayName = principal.DisplayName,
[GroupDistinguishedName] = () =>
result.GroupDistinguishedName =
principal.DistinguishedName,
[GroupGuid] = () => result.GroupGuid = principal.Guid,
[GroupIsSecurityGroup] = () =>
result.GroupIsSecurityGroup =
principal.IsSecurityGroup,
[GroupManagedBy] = () =>
result.GroupManagedBy = principal.GetManagedBy(),
[GroupName] = () => result.GroupName = principal.Name,
[GroupSamAccountName] = () =>
result.GroupSamAccountName = principal.SamAccountName,
[ActiveDirectoryAttribute.GroupScope] = () =>
result.GroupScope = principal.GroupScope,
[GroupSid] = () => result.GroupSid = principal.Sid,
[GroupStructuralObjectClass] = () =>
result.GroupStructuralObjectClass =
principal.StructuralObjectClass,
[GroupUserPrincipalName] = () =>
result.GroupUserPrincipalName =
principal.UserPrincipalName,
[GroupMembers] =
() => result.GroupMembers = principal.Members
};
if (!attributeMapping.ContainsKey(attribute)) return false;
attributeMapping[attribute]();
return true;
}
private static void AddUserAttributeToResult(
UserPrincipal principal,
ActiveDirectoryAttribute attribute,
dynamic result)
{
var attributeMapping =
new Dictionary<ActiveDirectoryAttribute, Action>
{
[UserUserAccountControl] = () =>
result.UserAccountControl =
principal.GetUserAccountControl(),
[UserAccountExpirationDate] = () =>
result.UserAccountExpirationDate =
principal.AccountExpirationDate,
[UserAccountLockoutTime] = () =>
result.UserAccountLockoutTime =
principal.AccountLockoutTime,
[UserAllowReversiblePasswordEncryption] = () =>
result.UserAllowReversiblePasswordEncryption =
principal.AllowReversiblePasswordEncryption,
[UserAssistant] = () =>
result.UserAssistant = principal.GetAssistant(),
[UserBadLogonCount] = () =>
result.UserBadLogonCount = principal.BadLogonCount,
[UserCertificates] = () =>
result.UserCertificates = principal.Certificates,
[UserCity] = () =>
result.UserCity = principal.GetCity(),
[UserComment] = () =>
result.UserComment = principal.GetComment(),
[UserCompany] = () =>
result.UserCompany = principal.GetCompany(),
[UserContext] = () =>
result.UserContext = principal.Context,
[UserContextType] = () =>
result.UserContextType = principal.ContextType,
[UserCountry] = () =>
result.UserCountry = principal.GetCountry(),
[UserDelegationPermitted] = () =>
result.UserDelegationPermitted =
principal.DelegationPermitted,
[UserDepartment] = () =>
result.UserDepartment = principal.GetDepartment(),
[UserDescription] = () =>
result.UserDescription = principal.Description,
[UserDisplayName] = () =>
result.UserDisplayName = principal.DisplayName,
[UserDistinguishedName] = () =>
result.UserDistinguishedName =
principal.DistinguishedName,
[UserDivision] = () =>
result.UserDivision = principal.GetDivision(),
[UserEmailAddress] = () =>
result.UserEmailAddress = principal.EmailAddress,
[UserEmployeeId] = () =>
result.UserEmployeeId = principal.EmployeeId,
[UserEnabled] = () =>
result.UserEnabled = principal.Enabled,
[UserFax] = () =>
result.UserFax = principal.GetFax(),
[UserSuffix] = () =>
result.UserSuffix = principal.GetSuffix(),
[UserGivenName] = () =>
result.UserGivenName = principal.GivenName,
[UserGuid] = () =>
result.UserGuid = principal.Guid,
[UserHomeAddress] = () =>
result.UserHomeAddress = principal.GetHomeAddress(),
[UserHomeDirectory] = () =>
result.UserHomeDirectory = principal.HomeDirectory,
[UserHomeDrive] = () =>
result.UserHomeDrive = principal.HomeDrive,
[UserHomePhone] = () =>
result.UserHomePhone = principal.GetHomePhone(),
[UserInitials] = () =>
result.UserInitials = principal.GetInitials(),
[UserIsAccountLockedOut] = () =>
result.UserIsAccountLockedOut =
principal.IsAccountLockedOut(),
[UserIsActive] = () =>
result.UserIsActive = principal.IsActive(),
[UserLastBadPasswordAttempt] = () =>
result.UserLastBadPasswordAttempt =
principal.LastBadPasswordAttempt,
[UserLastLogon] = () =>
result.UserLastLogon = principal.LastLogon,
[UserLastPasswordSet] = () =>
result.UserLastPasswordSet = principal.LastPasswordSet,
[UserManager] = () =>
result.UserManager = principal.GetManager(),
[UserMiddleName] = () =>
result.UserMiddleName = principal.MiddleName,
[UserMobile] = () =>
result.UserMobile = principal.GetMobile(),
[UserName] = () =>
result.UserName = principal.Name,
[UserNotes] = () =>
result.UserNotes = principal.GetNotes(),
[UserPager] = () =>
result.UserPager = principal.GetPager(),
[UserPasswordNeverExpires] = () =>
result.UserPasswordNeverExpires =
principal.PasswordNeverExpires,
[UserPasswordNotRequired] = () =>
result.UserPasswordNotRequired =
principal.PasswordNotRequired,
[UserPermittedLogonTimes] = () =>
result.UserPermittedLogonTimes =
principal.PermittedLogonTimes,
[UserPermittedWorkstations] = () =>
result.UserPermittedWorkstations =
principal.PermittedWorkstations,
[UserSamAccountName] = () =>
result.UserSamAccountName = principal.SamAccountName,
[UserScriptPath] = () =>
result.UserScriptPath = principal.ScriptPath,
[UserSid] = () =>
result.UserSid = principal.Sid,
[UserSip] = () =>
result.UserSip = principal.GetSip(),
[UserSmartcardLogonRequired] = () =>
result.UserSmartcardLogonRequired =
principal.SmartcardLogonRequired,
[UserState] = () =>
result.UserState = principal.GetState(),
[UserStreetAddress] = () =>
result.UserStreetAddress =
principal.GetStreetAddress(),
[UserStructuralObjectClass] = () =>
result.UserStructuralObjectClass =
principal.StructuralObjectClass,
[UserSurname] = () =>
result.UserSurname = principal.Surname,
[UserTitle] = () =>
result.UserTitle = principal.GetTitle(),
[UserUserCannotChangePassword] = () =>
result.UserUserCannotChangePassword =
principal.UserCannotChangePassword,
[UserUserPrincipalName] = () =>
result.UserUserPrincipalName =
principal.UserPrincipalName,
[UserVoiceTelephoneNumber] = () =>
result.UserVoiceTelephoneNumber =
principal.VoiceTelephoneNumber,
[UserVoip] = () =>
result.UserVoip = principal.GetVoip()
};
if (!attributeMapping.ContainsKey(attribute)) return;
attributeMapping[attribute]();
}
private void AddAttributesToResult(
ComputerPrincipal computerPrincipal,
GroupPrincipal groupPrincipal,
UserPrincipal directReportUserPrincipal,
UserPrincipal userPrincipal,
dynamic result)
{
foreach (var attribute in Attributes)
{
if (computerPrincipal != null)
{
if (AddComputerAttributeToResult(
computerPrincipal, attribute, result))
{
continue;
}
}
if (directReportUserPrincipal != null)
{
if (AddDirectReportAttributeToResult(
directReportUserPrincipal, attribute, result))
{
continue;
}
}
if (groupPrincipal != null)
{
if (AddGroupAttributeToResult(
groupPrincipal, attribute, result))
{
continue;
}
}
if (userPrincipal != null)
{
AddUserAttributeToResult(userPrincipal, attribute, result);
}
}
}
}
}
OrganizationalUnit.cs
using System;
namespace ActiveDirectoryToolWpf
{
internal class OrganizationalUnit
{
private const char Comma = ',';
private const string DomainComponentPrefix = ",DC=";
private const string LdapProtocol = "LDAP://";
private const string OrganizationalUnitPrefix = "OU=";
private const int StringStartIndex = 0;
internal string Path { get; set; }
internal string[] Split
{
get
{
var namesOnly = Path.Replace(LdapProtocol, string.Empty)
.Replace(OrganizationalUnitPrefix, string.Empty);
var firstDomainComponentIndex = namesOnly.IndexOf(
DomainComponentPrefix, StringComparison.Ordinal);
namesOnly = namesOnly.Substring(
StringStartIndex, firstDomainComponentIndex);
var split = namesOnly.Split(Comma);
Array.Reverse(split);
return split;
}
}
}
}
I have omitted several classes that provide only extension methods, as I am out of room.