Windows ベースのドメイン コントローラーでの分散リンク追跡

この記事では、Windows の分散リンク追跡サービスを使用して、NTFS 形式のボリュームとサーバー間でのリンク ファイルの作成と移動を追跡する方法について説明します。

適用対象: Windows Server 2012 R2
元の KB 番号: 312403

分散リンク追跡サーバー サービスと分散リンク追跡クライアント サービスを使用して、NTFS 形式のパーティション上のファイルへのリンクを追跡できます。 分散リンク追跡は、シェル ショートカットや OLE リンクなど、NTFS ボリューム上のファイルにリンクが作成されるシナリオでリンクを追跡します。 そのファイルの名前が変更された場合、同じコンピューター上の別のボリュームに移動された場合、別のコンピューターに移動された場合、または他の同様のシナリオで移動された場合、Windows は分散リンク追跡を使用してファイルを検索します。 移動したリンクにアクセスすると、分散リンク追跡によってリンクが検索されます。ファイルが移動されたこと、または移動されたファイルを見つけるために分散リンク追跡が使用されていることに気付かない。

分散リンク追跡は、クライアント サービスとサーバー サービスで構成されます。 分散リンク追跡サーバー サービスは、Windows Server ベースのドメイン コントローラーでのみ実行されます。 Active Directory に情報を格納し、分散リンク追跡クライアント サービスを支援するサービスを提供します。 分散リンク追跡クライアント サービスは、ワークグループ環境のコンピューターやワークグループに属していないコンピューターを含む、すべての Windows 2000 ベースおよび Microsoft Windows XP ベースのコンピューターで実行されます。 これは、分散リンク追跡サーバーとの唯一の相互作用を提供します。

分散リンク追跡クライアントは、分散リンク追跡サーバー サービスに、Active Directory に分散リンク追跡サーバー サービスが格納するファイル リンクに関する情報を提供することがあります。 また、分散リンク追跡クライアントは、シェル ショートカットまたは OLE リンクを解決できない場合に、その情報について分散リンク追跡サーバー サービスに対してクエリを実行することもできます。 分散リンク追跡クライアントは、30 日ごとにリンクを更新するように分散リンク追跡サーバーに求めます。 分散リンク追跡サーバー サービスは、90 日間更新されていないオブジェクトをスキャンします

リンクによって参照されているファイルが別のボリューム (同じコンピューター上または別のコンピューター上) に移動されると、分散リンク追跡クライアントは分散リンク追跡サーバーに通知し、Active Directory に linkTrackOMTEntry オブジェクトを作成します。 linkTrackVolEntry オブジェクトは、ドメイン内のすべての NTFS ボリュームに対して Active Directory に作成されます。

注:

Windows Server 2008 以降では、分散リンク追跡サーバー サービスは Windows に含まれなくなりました。 そのため、Active Directory からオブジェクトを安全に削除できます。

分散リンク追跡オブジェクトは、コンピューター アカウントをホストしているドメイン内のすべてのドメイン コントローラーと、フォレスト内のすべてのグローバル カタログ サーバー間でレプリケートされます。 Distributed Link Tracking Server サービスは、次の識別名パスにオブジェクトを作成します。

CN=FileLinks、CN=System、DC= Active Directory の ドメイン名 コンテナー

分散リンク追跡オブジェクトは、CN=FileLinks、CN=System フォルダーの下の次の 2 つのテーブルに存在します。

  • CN=ObjectMoveTable,CN=FileLinks,CN=System,DC= ドメイン名:

このオブジェクトは、ドメイン内で移動されたリンクされたファイルに関する情報を格納します。

  • CN=VolumeTable,CN=FileLinks,CN=System,DC= ドメイン名:

    このオブジェクトは、ドメイン内の各 NTFS ボリュームに関する情報を格納します。

分散リンク追跡オブジェクトは、個別にはほとんど領域を消費しませんが、時間の経過と同時に蓄積が許可されている場合、Active Directory で大量の領域を消費する可能性があります。

分散リンク追跡を無効にし、Active Directory から分散リンク追跡オブジェクトを削除すると、次の動作が発生する可能性があります。

  • Active Directory データベースのサイズが小さくなる可能性があります (この動作は、オブジェクトが廃棄され、ガベージ コレクションされた後、およびオフラインの最適化手順を実行した後に発生します)。
  • ドメイン コントローラー間のレプリケーション トラフィックが減少する可能性があります。

