Skip to main content
Code Review

Return to Question

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

This is an update to my previous post about my Active Directory Query Application Active Directory Query Application. I have made multiple modifications, and I request some feedback.

This is an update to my previous post about my Active Directory Query Application. I have made multiple modifications, and I request some feedback.

This is an update to my previous post about my Active Directory Query Application. I have made multiple modifications, and I request some feedback.

Source Link

Active Directory Query Application - Take 2

This is an update to my previous post about my Active Directory Query Application. I have made multiple modifications, and I request some feedback.

Summary: This program queries an active directory and writes either a list of the users or a list of the users with a list of the groups each user belongs to. The search is done in an Organizational Unit selected via a dropdown. Files are saved to .csv.

"Problems" I'd Appreciate Commentary On:

  1. The front end (ActiveDirectoryTool) does a bit of what seems to be back end work, but if I move the work to the back end, I don't see how I can have the front end report progress.

  2. On the same note, the front end's backgroundWorker_DoWork method is very complex, but aside from chopping it into separate methods for each of the cases, I don't know what to do.

  3. It feels like I have a lot of duplicate code, but I don't see how to trim things down without losing functionality.

ActiveDirectoryTool

using ActiveDirectoryTool.ActiveDirectoryToolBackend;
using System;
using System.ComponentModel;
using System.DirectoryServices.AccountManagement;
using System.Windows.Forms;
using static ActiveDirectoryTool.ActiveDirectoryToolBackend
 .ActiveDirectoryToolConstants;
namespace ActiveDirectoryTool
{
 public partial class ActiveDirectoryTool : Form
 {
 private ActiveDirectoryToolBackEnd backEnd;
 private Task currentTask;
 public ActiveDirectoryTool()
 {
 InitializeComponent();
 backEnd = new ActiveDirectoryToolBackEnd();
 UpdateDisplay();
 }
 private enum Task
 {
 PrintAllUsers,
 PrintAllUserGroups,
 PrintAllGroups,
 PrintAllComputers
 }
 private void backgroundWorker_ProgressChanged(object sender,
 ProgressChangedEventArgs e)
 {
 progressBar.Value = e.ProgressPercentage;
 var counts = (Tuple<int, int>)e.UserState;
 progressLabel.Text = counts.Item1 + ProgressLabelDivider
 + counts.Item2;
 }
 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
 {
 try
 {
 int percentComplete = 0;
 int currentCount = 0;
 switch (currentTask)
 {
 case Task.PrintAllUsers:
 var users = backEnd.GetUsers();
 var filename = backEnd.AllUsersFilename;
 backEnd.WriteHeaderToFile(filename, Header.User);
 for (int i = 0; i < users.Count; i++)
 {
 currentCount = i + 1;
 backEnd.WriteUserToFile(filename, users[i]);
 percentComplete = currentCount * PercentMultiplier
 / users.Count;
 backgroundWorker.ReportProgress(percentComplete,
 new Tuple<int, int>(currentCount,
 users.Count));
 }
 MessageBox.Show("Wrote all users to " + filename);
 break;
 case Task.PrintAllUserGroups:
 users = backEnd.GetUsers();
 filename = backEnd.AllUsersGroupsFilename;
 backEnd.WriteHeaderToFile(filename, Header.UserGroup);
 for (int i = 0; i < users.Count; i++)
 {
 currentCount = i + 1;
 try
 {
 foreach (GroupPrincipal group in users[i]
 .GetGroups())
 {
 backEnd.WriteUserGroupsToFile(filename,
 users[i], group);
 }
 }
 catch (Exception exc)
 {
 Console.WriteLine(exc.StackTrace);
 continue;
 }
 percentComplete = currentCount * PercentMultiplier
 / users.Count;
 backgroundWorker.ReportProgress(percentComplete,
 new Tuple<int, int>(currentCount,
 users.Count));
 }
 MessageBox.Show("Wrote all users' groups to "
 + filename);
 break;
 // TODO
 case Task.PrintAllGroups:
 break;
 // TODO
 case Task.PrintAllComputers:
 break;
 }
 }
 catch (Exception exc)
 {
 MessageBox.Show("Exception: " + exc.Message + "\n"
 + exc.StackTrace);
 }
 }
 private void backgroundWorker_RunWorkerCompleted(object sender,
 RunWorkerCompletedEventArgs e)
 {
 progressBar.Value = 0;
 progressLabel.Text = "Awaiting task...";
 this.Enabled = true;
 }
 private void getAllUsers_Click(object sender, EventArgs e)
 {
 PerformTask(Task.PrintAllUsers);
 }
 private void organizationalUnits_SelectedIndexChanged(object sender,
 EventArgs e)
 {
 backEnd.Scope = backEnd.OrganizationalUnits[organizationalUnits
 .SelectedIndex];
 }
 private void PerformTask(Task task)
 {
 if (!backgroundWorker.IsBusy
 && organizationalUnits.SelectedIndex > -1)
 {
 this.Enabled = false;
 currentTask = task;
 backgroundWorker.RunWorkerAsync();
 }
 else if (organizationalUnits.SelectedIndex < 0)
 {
 MessageBox.Show("Please select an Organizational Unit!");
 }
 else
 {
 MessageBox.Show("Currently performing an operation!");
 }
 }
 private void printAllComputers_Click(object sender, EventArgs e)
 {
 PerformTask(Task.PrintAllComputers);
 }
 private void printAllGroups_Click(object sender, EventArgs e)
 {
 PerformTask(Task.PrintAllGroups);
 }
 private void printAllUserGroups_Click(object sender, EventArgs e)
 {
 PerformTask(Task.PrintAllUserGroups);
 }
 private void UpdateDisplay()
 {
 foreach (var organizationalUnit in backEnd.OrganizationalUnits)
 {
 string organizationalUnitDisplay = organizationalUnit
 .Replace(",OU=Accounts,OU=Domtar,OU=DPP,DC=dnet,DC=domtar",
 "")
 .Replace("OU=", "");
 organizationalUnits.Items.Add(organizationalUnitDisplay);
 }
 }
 }
}

