たとえば、Active Directory がサイト間でデータをレプリケートするのに時間がかかりすぎる場合、ローカルの AD レプリカに最新の情報が含まれていることを確認する必要があります。
- 現在のサイトの DomainControllers のリストを取得するにはどうすればよいですか?
CodeprojectまたはStackOverflowで何も見つかりませんでした
たとえば、Active Directory がサイト間でデータをレプリケートするのに時間がかかりすぎる場合、ローカルの AD レプリカに最新の情報が含まれていることを確認する必要があります。
CodeprojectまたはStackOverflowで何も見つかりませんでした
このすべての問題に取り組むことは、おそらく無駄な努力です。ドメインコントローラーを見つけるための組み込みロジックで問題が発生していない限り、ドメインコントローラーを返す組み込みメソッドを使用する必要があります。Microsoftによると、それは自動的に近いものを見つけようとします:http ://technet.microsoft.com/en-us/library/cc978016.aspx 。
静的DomainController.FindOne
メソッドを使用して、を渡しますdirectorycontext
。
了解しました
。以下のコードを試してみてください。どのように機能するか教えてください。それぞれにpingを実行し、ラウンドトリップ時間を返します。-1(接続なし)の場合はスキップします。存在する場合、PDCステータスにフラグを立てます。PDCステータスによる注文、続いてping往復。
static void Main(string[] args)
{
var dcsInOrder = (from DomainController c in Domain.GetCurrentDomain().DomainControllers
let responseTime = Pinger(c.Name)
where responseTime >=0
let pdcStatus = c.Roles.Contains(ActiveDirectoryRole.PdcRole)
orderby pdcStatus, responseTime
select new {DC = c, ResponseTime = responseTime}
).ToList();
foreach (var dc in dcsInOrder)
{
System.Console.WriteLine(dc.DC.Name + " - " + dc.ResponseTime);
}
System.Console.ReadLine();
}
private static int Pinger(string address)
{
Ping p = new Ping();
try
{
PingReply reply = p.Send(address, 3000);
if (reply.Status == IPStatus.Success) return (int)reply.RoundtripTime;
}
catch { }
return -1;
}
まず、あなたが実際に尋ねた質問に答えます。
System.DirectoryServices.ActiveDirectory.ActiveDirectorySite.GetComputerSite().Servers
しかし、可能な限り最も近いドメイン コントローラーと通信していることを確認する方法を尋ねているようです。Windows はこの機能を正確に提供しているわけではありません。コードが実行されているサイトと同じサイトにドメイン コントローラーを提供するのが最善の方法です。
最初に確認することは、サイトとサブネットが正しく構成されていることだと思います。Active Directory サイトとサービスを実行し、サブネットとドメイン コントローラーが正しいサイトに割り当てられていることを確認します。
この MSDN ページ(および Peter の回答の Technet 記事) には、現在のサイトで DC を検索するには、DC ロケーターの DNS 名で検索する必要があると書かれています。Domain クラスの Name プロパティが DNS ドメイン名かどうかはわかりません。
DomainController.FindOne は のラッパーであると想定する必要がありますDsGetDcName
。そのリンクで、その関数のトレースをオンにする方法を見つけることができます。問題が解決しない場合は、これを使用するか、この関数を PInvoke する必要があります。
DC のハード コーディングがないコード サンプルを次に示します。コメントと批判は大歓迎です。
/// <summary>
/// For best results ensure all hosts are pingable, and turned on.
/// </summary>
/// <returns>An ordered list of DCs with the PDCE first</returns>
static LinkedList<DomainController> GetNearbyDCs()
{
LinkedList<DomainController> preferredDCs = new LinkedList<DomainController>();
List<string> TestedDCs = new List<string>();
using (var mysite = ActiveDirectorySite.GetComputerSite())
{
using (var currentDomain = Domain.GetCurrentDomain())
{
DirectoryContext dctx = new DirectoryContext(DirectoryContextType.Domain, currentDomain.Name);
var listOfDCs = DomainController.FindAll(dctx, mysite.Name);
foreach (DomainController item in listOfDCs)
{
Console.WriteLine(item.Name );
if (IsConnected(item.IPAddress))
{
// Enumerating "Roles" will cause the object to bind to the server
ActiveDirectoryRoleCollection rollColl = item.Roles;
if (rollColl.Count > 0)
{
foreach (ActiveDirectoryRole roleItem in rollColl)
{
if (!TestedDCs.Contains(item.Name))
{
TestedDCs.Add(item.Name);
if (roleItem == ActiveDirectoryRole.PdcRole)
{
preferredDCs.AddFirst(item);
break;
}
else
{
if (preferredDCs.Count > 0)
{
var tmp = preferredDCs.First;
preferredDCs.AddBefore(tmp, item);
}
else
{
preferredDCs.AddFirst(item);
}
break;
}
}
}
}
else
{
// The DC exists but has no roles
TestedDCs.Add(item.Name);
if (preferredDCs.Count > 0)
{
var tmp = preferredDCs.First;
preferredDCs.AddBefore(tmp, item);
}
else
{
preferredDCs.AddFirst(item);
}
}
}
else
{
preferredDCs.AddLast(item);
}
}
}
}
return preferredDCs;
}
static bool IsConnected(string hostToPing)
{
string pingurl = string.Format("{0}", hostToPing);
string host = pingurl;
bool result = false;
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
return true;
}
catch { }
return result;
}