Windows 2000、Windows XP、および Windows Server 2003 では、分散リンク追跡クライアント サービスの開始値が [自動] に設定されています。 Windows 2000 ベースのサーバーでは、分散リンク追跡サーバー サービスは既定で手動で開始されます。 ただし、Dcpromo.exe を使用してサーバーをドメインに昇格させる場合、分散リンク追跡サーバー サービスは自動的に開始するように構成されます。

Windows Server 2003 ベースのサーバーの場合、分散リンク追跡サーバー サービスは既定で無効になっています。 Dcpromo.exe を使用してサーバーをドメインに昇格させる場合、分散リンク追跡サーバー サービスは自動的に開始するように構成されていません。 Windows 2000 ベースのドメイン コントローラーを Windows Server 2003 にアップグレードすると、アップグレード中に分散リンク追跡サーバー サービスも無効になります。 管理者が分散リンク追跡サーバー サービスを使用する場合は、グループ ポリシーを使用するか、サービスを手動で自動的に開始するように設定する必要があります。 さらに、Windows Server 2003 または Windows XP SP1 を実行しているコンピューター上の分散リンク追跡クライアント サービスは、既定では分散リンク追跡サーバー サービスの使用を試みません。 分散リンク追跡サーバー サービスを利用するようにこれらのコンピューターを構成する場合は、[分散リンク追跡クライアントによるドメイン リソースの使用を許可する] ポリシー設定を有効にします。 これを行うには、グループ ポリシーで [コンピューターの構成]、[管理用テンプレート]、[システム] ノードを開きます。

Microsoft では、Windows 2000 ベースのサーバーで分散リンク追跡で次の設定を使用することをお勧めします。

  1. すべてのドメイン コントローラーで分散リンク追跡サーバー サービスをオフにします (これは、すべての Windows Server 2003 ベースのサーバーの既定の構成です)。

    レプリケーションのオーバーヘッドと、Active Directory で FileLinks テーブルが使用する領域のため、Active Directory ドメイン コントローラーで分散リンク追跡サーバー サービスをオフにすることをお勧めします。 サービスを停止するには、次のいずれかの方法を使用します。

    • [サービス] スナップイン (Services.msc または compmgmt.msc) で、分散リンク追跡サーバー サービスをダブルクリックし、[スタートアップの種類] ボックスで [無効] をクリックします。

    • グループ ポリシーの [コンピューターの構成]、[Windows の設定]、[System Services] ノードの [スタートアップ] の値を定義します。

    • すべての Windows 2000 ドメイン コントローラーをホストする組織単位でポリシー設定を定義します。

    ポリシーがレプリケートされたら、ドメイン コントローラーを再起動して、ポリシーが適用されるようにします。 ドメイン コントローラーを再起動しない場合は、各ドメイン コントローラーでサービスを手動で停止する必要があります。

  2. Active Directory ドメイン コントローラーから分散リンク追跡オブジェクトを削除します。

    分散リンク追跡オブジェクトを削除する方法の詳細については、この記事の「分散リンク追跡オブジェクトを削除する方法」セクションを参照してください。 分散リンク追跡サーバー サービスを無効にした後、オブジェクトを削除することをお勧めします。

    注:

    ドメイン コントローラーのディレクトリ情報ツリー (DIT) のサイズは、次のアクションが完了するまで縮小されません。

    1. オブジェクトはディレクトリ サービスから削除されます。

      注:

      削除されたオブジェクトは、廃棄ストーンの有効期間が切れるまで、削除済みオブジェクト コンテナーに格納されます。 廃棄石の有効期間の既定値は 60 日です。 最小値は 2 日間です。 既定では、Windows Server 2003 Service Pack 1 以降のバージョンの Windows Server 2003 と共にインストールされる新しいフォレストの場合、値は 180 日です。

      強力な Active Directory レプリケーション監視がない限り、180 日間の値を使用することをお勧めします。 DIT サイズの問題を処理するには、この値を小さくしないでください。 データベース サイズに問題がある場合は、Microsoft カスタマー サポート サービスにお問い合わせください。

    2. ガベージ コレクションは完了まで実行されました。

    3. Ntdsutil.exe を使用して、Dsrepair モードで Ntds.dit ファイルを最適化します。