ActiveDirectoryToolBackend

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.IO;
using static ActiveDirectoryTool.ActiveDirectoryToolBackend
 .ActiveDirectoryToolConstants;
namespace ActiveDirectoryTool.ActiveDirectoryToolBackend
{
 internal enum Header
 {
 User,
 Group,
 UserGroup,
 Computer
 }
 internal class ActiveDirectoryToolBackEnd
 {
 private string path = Path.Combine(Environment
 .GetFolderPath(Environment.SpecialFolder.MyDocuments),
 FolderName);
 public ActiveDirectoryToolBackEnd()
 {
 Directory.CreateDirectory(path);
 }
 public string AllUsersFilename
 {
 get
 {
 return Path.Combine(path, GenerateFilename(FilenameUsers));
 }
 }
 public string AllUsersGroupsFilename
 {
 get
 {
 return Path.Combine(path,
 GenerateFilename(FilenameUserGroups));
 }
 }
 public List<string> OrganizationalUnits
 {
 get
 {
 var organizationalUnits = new List<string>();
 DirectoryEntry userRoot = new DirectoryEntry(
 DefaultUserOrganizationalUnitsRoot);
 var searcher = new DirectorySearcher(userRoot);
 searcher.Filter = DirectorySearcherFilterOrganizationalUnits;
 searcher.SearchScope = SearchScope.OneLevel;
 foreach (SearchResult result in searcher.FindAll())
 {
 string resultString = result.Path.Replace(LdapPrefix,
 String.Empty);
 organizationalUnits.Add(resultString);
 }
 return organizationalUnits;
 }
 }
 public String Scope { get; set; }
 public List<UserPrincipal> GetUsers()
 {
 var users = new List<UserPrincipal>();
 using (var searcher = new PrincipalSearcher(new UserPrincipal(
 GetPrincipalContext())))
 {
 foreach (UserPrincipal user in searcher.FindAll())
 {
 users.Add(user);
 }
 }
 return users;
 }
 public void WriteHeaderToFile(string filename, Header header)
 {
 using (var writer = new StreamWriter(filename))
 {
 writer.WriteLine(CommaSeparatedValuesSeparatorSemicolon);
 switch (header)
 {
 case Header.User:
 writer.WriteLine(HeaderUser);
 break;
 case Header.Group:
 writer.WriteLine(HeaderGroup);
 break;
 case Header.UserGroup:
 writer.WriteLine(HeaderUserGroup);
 break;
 case Header.Computer:
 writer.WriteLine(HeaderComputer);
 break;
 }
 }
 }
 public void WriteUserGroupsToFile(string filename, UserPrincipal user,
 GroupPrincipal group)
 {
 using (var writer = new StreamWriter(filename, true))
 {
 writer.WriteLine(UserGroupAsString(user, group));
 }
 }
 public void WriteUserToFile(string filename, UserPrincipal user)
 {
 using (var writer = new StreamWriter(filename, true))
 {
 writer.WriteLine(UserAsString(user));
 }
 }
 private string ComputerAsString(ComputerPrincipal computer)
 {
 return String.Join(
 Char.ToString(Tab),
 computer.Name);
 }
 private string GenerateFilename(string fileType)
 {
 return fileType + Hyphen + DateTime.Now.ToString(DateTimeFormat)
 + DefaultExtension;
 }
 private PrincipalContext GetPrincipalContext()
 {
 return new PrincipalContext(ContextType.Domain, Domain,
 Scope);
 }
 private string GroupAsString(GroupPrincipal group)
 {
 DirectoryEntry entry = group.GetUnderlyingObject() as
 DirectoryEntry;
 string manager = (string)entry.Properties[PropertyManager].Value;
 if (String.IsNullOrWhiteSpace(manager))
 {
 manager = PropertyNone;
 }
 return String.Join(
 Char.ToString(Tab),
 group.SamAccountName,
 manager,
 group.Description,
 group.DistinguishedName);
 }
 private bool IsActive(DirectoryEntry de)
 {
 if (de.NativeGuid == null) return false;
 int flags = (int)de.Properties[PropertyUserAccountControl].Value;
 return !Convert.ToBoolean(flags & 0x0002);
 }
 private string UserAsString(UserPrincipal user)
 {
 DirectoryEntry entry = user.GetUnderlyingObject() as
 DirectoryEntry;
 return string.Join(
 Char.ToString(Semicolon),
 user.Surname,
 user.GivenName,
 user.DisplayName,
 user.SamAccountName,
 IsActive(entry).ToString(),
 user.IsAccountLockedOut().ToString(),
 user.Description,
 user.HomeDrive,
 user.HomeDirectory,
 user.ScriptPath,
 user.EmailAddress,
 (string)entry.Properties[PropertyStreetAddress].Value,
 (string)entry.Properties[PropertyCity].Value,
 (string)entry.Properties[PropertyState].Value,
 user.VoiceTelephoneNumber,
 user.DistinguishedName);
 }
 private string UserGroupAsString(UserPrincipal user,
 GroupPrincipal group)
 {
 return String.Join(
 Char.ToString(Semicolon),
 user.SamAccountName,
 group.SamAccountName,
 user.Name,
 user.DistinguishedName);
 }
 }
}

