Чтобы определить, являются ли учетные записи компьютеров осиротевшими, я хотел бы запросить все контроллеры домена всех доверенных доменов, чтобы получить lastLogon и lastLogonTimeStamp для всех компьютеров.У меня есть программа, которая работает (по крайней мере, в моей тестовой среде), но у меня есть несколько вопросов, на которые, я надеюсь, вы сможете ответить.
Методы, которые я используюиспользовать, чтобы найти домены и контроллеры доменов, а затем извлечь информацию AD, используя как можно меньше ресурсов (ЦП и ОЗУ контроллера сети / контроллера домена)?Как их можно улучшить?
Можно ли иметь более 1 значения в паре словарь ключ / значение?Наличие словаря для LastLogIn и другого для LastLogInTimestamp кажется бесполезным.
Ссылка на словарь и свойства AD: как проверить несуществующие значения в отличие от использования Try/ Catch?
try {// Этот DC больше тока, чем последний?if (dict_LastLogIn [pc] <(long) result.Properties ["lastlogon"] [0]) {dict_LastLogIn [pc] = (long) result.Properties ["lastlogon"] [0];}} catch {// Элемент еще не существует .. try {dict_LastLogIn [pc] = (long) result.Properties ["lastlogon"] [0];} catch {// .. или // Нет последнего LastLogin ... dict_LastLogIn [pc] = 0;}} </p>
Вот весь код:
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace dictionary
{
class Program
{
internal static Dictionary<string, long> dict_LastLogIn =
new Dictionary<string, long>();
internal static Dictionary<string, long> dict_LastLogInTimeStamp =
new Dictionary<string, long>();
internal static Dictionary<string, DateTime> output =
new Dictionary<string, DateTime>();
internal static bool AreAllDCsResponding = true;
static void Main(string[] args)
{
Console.BufferWidth = 150;
Console.BufferHeight = 9999;
Console.WindowWidth = 150;
Dictionary<String, int> dict_domainList = new Dictionary<String, int>();
Dictionary<String, int> dict_dcList = new Dictionary<String, int>();
//Get the current domain's trusts.
Domain currentDomain = Domain.GetCurrentDomain();
Console.WriteLine("Retrieved the current Domain as {0}", currentDomain.ToString());
var domainTrusts = currentDomain.GetAllTrustRelationships();
Console.WriteLine(" {0} trusts were found.", domainTrusts.Count);
//Add the current domain to the dictonary. It won't be in domainTrusts!
dict_domainList.Add(currentDomain.ToString(), 0);
// Then add the other domains to the dictonary...
foreach (TrustRelationshipInformation trust in domainTrusts)
{
dict_domainList.Add(trust.TargetName.Substring(0, trust.TargetName.IndexOf(".")).ToUpper(), 0);
Console.WriteLine(" Adding {0} to the list of trusts.", trust.TargetName.Substring(0, trust.TargetName.IndexOf(".")).ToUpper());
}
// Now get all DCs per domain
foreach (var pair in dict_domainList)
{
DirectoryContext dc = new DirectoryContext(DirectoryContextType.Domain, pair.Key);
Domain _Domain = Domain.GetDomain(dc);
foreach (DomainController Server in _Domain.DomainControllers)
{
dict_dcList.Add(Server.Name, 0);
Console.WriteLine(" Adding {0} to the list of DCs.", Server.Name.ToUpper());
}
// Now search through every DC
foreach (var _pair in dict_dcList)
{
Console.WriteLine(" Querying {0} for Computer objects.", _pair.Key.ToUpper());
Search(pair.Key);
Console.WriteLine("\n");
Console.WriteLine("The following Computer objects were found:");
}
if (AreAllDCsResponding == true)
{
ConvertTimeStamp(dict_LastLogIn);
}
else
{
ConvertTimeStamp(dict_LastLogInTimeStamp);
}
Console.ReadLine();
}
}
internal static void Search(string domainName)
{
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domainName);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = ("(&(ObjectCategory=computer))");//(lastlogon=*)(lastlogonTimeStamp=*))");
mySearcher.SizeLimit = int.MaxValue;
mySearcher.PropertiesToLoad.Add("DistinguishedName");
mySearcher.PropertiesToLoad.Add("lastlogon");
mySearcher.PropertiesToLoad.Add("lastlogonTimeStamp");
try
{
foreach (System.DirectoryServices.SearchResult result in mySearcher.FindAll())
{
string pc = result.Properties["DistinguishedName"][0].ToString();
try
{ // Is this DC more current than the last?
if (dict_LastLogIn[pc] < (long)result.Properties["lastlogon"][0])
{
dict_LastLogIn[pc] = (long)result.Properties["lastlogon"][0];
}
}
catch
{ // The item doesn't exist yet..
try
{
dict_LastLogIn[pc] = (long)result.Properties["lastlogon"][0];
}
catch
{ // .. or
// There is no last LastLogin...
dict_LastLogIn[pc] = 0;
}
}
try
{
// Not yet replicated?...
if (dict_LastLogInTimeStamp[pc] < (long)result.Properties["lastlogonTimeStamp"][0])
{
dict_LastLogInTimeStamp[pc] = (long)result.Properties["lastlogonTimeStamp"][0];
}
}
catch
{ // The item doesn't exist yet..
try
{
dict_LastLogInTimeStamp[pc] = (long)result.Properties["lastlogonTimeStamp"][0];
}
catch
{ // .. or
// There is no last LastLoginTimeStamp...
dict_LastLogInTimeStamp[pc] = 0;
}
}
}
}
catch (System.Runtime.InteropServices.COMException)
{
//If even one DC doesn't answer, don't use LastLogon!
//Use the less accurate, but replicated(!) LastLogonTimeStamp.
AreAllDCsResponding = false;
}
}
internal static void ConvertTimeStamp(Dictionary<string, long> _dict)
{
foreach (var pair in _dict)
{
output.Add(pair.Key, DateTime.FromFileTime(pair.Value));
Console.WriteLine("{0} - {1}", pair.Key, DateTime.FromFileTime(pair.Value));
}
}
}
}
Спасибо за любую помощь, которую вы можете предложить.