分散リンク追跡サーバー サービスを停止した後、これらのオブジェクトで使用されているディスク領域をできるだけ早く解放する必要がない限り、分散リンク追跡オブジェクトを手動で削除することは重要ではありません。 分散リンク追跡クライアントは、30 日ごとにリンクを更新するように分散リンク追跡サーバーに求めます。 Distributed Link Tracking Server サービスは、90 日間更新されていないオブジェクトをスキャンします。

Dltpurge.vbs VBScript を実行すると、分散リンク追跡サーバー サービスによって使用されるすべての Active Directory オブジェクトが、スクリプトが実行されているドメインから削除されます。 フォレスト内のドメインごとに 1 つのドメイン コントローラーでスクリプトを実行する必要があります。 Dltpurge.vbs を実行するには:

  1. Microsoft 製品サポートから Dltpurge.vbs スクリプトを取得します。

  2. Dltpurge.vbs の対象となるドメイン内のすべてのドメイン コントローラーで、分散リンク追跡サーバー サービスを停止します。

  3. 管理者特権を使用して、Dltpurge.vbs の対象となるドメイン コントローラーまたはドメイン内のメンバー コンピューターのコンソールにログオンします。

  4. コマンド ラインから Dltpurge.vbs を実行するには、次の構文を使用します。

    cscript dltpurge.vbs -s myserver -d dc=mydomain,dc=mycompany,dc=com  
    

    このコマンド ラインでは、次の操作を行います。

    • -s は、分散リンク追跡オブジェクトを削除するドメイン コントローラーの DNS ホスト名です。
    • -d は、分散リンク追跡オブジェクトを削除するドメインの識別名パスです。
  5. オブジェクトが廃棄され、ガベージ コレクションされた後に、Ntds.dit ファイルのオフライン最適化手順を実行します。 ガベージ コレクション プロセスの詳細については、次の記事番号をクリックして、Microsoft サポート技術情報の記事を表示します。

    198793 Active Directory データベースのガベージ コレクション プロセス

カスタマー エクスペリエンスのサンプル

このセクションで説明する最悪のシナリオでは、大規模な運用ドメイン内の多数の分散リンク追跡オブジェクトを削除するときに考慮すべきいくつかの問題を示します。

世界中で 40,000 人を超える従業員を持つ架空の Fortune 500 のお客様である Trey Research は、世界の主要な地理的リージョン (北米、アジア、ヨーロッパなど) をマップする子ドメインを持つ空のルート ドメインで構成される単一の Active Directory フォレストを展開します。 フォレスト内の最大のドメインには、約 35,000 のユーザー アカウントと同じ数のコンピューター アカウントが含まれています。

Ntds.dit ファイルは、18 ギガバイト (GB) の raid アレイに配置されました。 Windows 2000 の初期展開以降、グローバル カタログ ファイルは 17 GB に増加しました。