ActiveDirectoryToolConstants

namespace ActiveDirectoryTool.ActiveDirectoryToolBackend
{
 internal static class ActiveDirectoryToolConstants
 {
 public const char Comma = ',';
 public const char Hyphen = '-';
 public const char Quote = '"';
 public const char Semicolon = ';';
 public const char Tab = '\t';
 public const int PercentMultiplier = 100;
 public const string CommaSeparatedValuesExtension = ".csv";
 public const string CommaSeparatedValuesSeparatorSemicolon = "sep=;";
 public const string DateTimeFormat = "yyyyMMddTHHmmss";
 public const string DefaultExtension = CommaSeparatedValuesExtension;
 public const string DefaultUserOrganizationalUnitsRoot
 = "LDAP://OU=Accounts,OU=Domtar,OU=DPP,DC=dnet,DC=domtar";
 public const string DirectorySearcherFilterOrganizationalUnits
 = "(objectCategory=organizationalUnit)";
 public const string Domain = "dnet.domtar";
 public const string FilenameComputers = "Computers";
 public const string FilenameGroups = "Groups";
 public const string FilenameUserGroups = "UserGroups";
 public const string FilenameUsers = "Users";
 public const string FolderName = "ActiveDirectoryTool";
 public const string HeaderComputer = "Name";
 public const string HeaderGroup =
 "Group Name;Group ID;Managed By;Description;Distinguished Name";
 public const string HeaderUser
 = "Last;First;Display Name;ID;Active;Locked;Description;"
 + "Home Drive;Home Folder;Login Script;Email;Street;City;State;"
 + "Phone;Distinguished Name";
 public const string HeaderUserGroup
 = "User ID;Group;User Full Name;User Distinguished Name";
 public const string LdapPrefix = "LDAP://";
 public const string PlainTextExtension = ".txt";
 public const string ProgressLabelDivider = " of ";
 public const string PropertyCity = "l";
 public const string PropertyManager = "managedBy";
 public const string PropertyNone = "none";
 public const string PropertyState = "st";
 public const string PropertyStreetAddress = "streetAddress";
 public const string PropertyUserAccountControl = "userAccountControl";
 public const string TabSeparatedValuesExtension = ".tsv";
 }
}
lang-cs

AltStyle によって変換されたページ (->オリジナル) /