將過期的全域編錄伺服器重新上線之後,遺留物件可能會保留下來
本文說明在您讓離線DC重新上線之後,清除重新導入AD之物件的程式。
適用於: Windows Server 2019、Windows Server 2016、Windows Server 2012 R2
原始 KB 編號: 314282
徵狀
將域控制器 (DC) 或全域編錄伺服器離線一段時間之後,即可上線。 上線之後,您會觀察下列一或多個問題:
- 電子郵件訊息不會傳遞給用戶,用戶物件已在網域之間移動。 將過期的 DC 或全域編錄伺服器重新上線之後,用戶物件的兩個實例都會出現在全域目錄中。 這兩個物件都有相同的電子郵件位址,因此無法傳遞電子郵件訊息。
- 不再存在的用戶帳戶仍會出現在全域通訊清單中。
- 不再存在的通用群組仍會出現在使用者的存取令牌中。
- 其他 DC 或全域編錄伺服器會記錄事件,例如 EventID 1084, 伺服器上沒有這類物件。 受影響的DC或全域編錄伺服器上會封鎖進一步複寫。
原因
如果 DC 或全域編錄伺服器的離線時間超過用戶物件的 Tombstone-Lifetime 屬性值,就可能發生這些問題。
如需 Tombstone-Lifetime 屬性的 詳細資訊,請參閱 Tombstone-Lifetime 屬性。
Tombstone-Lifetime 屬性會定義從目錄服務移除已刪除物件之前的天數。 這有助於從復寫的伺服器移除物件,並防止還原重新導入已刪除的物件。 預設值是 180 天。 之後,Active Directory 就不再需要記住變更。
如果 DC 或全域編錄伺服器離線的時間超過 Tombstone-Lifetime 屬性的值,則其 Active Directory (複本或全域編錄) 可能包含已在其他 DC 上刪除的物件。 不過,其他 DC 不再記得已刪除物件。 當您讓離線 DC 上線時,它會將其 Active Directory 複本與網域的其餘部分進行同步處理。 由於已捨棄刪除的相關信息,因此 DC 會將受影響的對象復寫 (稱為回溯物件,) 回網域的其餘部分。
一般而言,AD DS 會使用 鬆散一致性複寫模型,其中某些命名內容 (也稱為目錄分割) 是讀取/寫入,而其他則是只讀的。 當 DC 接收屬於讀取/寫入命名內容的複寫物件,且該物件尚未存在於目錄資訊樹狀結構 (DIT) 的本地副本中時,DC 會建立 物件。 隨著復寫程式的繼續,物件會重新出現在網域中的所有DC上。
DC 和全域編錄伺服器也可以使用嚴格的複寫一致性模型。 在此模型下,當 DC 收到本機 DIT 中尚未存在的復寫物件時,DC 會停止接收或傳送複寫的數據,並記錄事件識別碼 1084 等事件:「伺服器上沒有這類物件」。如需嚴格復寫一致性的詳細資訊,包括 DC 預設可能會使用此模型的情況,請參閱 KB 910205、有關在 Windows Server Active Directory 樹系中保留物件的資訊。 如需標記問題的詳細資訊, 請參閱 KB216993 Active Directory 系統狀態備份的實用貨架存留期。
解決方法 1:判斷 Active Directory 是否有遺留物件,並避免未來遺留物件
KB 910205說明數種方式,用來判斷您的 Active Directory 系統是否累積了不斷的物件。 KB 910205也會說明您可以採取的步驟,以防止物件累加。
解決方法 2:刪除遺留物件
例如,如果物件不應該存在於 Active Directory 中 (,如果物件是由過時的域控制器) 重新導入,您可以使用 ADSIEdit 等標準 (工具或 Active Directory 使用者和電腦 嵌入式管理單元) 來刪除物件。
您可以輕鬆地移除讀取/寫入命名內容的遺留物件。 在 Windows Server 2003 和更新版本中,您可以使用 命令 repadmin /removelingeringobjects
來移除遺留物件。 如需如何使用 RepAdmin 的資訊,請參閱 Active Directory 複寫事件標識碼 1388 或 1988:偵測到遺留的物件。
本文說明如何移除已經出現在只讀命名內容中的遺留物件,例如全域編錄伺服器上的目錄分割區,或 Read-Only 域控制器 (RODC) 。 「 詳細資訊 」一節中所討論的功能仍存在於較新的操作系統中,而且可能仍然有助於針對非預期的 RepAdmin 行為進行疑難解答。
其他相關資訊
此程式需要DC的 objectGUID ,該DC具有物件的讀取/寫入複本,以及物件本身的 objectGUID 。 如果您必須移除一個以上的物件,請判斷是否有任何物件在父/子關聯性中 (您可以從對象的辨別名稱判斷) 。 如果是這種情況,請排序刪除,以便在其父物件之前刪除所有子物件。
此程式有三個主要步驟,您必須在可存取樹系 (的計算機上執行,而且您必須使用具有樹系) 系統管理許可權的用戶帳戶:
- 取得遺留對象的辨別名稱和 ObjectGUID。
- 識別物件網域中的DC。
- 刪除停留物件。 選取下列其中一個方法:
- 刪除一些拖動物件。
- 刪除大量遺留物件。
重要事項
您要執行刪除作業的每個全域編錄伺服器 (步驟 3) 必須具有與您在步驟 2) (識別的域控制器的網路連線。
如需疑難解答資訊,請參閱下列各節:
- 執行Walkservers.cmd修改環境中許多遺留物件時的錯誤訊息。
- 拿掉環境中的遺留物件時的錯誤訊息 87。
取得遺留對象的辨別名稱和 ObjectGUID
識別物件所在的網域 (以及從中判斷具有物件讀取/寫入複本之 DC 名稱的最佳方式) 是擷取物件的辨別名稱。 您可以使用 Ldp.exe 工具來搜尋物件名稱 (或部分名稱) 。 如果要執行這項操作,請依照下列步驟執行:
開始 Ldp.exe。
在大部分的 Windows 版本中,選取 [開始>執行 ],然後輸入 ldp.exe。 在 Windows Server 2003 SP1 等舊版 Windows () 此工具可作為其中一個支援工具。
選取 [連線]> [連接]。 在 [ 伺服器] 方塊中,輸入全域編錄伺服器的名稱。 在 [ 埠] 方 塊中輸入 3268,然後選取 [ 確定]。
選取 [連線>系結]。 如果您目前的認證不足以查詢所有全域編錄內容,請輸入有效的認證。 選取 [確定]。
選 取 [檢視>樹狀結構]。 輸入樹系根目錄的辨別名稱,然後選取 [ 確定]。
在樹狀目錄清單中,以滑鼠右鍵按下樹系根目錄,然後選取 [ 搜尋]。
在 [篩選] 方塊中,輸入使用 屬性 = <值>格式的<>篩選條件。
在篩選文字中,<屬性>代表要搜尋的物件屬性,而< value> 則代表您要搜尋的準則。 您可以使用*****做為值中的通配符,而且可以使用表達式。
如需輕量型目錄存取通訊協定 (LDAP) 篩選語法的相關信息,請 參閱搜尋篩選語法。
例如,若要尋找 sAMAccountName 屬性具有 testuser 值的物件,請在 [篩選] 方塊中輸入 (sAMAccountName = testuser) 。 若要搜尋用戶物件,下列屬性最有用:
- 快遞 之 家
- userPrincipalName
- sAMAccountName
- name
- 錫
若要搜尋群組物件,下列屬性最有用:
- 快遞 之 家
- sAMAccountName
- name
在 [範圍] 底下,選取 [子樹狀目錄]。
選取 [ 屬性] 方塊,然後選取屬性字串的結尾。 類型 ;位於 字串結尾的 objectGUID。
在某些版本的[布德文] 中,您必須選取 [ 選項 ] 以查看 [ 屬性] 方 塊。
若要執行查詢,請選取 [ 執行]。
結果會出現在主要的 [卡達文] 視窗中。
判斷應該從全域目錄中移除結果中列出的物件,如果有的話。 您發現不正確的物件之一,就是物件不存在於命名內容的讀取/寫入複本上。
如果您要尋找的物件未包含在查詢結果中,請重新重設篩選條件,然後再次執行搜尋。
如果您已識別出停留物件,請記下其 DN 和 objectGUID 屬性的值。 您稍後將需要這些值。
識別物件網域中的DC
物件的 DN 屬性值包含 物件的網域。 當您知道網域時,可以識別網域內的DC或全域編錄伺服器。 若要執行這項操作,請依照下列步驟執行。
檢查 DN 值的 dc= 部分。 合併 dc= 部分以取得功能變數名稱。
例如,如果物件的 DN 值為 cn=FirstName LastName,cn=Users,dc=name1,dc=name2,dc=com,則對象位於網域中
name1.name2.com
。若要在此網域中尋找DC (或全域編錄伺服器) ,請開啟 Active Directory 使用者和電腦、開啟網域容器,然後開啟域控制器容器。
開啟提升權限的指令提示字元視窗,然後輸入
repadmin /showreps dc-name
。注意事項
在此命令中, dc-name 代表您在步驟 2 中識別的 DC 計算機名稱。
在 Windows Server 2003 SP1) 等舊版 Windows (中,RepAdmin 是其中一個支援工具。
Repadmin 會產生類似下列的結果:
Default-First-Site-Name\WS2016-DC-01 DSA 選項:IS_GC網站選項: (無) DSA 物件 GUID: <GUID> DSA invocationID: <invocationID>
請注意 DSA 物件 GUID 的值。 這是 DC 的 objectGUID 值。
刪除遺留物件
使用下列方法來刪除遺留物件。
從一些全域編錄伺服器刪除一些拖著不動的物件
如果您只有少數物件和全域編錄,請遵循下列步驟,使用 Ldp.exe 刪除物件:
使用企業系統管理員認證來登入每個包含遺留物件複本的全域編錄伺服器。
啟動 Ldp.exe 並連線到本機域控制器上的埠 389 (讓 [伺服器 ] 方塊保留空白) 。
選取 [連線>系結]。 以企業系統管理員) 身分登入 (,將所有方塊保留空白。
選 取 [流覽修改>]。
在 [ 修改 ] 對話框中設定下列專案:
將 [Dn] 方塊 保留空白。
在 [ 屬性] 方塊 中,輸入 RemoveLingeringObject。
在 [ 值] 方塊中,輸入使用下列格式的值:
<GUID=dcGUID>: <GUID=objectGUID>
在此值中, dcGUID 代表您在本節步驟 2 中識別的 DC GUID,而 objectGUID 則代表您在本節步驟 1 中識別之遺留物件的 GUID。
值應該如下所示:
<GUID=<GUID>>: <GUID=<GUID>>
重要事項
在 值中,請勿省略冒號前後的空格。
選取 [作業>取代],然後選取 Enter。
[ 項目清單] 方塊會顯示完整的命令。
選取 [執行]。
結果會出現在主要的 [卡索引] 視窗中,而且應該如下所示。
通話修改...ldap_modify_s (ld, ' (null) ',[1] attrs) ;已修改 ”
從數部全域編錄伺服器刪除大量遺留物件
如果您必須刪除大量的遺留物件,則可以使用腳本比手動刪除這些物件更有效率地刪除這些物件。 若要建置這類腳本,請使用下列步驟:
建立新資料夾,然後在該資料夾中建立具有下列名稱的新檔案:
- Walkservers.cmd
- Walkobjects.cmd
- Modifyrootdse.vbs
- Server-list.txt
- Object-list.txt 檔案
將下列文字貼入Walkservers.cmd:
for /f %%j in (server-list.txt) do walkobjects %%j
將下列文字貼入Walkobjects.cmd:
for /f "delims=@" %%i in (object-list.txt) do cscript //NoLogo MODIFYROOTDSE.VBS %1 "%%i" >>update-%1.log
將下列文字貼入 Modifyrootdse.vbs:
'******************************************************************** '* '* File: MODIFYROOTDSE.VBS '* Created: January 2002 '* Version: 1.0 '* '* Main Function: Writes Active Directory information to clean up '* objects as per: Q314282. '* Usage: Modifyrootdse.vbs <TargetServer> <GUID PAIR> '* Parameter are fed into the script using a pair of batch files. '* '* Copyright (C) 2002 Microsoft Corporation '* '******************************************************************** OPTION EXPLICIT ON ERROR RESUME NEXT Dim objDomain Dim ObjValue, strServerName, adsLdapPath Dim i 'Get the command-line arguments if Wscript.arguments.count <> 2 Then Print "Invalid Number of Parameters. Use with WalkServers.CMD and WalkObjects.CMD" WScript.quit End If strServerName = Wscript.arguments.item(0) ObjValue = Wscript.arguments.item(1) adsLdapPath = "LDAP://" & strServerName & "/RootDSE" Set objDomain = GetObject(adsLdapPath) If Err.Number <> 0 Then WScript.Echo "Error opening ROOTDSE. Error number is: " & Err.Number & ". Error description is: " & Err.Description & "." Set objDomain = Nothing WScript.quit End If objDomain.Put "RemoveLingeringObject", ObjValue objDomain.Setinfo If Err.Number = 0 Then WScript.Echo "Object " & ObjValue & " was removed." Else WScript.Echo "Object " & ObjValue & " could not be removed. Error number is: " & Err.Number & ". Error description is: " & Err.Description & "." End If WScript.Quit
注意事項
如果您手動啟動 Modifyrootdse.vbs,請務必以引弧括住任何包含空格的參數。
建立包含遺留物件之全域編錄伺服器和DC的所有完整域名清單,然後將清單貼到 Server-list.txt 中。 使用完整域名來避免 DNS 後綴搜尋。
針對每個停留對象,識別物件網域中沒有遺留物件複本的DC。 這通常是具有讀取/寫入命名內容的DC,您會在其中手動刪除遺留的物件。 如本文其他位置所述,請使用 RepAdmin 來取得每個 DC 的 objectGUID 值。
在 Object-list.txt 中,使用下列格式建立 GUID 配對的清單:
<GUID=dcGUID>: <GUID=objectGUID>
注意事項
在此值中, dcGUID 代表 DC 的 GUID,該 DC 沒有遺留對象的複本,而 objectGUID 則代表遺留物件的 GUID。
每個配對應該如下所示:
<GUID=<GUID>>: <GUID=<GUID>>
重要事項
在 值中,請勿省略冒號前後的空格。
執行Walk-servers.cmd檔案。
針對 Server-list.txt 中列出的每個 DC 或全域編錄伺服器,腳本會產生名為 Update-server-name.log 的記錄檔。 每個記錄檔都包含要刪除之每個物件的一行。
因為每個列出的伺服器上可能都不存在遺留物件,所以記錄檔中的錯誤不一定表示有問題。 不過,表單作業的錯誤訊息 會拒絕 或 作業錯誤 ,表示 GUID 或值的語法有問題。 如果發生這些錯誤,請確認下列事項:
請確定DC GUID 是域控制器的正確 GUID,而域控制器包含包含物件之網域的讀取/寫入命名內容。
請確定物件 GUID 可識別全域編錄伺服器或 RODC) (唯讀命名內容中遺留的物件。
執行Walkservers.cmd修改環境中許多遺留物件時發生錯誤
物件 <GUID=<GUID>>:<無法移除 GUID=<GUID>>。 錯誤號碼為: -2147016672。 錯誤描述為:。
造成此錯誤的原因
當文稿針對未包含讀取/寫入命名內容的DC GUID執行時,就會發生此錯誤,而該命名內容對應至包含暫留物件的命名內容。 透過 Ldp.exe 工具來確認物件的遺留位置。
範例
在下列範例中,要移除的遺留對象位於 corp.company.local 網域中。 不過,Objects-list.txt <檔案中的 GUID=<GUID>> 專案與位於 company.local 網域中的 DC 相關聯。 此 DC 沒有 corp.company.local 網域的讀取/寫入命名內容。
下列搜尋會產生多個物件,代表 Joe) (相同的用戶,並列出其 objectGUID 值。
ldap_search_s (ld, “DC=company,DC=local”, 2, “ (cn=User*) ”, attrList, 0, &msg) Result <0>: (null)
相符的 DN:
取得 4 個專案:
>> Dn: CN=User, Joe,OU=Exec,OU=公司使用者,DC=corp,DC=company,DC=local
1> canonicalName: corp.company.local/Company Users/Exec/User, Joe;
1> cn: User, Joe; 1> description: CEO;
1> displayName: User, Joe; 1> distinguishedName: CN=User, Joe, OU=Exec,OU=Company Users,DC=corp,DC=company,DC=local; 4> objectClass: top; person; organizationalPerson; user;
1 個> objectGUID: <GUID>;1 個> 名稱:User、Joe;
>> Dn: CN=User, Joe, OU=Migration,DC=corp,DC=company,DC=local 1> canonicalName: corp.company.local/Migration/User, Joe;
1> cn: User, Joe;
1> 描述: 停用帳戶; 1> displayName: User, Joe; 1> distinguishedName: CN=User, Joe,OU=Migration,DC=corp,DC=company,DC=local;
4> objectClass: top; person; organizationalPerson; user;
1 個> objectGUID: <GUID>;
1> 個名稱:User、Joe;
在此範例中,假設 corp.company.local 網域中有一個名為 CORP-DC-01 的 DC。 執行命令 repadmin /showreps CORP-DC-01
會產生 objectGUID 值 <GUID>。 此 GUID 會取代 Objects-list.txt 檔案中先前的 GUID。 這個遞留物件的項目現在會如下所示:
<GUID=<GUID>> : <GUID=<GUID>>
第一個 GUID 是 corp.company.local 網域中域控制器的 GUID。 第二個 GUID 是遺留物件的 GUID。 在此變更之後,Walk-servers.cmd腳本會成功執行。
拿掉環境中的遺留物件時的錯誤訊息 87
當您發現對象實際上並未出現在裝載命名內容但未移除它們的所有 DC 上時, repadmin /removelingeringobjects
可能會發生此錯誤。 當中樞DC複寫使用全域編錄伺服器建立的新物件,但不在自己的網域中使用讀取/寫入複本DC時,可能會發生這種情況。
此錯誤只會在兩種情況下傳回:
- 物件存在於參考 DC 上。
- 相較於目前的 TSL 值, (物件太少,) 無法停留。
如需第二個案例的範例,請考慮具有下列元數據的全域編錄伺服器:
Loc.USN 源自 DC Org.USN Org.Time/Date Ver 屬性
======= =============== ========= ============= === =========
143543261 d20f71f3-6147-4f80-a0c2-470541ef09e6 104742409 <DateTime> 物件Class
RW 複本的更新日期向量:d20f71f3-6147-4f80-a0c2-470541ef09e6 @ USN 104583382 @ Time <DateTime>
GC 的更新日期向量:d20f71f3-6147-4f80-a0c2-470541ef09e6 @ USN 104762881 @ Time <DateTime>
在此情況下,DC 會在使用本身網域中的DC進行複寫后建立物件,但該物件仍會與其他網域中的全域編錄伺服器一起複寫。
若要解決此問題,請讓這些對象變成實際的物件, (過時超過 TSL) ,然後使用本文中的腳本加以移除。 若要確定數據會繼續復寫,請在樹系中的所有DC上設定[ 允許使用發散和損毀的夥伴進行複 寫]。
如果您無法使用這些方法來解決記錄檔中的錯誤,您可能會遇到不同的問題。 如需其他協助,請連絡 Microsoft 產品支援服務。
資料收集
如果您需要 Microsoft 支援的協助,建議您依照 使用 TSS 針對 Active Directory 複寫問題收集資訊中所述的步驟來收集資訊。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應