Trey Research は、今後 10 日以内に Windows Server 2003 を展開したいと考えていますが、アップグレードを開始する前に、データベース パーティションに少なくとも 1.5 GB の空きディスク領域が必要です。 Adprep.exe は、以前にインストールされた修正プログラムとサービス パックに応じて 3 から 5 個の継承された ace を追加することが知られているため、この多くのディスク領域が必要です。 次の条件は、大きなグローバル カタログ サイズまたはディスク領域の不足に影響します。

  • 条件 1: Trey Research は Windows 2000 の初期導入者であり、好みのハードウェア ベンダーから受け取った最大のドライブは、RAID アレイで構成されたときに 9 GB または 18 GB でした。 現在のドライブは、コストの半分の 2 倍のサイズです。

  • 条件 2: フォレスト内の各ドメインに委任された Active Directory 統合 DNS ゾーンで DNS 清掃が有効になっていませんでした。

  • 条件 3: ドメイン ユーザーがドメインにコンピューター アカウントを作成することを許可されました。 管理者は、孤立したコンピューター アカウントを特定して削除するための定期的なプロセスを持っていませんでした。

  • 条件 4: しばらくの間、セキュリティ記述子は、ルート名前付けコンテキスト (NC) ヘッド (cn=schema、cn=configuration、cn= domain) および Active Directory で何千ものオブジェクトをホストするその他のコンテナーで管理者、サービス パック、修正プログラムによって定義されました。 さらに、同じパーティションで監査が有効になりました。 Active Directory でアクセス許可を設定し、オブジェクトの監査を有効にすると、データベースのサイズが大きくなります。 Windows Server 2003 ベースのドメイン コントローラー (Adprep) 用に Windows 2000 フォレストとドメインを準備するツールでは、継承された ace も追加されます。そのため、Trey Research は、ドメインをアップグレードする前にディスク ドライブの空き領域を解放する必要があります。

  • 条件 5: Trey Research は、Dsrepair モードで Ntds.dit ファイルのオフラインデフラグ手順を定期的に実行しませんでした。

  • 条件 6: 最大ドメインの CN=FileLinks、CN=System、DC= ドメイン名 コンテナーがレビューされると、700,000 を超える分散リンク追跡オブジェクトが表示されました。 各 Distributed Link Tracking オブジェクトのセキュリティ記述子は、約 2 KB (KB) でした。 これらの各条件は、17 GB の .dit ファイルへの貢献について評価されました。

  • 条件 1: Trey Research は、コストとそれにかかる時間のために、新しいドライブをデプロイしないことを決定しました。 また、Windows Server 2003 にアップグレードした後、単一インスタンス ストア (SIS) プロセスが完了した後に Active Directory データベースが縮小されることが予想されたため、ディスク領域が一時的にのみ必要でした (SIS は Active Directory データベースにアクセス許可のより効率的なストレージを実装します)。

  • 条件 2 と 3: Trey Research は、これらの条件がベスト プラクティスであると判断しました。しかし、Trey Research が実装したとしても、必要な結果は得られないでしょう。 DNS の清掃は簡単に実装できるため、有効にすることにしました。

  • 条件 4: Trey Research では、セキュリティ記述子とシステム アクセス制御リスト (SACL) を再定義すると、目的の結果が得られると認識されましたが、この手順は、サイズの削減、レプリケーションのオーバーヘッド、最も重要な運用環境を反映するラボ シナリオでのプログラム/管理の互換性を徹底的にテストできるようになるまで、実装に時間がかかると判断しました。

    Trey Research では Windows 2000 SP2 といくつかの修正プログラムが展開されているため、Adprep によって (NC ドメイン内のオブジェクトに) 追加された増分継承 ace は、300 MB (MB) ほど小さいと予想されていました。 運用フォレストのアップグレードをテストするために使用されるラボ環境で、この動作を確認できます。

  • 条件 5: Trey Research は、オフラインの最適化手順を実行した場合、Ntds.dit ファイル内の "空白" を回復できない可能性があることを認識しました。 実際、Trey Research の管理者は、オフラインの最適化手順を完了した直後にデータベース サイズの増加に気付きました。 この動作は、Windows 2000 データベース エンジンの非効率性が原因で発生しました。このエンジンは Windows Server 2003 で強化されています。

  • 条件 6: Trey Research は、フォレスト内の各ドメイン内のドメイン コントローラー上の CN=FileLinks、CN=System、DC= ドメイン名 コンテナーから、すべての分散リンク追跡オブジェクトの単純な一括削除を実行することが明らかな対処方法であると合意しました。 しかし、その場合、オブジェクトが廃棄されてガベージ コレクションされるまで、およびドメイン内の各ドメイン コントローラーでオフラインの最適化手順が完了するまで、追加のディスク領域が解放されないことに気付きました。 廃棄石の有効期間の値は 2 日という低い値に設定できますが、Trey Research フォレスト内のいくつかのドメイン コントローラーは、ハードウェアとソフトウェアの更新プログラムを待機しているときにオフラインでした。 エンド ツー エンド レプリケーションが実行される前にオブジェクトが廃棄されている場合、削除されたオブジェクトは再アニメーション化されるか、フォレスト内のグローバル カタログ サーバー間で一貫性のないデータが報告される可能性があります。 すぐに救済するために、トレイ・リサーチは次の手順を実行しました。

  1. 分散リンク追跡スキーマ クラス オブジェクトの既定のセキュリティ記述子を削除し、単一のセキュリティ プリンシパル (ユーザー アカウント) に置き換えます。
  2. 既存のすべてのセキュリティ記述子を削除し、単一のセキュリティ プリンシパルの明示的な ace に置き換える VBScript プログラムを作成しました。
  3. 分散リンク追跡オブジェクトは、10,000 単位の増分で削除され、各オブジェクト削除の間に 3 時間の遅延が発生しました。
  4. すべての分散リンク追跡オブジェクトが削除された後、ドメイン内の各ドメイン コントローラーでオフライン最適化手順を実行しました。 Trey Research が記述子を削除し、最適化手順を実行すると、データベースはドメイン内のすべてのドメイン コントローラーで約 1.5 GB のディスク領域を回復しました。 この領域は、Adprep ツールを快適に実行し、すべての Windows 2000 ベースのドメイン コントローラーとグローバル カタログを Windows Server 2003 にアップグレードするのに十分でした。

