Active Directoryの同期

当直には、Active Directoryに対処する必要がありました。 読んで、クラスで実験しなければなりませんでしたが、結果としてすべてが完璧に機能しました。

まず、.net framework 2.0に登場した小さなディレクトリ同期オブジェクトについて説明したいと思います。 マイクロソフトのWebサイト(http://msdn.microsoft.com/en-us/magazine/cc188700.aspx)で第2フレームワークのその他の利点について読むことができます。 個人的には、この記事は私がそれを理解するのに役立ちましたが、dyrSyncに関する情報はネットワーク上に豊富にありません。


私がWebサービスを使用する同期の場合、アクションは次のとおりです。

1. Webサービスは、リクエストへのLDAPパスを受け取ります。
[WebMethod]
public void Synchronize( string DomainPath、 string Filter、 string EntryPath)
{

DirectoryEntry de = new DirectoryEntry(DomainPath);
使用 (SqlConnection conn = 新しい SqlConnection(Globals.ConnectionString))
{
conn.Open();
SqlCommandコマンド= conn.CreateCommand();
command.CommandText = "INSERT INTO SyncTable(スナップショット、OU)VALUES(@ Snapshot、@ OU、@ ExchangeServer)" ;
command.Parameters.AddWithValue( "@Snapshot" 、GetSyncData(de、filter));
command.Parameters.AddWithValue( "@OU" 、EntryPath);

command.ExecuteNonQuery();
conn.Close();
}

}

2. GetSyncDataはAD Cookieを返します。
パブリック バイト [] DirectorySync(DirectoryEntry DomainDE、 文字列フィルター)
{
ADInit.Init();
試してみる
{
使用 (DirectorySearcher srch = 新しい DirectorySearcher(DomainDE、フィルター))
{
srch.SearchScope = SearchScope.Base;
srch.DirectorySynchronization = 新しい DirectorySynchronization();

foreach (srch.FindAll()のSearchResult se)
{
}

MemoryStream ms = 新しい MemoryStream();
BinaryFormatter bFormat = new BinaryFormatter();
bFormat.Serialize(ms、srch.DirectorySynchronization.GetDirectorySynchronizationCookie());
ms.Close();

return ms.GetBuffer();
}
}
catch (例外Ex)
{
Exを投げます。
}
}

DirSynchはツリーのルート要素と連携するため、エントリポイントとしてドメインを使用する必要があります。 フィルターは、OU = myOUまたはそのような形式にすることができます。 私の場合、この機能を単に回避しました。ドメインへのLDAPパスとこのオブジェクトへのLDAPパスの両方を選択できる階層構造を作成しました。 フィルターは、同期するオブジェクトの名前を使用します。

3.逆同期+調整
[WebMethod]
パブリック bool GetRegionEntry( 文字列 Domain、 文字列 Filter、 文字列 EntryPath)
{
DirectoryEntry de = 新しい DirectoryEntry(ドメイン);

RegionInfo _regionInfo = regionEntry.GetEntry();
使用 (SqlConnection conn = 新しい SqlConnection(Globals.ConnectionString))
{
conn.Open();
SqlCommandコマンド= conn.CreateCommand();
command.CommandText = "SELECT * FROM SyncTable WHERE OU = @OU" ;
command.Parameters.AddWithValue( "@OU" 、EntryPath);

SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
return regionEntry.GetSyncDelta(de、Filter、( byte [])reader [ "Snapshot" ]);
}
他に
{
新しい例外をスロー (「データベースから同期Cookie 読み取れません!」);

}
conn.Close();
}
return _regionInfo;
}


ここで、必要に応じて、ブール値を取得するか(違いがあります-違いはありません)、デルタを完全に取得します。
/// public Dictionary <string、object> GetSyncDelta(DirectoryEntry DomainDE、string Filter、byte [] _cookie)

パブリック bool GetSyncDelta(DirectoryEntry DomainDE、 文字列フィルター、 バイト [] _cookie)
{
辞書< 文字列オブジェクト > _delta = 新しい辞書< 文字列オブジェクト >();

BinaryFormatter bf = new BinaryFormatter();
byte [] cookie =( byte [])bf.Deserialize( new MemoryStream(_cookie));

DirectorySynchronization dirSync = 新しい DirectorySynchronization(cookie);
DirectorySearcher srch = 新しい DirectorySearcher(DomainDE、フィルター);
srch.DirectorySynchronization = dirSync;

foreach (srch.FindAll()のSearchResult sr)
{
foreach (sr.Properties.PropertyNamesの文字列 attrName)
{
_delta.Add(attrName、sr.Properties [attrName]);
}
trueを 返し ます
}

falseを 返し ます
// _deltaを返します;
}


辞書< 文字列オブジェクト >は XMLの標準メソッドではシリアル化されません。keyvaluepairで配列を使用するか、シリアル化を書き換えてください)。

4.レコード変更の履歴全体を保存するには、別のテーブルを作成し、それに識別子フィールドを追加して、トリガーをINSERT / UPDATEに設定します。
ALTER TRIGGER [SyncTableTrg]
ON [dbo]。[SyncTable]
INSERTの後、 UPDATE
として
開始
SyncTableLogに挿入(OU、スナップショット)
OUを選択 、スナップショットから挿入
終了


したがって、同期する各レコードに関する良いストーリーを取得できます。 これが唯一の方法ではありませんが。

ご清聴ありがとうございました

PS 厳密に判断しないでください。 以前にブログされていない(最初の経験

Source: https://habr.com/ru/post/J29180/


All Articles