Trey Research がオペレーティング システムを Windows Server 2003 にアップグレードした後、Windows Server 2003 の単一インスタンス ストア機能によってデータベース サイズが約 8 GB に縮小されたときに、より多くのディスク領域が解放されました (これらの結果を取得するには、オフラインの最適化手順を実行する必要があります)。 TSL 間隔の有効期限が切れた後に、より多くの領域が回復され、分散リンク追跡オブジェクトがガベージ コレクションされ、オフラインの最適化手順が実行されました。

Trey Research は、新しいレプリカ Windows 2000 ベースのドメイン コントローラーをドメインに昇格させ、コンピューター アカウントを通常使用される組織単位とは異なる組織単位に配置しました。 2 日間で、Windows 2000 ベースのドメイン コントローラーには、約 8,000 個の分散リンク追跡オブジェクトが存在しました。 Trey Research は、分散リンク追跡を停止したか、サービスを停止するポリシーを作成した後、Windows 2000 ベースのドメイン コントローラーをホストする組織単位にポリシーをリンクしました。 最後に、Trey Research は Dltpurge.vbs を使用して、残りの分散リンク追跡オブジェクトを削除対象としてマークしました。

DLT オブジェクトの削除の構造

DLT オブジェクト自体に含まれる属性は少なく、Active Directory では領域がほとんど使用されません。 オブジェクトが削除対象としてマークされている場合 (廃棄)、Active Directory から削除されるまでオブジェクトを追跡するために必要な属性を除き、すべての不要な属性が削除されます。

リンク追跡オブジェクトの場合、削除対象としてオブジェクトをマークすると、削除される属性は dscorepropagationdata と objectcategory の 2 つの属性に限定されます。 2 つの属性を削除すると、最初に 34 バイトが節約されます。 ただし、リンク追跡オブジェクトを削除対象としてマークするプロセスでは、IS_DELETED属性 (4 バイト) を追加し、RDN 属性と "共通名" 属性をマングルすることで、オブジェクトも更新され、これらの各属性は約 80 バイト増加します。 さらに、"レプリケーション メタデータ" 属性も約 50 バイト増加し、このオブジェクトに対して実行された更新を反映します。 そのため、リンク追跡オブジェクトに削除のマークを付けることで、オブジェクトは約 200 バイト増加します。 NTDS。DIT では、削除されたオブジェクトが廃棄され、ガベージ コレクションされ、オフラインデフラグが実行されるまで、サイズは縮小されません。

注:

この記事で推奨されているようにサービスがオフになっている場合、自動クリーンアップは行われません。

Dltpurge.vbs のテキスト バージョン

このスクリプトを使用するには:

  1. この記事の [コピーの開始] <タグと [ここで>最後にコピー>] <タグの間にあるすべてのテキストをコピーし、テキストを ASCII テキスト エディター ファイル (Microsoft メモ帳ファイルなど) に貼り付けます。
  2. ファイルを "Dltpurge.vbs" として保存します。 3「分散リンク追跡オブジェクトを削除する方法」で説明されている手順を完了します
<Start Copy Here>
'==============================================================================
'==============================================================================
'
' Copyright (C) 2001 by Microsoft Corporation.  All rights reserved.
'
' This script deletes all Active Directory objects used by the
' Distributed Link Tracking Server service.
'
' It is assumed that the DLT Server service has been disabled,
' and you wish to recover the DIT space these objects occupy.
'
' Usage:   cscript DltPurge.vbs <options>
' Options: -s ServerName
'          -d distinguishedname dc=mydomain,dc=mycompany,dc=com
'          -b BatchSize  BatchDelayMinutes
'          -t (optional test mode)
'
' The objects are deleted in batches - BatchSize objects are deleted,
' then there is a BatchDelayMinutes delay before the next batch.
'
'==============================================================================
'==============================================================================

Option Explicit

'
' Globals, also local to main.
'
Dim oProvider
Dim oTarget
Dim sServer
Dim sDomain
Dim bTest

Dim BatchSize
Dim BatchDelayMinutes

'
' Set defaults
'

BatchSize = 1000
BatchDelayMinutes = 15
bTest = False

'==============================================================================
'
'   ProcessArgs
'
'   Parse the command-line arguments.  Results are set in global variables
'   (oProvider, oTarget, sServer, sDomain, BatchSize, and BatchDelayMinutes).
'
'==============================================================================


public function ProcessArgs

    Dim iCount
    Dim oArgs

    on error resume next

    '
    ' Get the command-line arguments
    '
    
    Set oArgs = WScript.Arguments

    if oArgs.Count > 0 then

        '
        ' We have command-line arguments.  Loop through them.
        '

        iCount = 0
        ProcessArgs = 0

        do while iCount < oArgs.Count

            select case oArgs.Item(iCount)

                '
                ' Server name argument
                '
                
                case "-s"

                    if( iCount + 1 >= oArgs.Count ) then
                        Syntax
                        ProcessArgs = -1
                        exit do
                    end if

                    sServer = oArgs.Item(iCount+1)
                    if Len(sServer) > 0 then sServer = sServer & "/"
                    iCount = iCount + 2

                '
                ' Enable testing option
                '
                
                case "-t"

                    iCount = iCount + 1
                    bTest  = True

                '
                ' Domain name option
                '
                
                case "-d"

                    if( iCount + 1 >= oArgs.Count ) then
                        Syntax
                        ProcessArgs = -1
                        Exit Do
                    end if

                    sDomain = oArgs.Item(iCount+1)
                    iCount = iCount + 2

                '
                ' Batching option (batch size, batch delay)
                '

                case "-b"

                    if( iCount + 2 >= oArgs.Count ) then
                        Syntax
                        ProcessArgs = -1
                        exit do
                    end if

                    Err.Clear
                    
                    BatchSize = CInt( oArgs.Item(iCount+1) )
                    BatchDelayMinutes = CInt( oArgs.Item(iCount+2) )
                    
                    if( Err.Number <> 0 ) then 
                        wscript.echo "Invalid value for -b argument" & vbCrLf
                        Syntax
                        ProcessArgs = -1
                        exit do
                    end if
                    
                    iCount = iCount + 3

                '
                ' Help option
                '
                
                case "-?"
                    Syntax
                    ProcessArgs = -1
                    exit do

                '
                ' Invalid argument
                '
                
                case else
                
                    ' Display the syntax and return an error

                    wscript.echo "Unknown argument: " & oArgs.Item(iCount) & vbCrLf
                    Syntax
                    ProcessArgs = -1
                    Exit Do
                    
            end select
      loop

    else
    
        '
        ' There were no command-line arguments, display the syntax
        ' and return an error.
        '

        Syntax
        ProcessArgs = -1

    end if

    Set oArgs = Nothing

end function ' ProcessArgs

'==============================================================================
'
'   Syntax
'
'   Show the command-line syntax
'
'==============================================================================

public function Syntax

    wscript.echo    vbCrLf & _
                    "Purpose:   Delete Active Directory objects from Distributed Link Tracking" & vbCrLf & _
                    "           Server service (Assumes that DLT Server has been disabled" & vbCrLf & _
                    "           on all DCs)" & vbCrLf & _
                    vbCrLf & _
                    "Usage:     " & wscript.scriptname & " <arguments>" & vbCrLf & _
                    vbCrLf & _
                    "Arguments: -s Server" & vbCrLf & _
                    "           -d FullyQualifiedDomain" & vbCrLf & _
                    "           -b BatchSize BatchDelayMinutes (default to 1000 and 15)" & vbCrLf & _
                    "           -t (optional test mode, nothing is deleted)" & vbCrLf & _
                    vbCrLf & _
                    "Note:      Objects are deleted in batches, with a delay between each" & vbCrLf & _
                    "           batch.  The size of the batch defaults to 1000 objects, and" & vbCrLf & _
                    "           the length of the delay defaults to 15 minutes.  But these" & vbCrLf & _
                    "           values can be overridden using the -b option." & vbCrLf & _
                    vbCrLf & _
                    "Example:   " & wscript.scriptname & "  -s  myserver  -d distinguishedname dc=mydomain,dc=mycompany,dc=com "

end function    ' Syntax



'==============================================================================
'
'   PurgeContainer
'
'   Delete all objects of the specified class in the specified container.
'   This subroutine is called once for the volume table and once for
'   the object move table.
'
'==============================================================================

sub PurgeContainer(ByRef oParent, ByVal strClass)

    dim oChild
    dim iBatch
    dim iTotal

    On Error Resume Next

    iTotal = 0
    iBatch = 0

    ' Loop through the children of this container

    For Each oChild in oParent

        ' 
        ' Is this a DLT object?
        '

        
        if oChild.Class = strClass Then

            '
            ' Yes, this is a DLT object, it may be deleted
            '
            
            iTotal = iTotal + 1
            iBatch = iBatch + 1

            '
            ' Delete the object
            '
            
            if bTest then
                wscript.echo "Object that would be deleted: " & oChild.adspath
            else
                oParent.Delete oChild.Class, oChild.Name
            end if

            '
            ' If this is the end of a batch, delay to let replication
            ' catch up.
            '
            
            if iBatch = BatchSize then
            
                iBatch = 0
                
                wscript.stdout.writeline "" ' ignored by wscript
                wscript.echo "Deleted " & BatchSize & " objects"
                wscript.echo "Pausing to allow processing (will restart at " & DateAdd("n", BatchDelayMinutes, Time) & ")"
                
                wscript.sleep BatchDelayMinutes * 60 * 1000
                wscript.echo "Continuing ..."
                
            end if
            
        else
        
            ' oChild.Class didn't match strClass
            wscript.echo "Ignoring unexpected class: " & oChild.Class
            
        end if

        oChild = NULL

    Next


    wscript.echo "Deleted a total of " & iTotal & " objects"

end sub ' PurgeContainer


'==============================================================================
'
' Main
'
'==============================================================================

if (ProcessArgs=-1) then wscript.quit

on error resume next

'
' Explain what's about to happen
'

wscript.stdout.writeline "" ' ignored by wscript
wscript.echo "This script will purge all objects from the Active Directory" & vbCrLf & _
             "used by the Distributed Link Tracking Server service (trksvr)." & vbCrLf & _
             "It is assumed that this service has already been disabled on" & vbCrLf & _
             "all DCs in the domain."

'
' When running in cscript, pause to give an opportunity to break out
' (These 3 lines are for cscript and ignored by wscript.)
'

wscript.stdout.writeline ""
wscript.stdout.writeline "Press Enter to continue ..."
wscript.stdin.readline

'
' Get an ADSI object
'

Set oProvider = GetObject("LDAP:")

'
' Purge the System/FileLinks/ObjectMoveTable
'

wscript.stdout.writeline "" ' ignored by wscript
wscript.echo "Purging ObjectMoveTable"

Set oTarget = oProvider.OpenDSObject( "LDAP://" & sServer  & "cn=ObjectMoveTable,CN=FileLinks,CN=System," & sDomain ,_
                                      vbNullString, vbNullString, _
                                      1) ' ADS_SECURE_AUTHENTICATION

call PurgeContainer( oTarget, "linkTrackOMTEntry" )
oTarget = NULL

'
' Purge the System/FileLinks/VolumeTable
'

wscript.stdout.writeline "" ' ignored by wscript
wscript.echo "Purging VolumeTable"

Set oTarget = oProvider.OpenDSObject("LDAP://" & sServer  & "cn=VolumeTable,CN=FileLinks,CN=System," & sDomain  ,_
                                     vbNullString, vbNullString, _
                                     1) ' ADS_SECURE_AUTHENTICATION
call PurgeContainer( oTarget, "linkTrackVolEntry" )
oTarget = NULL

oProvider = NULL
<END Copy Here>