Skip to content

Commit b53f557

Browse files
author
Simonx Xu
authored
Merge pull request #7896 from v-lianna/CI_3039
AB#3039 lingering-objects-remain-dc-gc-back
2 parents 6e0d6e9 + 20be639 commit b53f557

3 files changed

Lines changed: 240 additions & 2 deletions

File tree

.openpublishing.redirection.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11147,7 +11147,7 @@
1114711147
},
1114811148
{
1114911149
"source_path": "support/windows-server/active-directory/lingering-objects-remain.md",
11150-
"redirect_url": "/previous-versions/troubleshoot/windows-server/lingering-objects-remain",
11150+
"redirect_url": "/troubleshoot/windows-server/active-directory/manually-remove-lingering-objects",
1115111151
"redirect_document_id": false
1115211152
},
1115311153
{
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
---
2+
title: Manually Remove Lingering Objects on Outdated Replication Partners
3+
description: Helps with manual removal of lingering objects after you bring an outdated domain controller (DC) or global catalog server back online.
4+
ms.date: 12/24/2024
5+
manager: dcscontentpm
6+
audience: itpro
7+
ms.topic: troubleshooting
8+
ms.reviewer: kaushika, herbertm, v-lianna
9+
ms.custom: sap:Active Directory\Active Directory replication and topology, csstroubleshoot
10+
---
11+
# Manually remove lingering objects on outdated replication partners
12+
13+
This article helps manually remove [lingering objects](information-lingering-objects.md#summary) after you bring an outdated domain controller (DC) or global catalog server back online. In many cases, you can clean up lingering objects using the `repadmin /removelingeringobjects` command or tools like [Lingering Object Liquidator](lingering-object-liquidator-tool.md). However, these facilities don't work if you have [abandoned objects](https://support.microsoft.com/topic/attributes-that-contain-stale-or-bad-data-cause-exchange-offline-address-book-oab-generation-failures-and-event-ids-9126-9330-and-9339-together-with-stop-error-code-8004010e-occur-d505154b-f51f-6604-436b-e30fe4e486d9).
14+
15+
When you bring a domain controller or global catalog server back online after it has been offline for a long time, any of the following issues might occur:
16+
17+
- Email messages aren't delivered to a user whose user object was moved between domains. After you bring the outdated domain controller or global catalog server back online, both instances of the user object appear in the global catalog content. Both objects have the same email address, so email messages can't be delivered.
18+
- A user account that no longer exists still appears in the global address list.
19+
- A universal group that no longer exists still appears in a user's access token.
20+
21+
## The offline duration is longer than the value of the tombstone lifetime setting
22+
23+
A domain controller or global catalog server that has been offline for longer than the value of the [tombstone lifetime](information-lingering-objects.md#how-object-deletions-replicate-through-a-forest) setting (the default value is 60 or 180 days) might contain objects that have been deleted on other domain controllers or global catalog servers. Additionally, tombstones for these objects may no longer exist. When you bring the outdated domain controller back online, it can't be notified of the object deletions. If any of the objects are modified, they're reactivated in the rest of the domain.
24+
25+
For lingering objects that are replicated into read/write naming contexts, the standard behavior (Loose Replication Consistency) is that the receiving domain controller re-creates the objects that aren't already present in the local database Directory Information Tree (DIT). These objects are then replicated back to the originating domain controller, effectively re-creating the deleted objects. If the object shouldn't exist in Active Directory (for example, if the object was reintroduced by an outdated domain controller), you can delete the objects with standard tools (such as ADSIEdit or the Active Directory Users and Computers snap-in).
26+
27+
It's straightforward to remove lingering objects for read/write naming contexts. This article describes how to remove lingering objects that have already appeared in global catalog (read-only) naming contexts.
28+
29+
## Obtain the distinguished name and identify the domain
30+
31+
The best way to identify in which domain an object is located (and therefore the name of a domain controller that has a read/write copy of the object) is to establish the distinguished name of the object. You can do this by searching for the name (or part of the name) of the duplicate user, group, or distribution list by using the **Ldp.exe** tool:
32+
33+
1. Start **Ldp.exe**.
34+
2. On the **Connection** menu, select **Connect**.
35+
3. Enter the name of a global catalog server. Enter **3268** as the port to connect to. Select **OK**.
36+
4. On the **Connection** menu, select **Bind**. If your current credentials aren't sufficient to query all of the global catalog contents, enter valid credentials. Select **OK**.
37+
5. On the **View** menu, select **Tree**. Enter the distinguished name of the forest root. Select **OK**.
38+
6. Right-click the forest root in the tree list, and then select **Search**.
39+
7. Create a filter of the following form:
40+
41+
**(attribute=value)**
42+
43+
Substitute *attribute* and *value* with the appropriate data. For example, to create a filter to return results where the **sAMAccountName** attribute has a value set to a user account named **testuser**, enter **(sAMAccountName=testuser)** in the **Filter** box. The **cn**, **userPrincipalName**, **sAMAccountName**, **name**, **mail**, and **sn** attributes are useful candidates for finding a user object. For group objects, use the **cn**, **sAMAccountName**, or **name** attributes. You can use asterisks (*) in the *value* field if necessary.
44+
45+
For more information on Lightweight Directory Access Protocol (LDAP) filter syntax, see [Search Filter Syntax](/windows/win32/adsi/search-filter-syntax).
46+
47+
8. Select **Subtree** as the search scope.
48+
9. Select **Options**. In the **Search Options** dialog, move to the end of the **Attributes** control.
49+
10. Append **objectGUID;** to the list. Select **OK**.
50+
11. Select **Run** to run the query.
51+
12. View the results. You must identify which of the displayed objects should be removed from the global catalog server. One indication that you have found a problematic object is that the object doesn't exist on a read/write copy of the naming context.
52+
13. Rephrase the query and rerun it if necessary.
53+
14. If you have identified the lingering object, note its distinguished name and **objectGUID**.
54+
55+
After you obtain the object's distinguished name, identify the domain in which it was located by looking at the **dc=** part of the distinguished name. For example, the domain of **cn=FirstName LastName,cn=Users,dc=contoso,dc=com** is **contoso.com**. Next, locate a domain controller for the domain (it can also be a global catalog server).
56+
57+
Run the `repadmin /showreps <dcname>` command (where `<dcname>` is the name of the domain controller you located). From the output, note the domain controller's `objectGuid`:
58+
59+
```console
60+
C:\>repadmin /showreps some-DC
61+
Your-Site\some-DC
62+
DSA Options : (none)
63+
objectGuid : <GUID>
64+
```
65+
66+
## Delete lingering objects if you have only a few objects and global catalog servers
67+
68+
If you have only a few objects and global catalog servers, follow these steps to delete the objects by using **Ldp.exe**:
69+
70+
1. Sign in to each global catalog server that contains a copy of the lingering object by using Enterprise Administrator credentials.
71+
2. Start **Ldp.exe** and connect to port 389 on the local domain controller (leave the **Server** box empty).
72+
3. On the **Connection** menu, select **Bind**. Leave all of the boxes empty (you're already signed in as an Enterprise Administrator).
73+
4. On the **Browse** menu, select **Modify**.
74+
5. Leave the **Dn** box empty.
75+
6. In the **Attribute** box, enter **RemoveLingeringObject**.
76+
7. Enter **<GUID=** as the value.
77+
8. Append the GUID of the domain controller that you obtained earlier from the command `repadmin /showreps <dcname>`.
78+
79+
> [!NOTE]
80+
> In this example, `<dcname>` is a domain controller that hosts the writable naming context of the lingering object.
81+
82+
9. Append **> : <GUID=**. Don't omit the spaces.
83+
10. Append the GUID of the lingering object.
84+
11. Append **>**.
85+
12. The complete value should look like:
86+
**<GUID=*GUID*> : <GUID=*GUID*>**
87+
13. Select the **Replace** operation, and then select **Enter** on the interface. Now the command appears in the **Entry List**.
88+
14. Select **Run** to run the request. The right side of the **Ldp.exe** window contains the request result. It should look similar to this example:
89+
90+
```output
91+
***Call Modify...
92+
ldap_modify_s(ld, '(null)',[1] attrs);
93+
Modified "".
94+
```
95+
96+
## Delete lingering objects if you have many objects and global catalog servers
97+
98+
If you have many objects to delete and many global catalog servers, it might be more convenient to use the following scripts:
99+
100+
1. Paste the following text into a new file named **Walkservers.cmd** in a new folder:
101+
102+
```console
103+
for /f %%j in (server-list.txt) do walkobjects %%j
104+
```
105+
106+
2. Paste the following text into a file named **Walkobjects.cmd**:
107+
108+
```console
109+
for /f "delims=@" %%i in (object-list.txt) do cscript //NoLogo MODIFYROOTDSE.VBS %1 "%%i" >>update-%1.log
110+
```
111+
112+
> [!NOTE]
113+
> This is a single command line. Line breaks are inserted here for readability.
114+
115+
3. Paste the following text into a file named **Modifyrootdse.vbs**:
116+
117+
```vbscript
118+
'********************************************************************
119+
'*
120+
'* File: MODIFYROOTDSE.VBS
121+
'* Created: January 2002
122+
'* Version: 1.0
123+
'*
124+
'* Main Function: Writes Active Directory information to clean up
125+
'* objects as per: Q314282.
126+
'* Usage: Modifyrootdse.vbs <TargetServer> <GUID PAIR>
127+
'* Parameter are fed into the script using a pair of batch files.
128+
'*
129+
'* Copyright (C) 2002 Microsoft Corporation
130+
'*
131+
'********************************************************************
132+
133+
OPTION EXPLICIT
134+
ON ERROR RESUME NEXT
135+
136+
Dim objDomain
137+
Dim ObjValue, strServerName, adsLdapPath
138+
Dim i
139+
140+
'Get the command-line arguments
141+
if Wscript.arguments.count <> 2 Then
142+
Print "Invalid Number of Parameters. Use with WalkServers.CMD and WalkObjects.CMD"
143+
WScript.quit
144+
End If
145+
146+
strServerName = Wscript.arguments.item(0)
147+
ObjValue = Wscript.arguments.item(1)
148+
149+
adsLdapPath = "LDAP://" & strServerName & "/RootDSE"
150+
151+
Set objDomain = GetObject(adsLdapPath)
152+
If Err.Number <> 0 Then
153+
WScript.Echo "Error opening ROOTDSE. Error number is: " & Err.Number & ". Error description is: " & Err.Description & "."
154+
Set objDomain = Nothing
155+
WScript.quit
156+
End If
157+
158+
objDomain.Put "RemoveLingeringObject", ObjValue
159+
objDomain.Setinfo
160+
161+
If Err.Number = 0 Then
162+
WScript.Echo "Object " & ObjValue & " was removed."
163+
Else
164+
WScript.Echo "Object " & ObjValue & " could not be removed. Error number is: " & Err.Number & ". Error description is: " & Err.Description & "."
165+
End If
166+
WScript.Quit
167+
```
168+
169+
> [!NOTE]
170+
> If you start **Modifyrootdse.vbs** manually, make sure to enclose any parameters that contain spaces in quotation marks.
171+
172+
4. Create a list of all global catalog servers that contain the lingering objects. Place the server names in a **Server-list.txt** file in the same folder. Use the fully qualified domain names to avoid DNS suffix searches.
173+
5. Add the GUID pairs that you obtained earlier in this procedure to an **Object-list.txt** file. Add one pair per line. Use the following syntax:
174+
175+
`<GUID = <DC GUID>> : <GUID = <object GUID>>`
176+
177+
Here, the first value is the GUID of the writable domain controller that is used to confirm that the original object no longer exists. The second value is the GUID of the lingering object to be removed.
178+
179+
6. Run the **Walk-servers.cmd** file. The scripts generate a log file named **Update-server-name.log** for each global catalog server listed in the **Server-list.txt** file. The log files contain a line for each object that is to be deleted.
180+
181+
> [!NOTE]
182+
> Errors in the log files don't necessarily indicate a problem because the lingering objects might not exist on all global catalog servers. However, error messages of the form "operation refused" or "operation error" indicate a problem with the GUIDs or the value syntax. If these errors occur, verify the following items:
183+
>
184+
> - Make sure that the domain controller GUIDs are the correct GUIDs for domain controllers that contain a writable copy of the domain that contains the object.
185+
> - Make sure that the object GUIDs identify lingering objects in global catalog (read-only) naming contexts.
186+
187+
### Error message when running Walkservers.cmd to modify many lingering objects in the environment
188+
189+
> Object <GUID=GUID> : <GUID=GUID> could not be removed. Error number is: -2147016672. Error description is: .
190+
191+
This error occurs because the script runs against the GUID of a domain controller that doesn't contain a writeable partition that contains the lingering object. Use the **Ldp.exe** tool to verify the location of the lingering object.
192+
193+
#### Example
194+
195+
In the following example, the lingering object that causes the error message to be removed is located in the `corp.company.local` domain. However, the `<GUID=<GUID>>` from the **objects-list.txt** file is associated with a domain controller in the `company.local` domain that doesn't have a writeable partition for `corp.company.local`.
196+
197+
```output
198+
ldap_search_s(ld, "DC=company,DC=local", 2, "(cn=User*)", attrList, 0, &msg)
199+
Result <0>: (null)
200+
Matched DNs:
201+
Getting 4 entries:
202+
>> Dn: CN=User\, Joe,OU=Exec,OU=Corporate Users,DC=corp,DC=company,DC=local
203+
1> canonicalName: corp.company.local/Corporate Users/Exec/User, Joe;
204+
1> cn: User, Joe;
205+
1> description: CEO;
206+
1> displayName: User, Joe;
207+
1> distinguishedName: CN=User\, Joe,OU=Exec,OU=Corporate Users,DC=corp,DC=company,DC=local;
208+
4> objectClass: top; person; organizationalPerson; user;
209+
1> objectGUID: <GUID>;
210+
1> name: User, Joe;
211+
>> Dn: CN=User\, Joe,OU=Migration,DC=corp,DC=company,DC=local
212+
1> canonicalName: corp.company.local/Migration/User, Joe;
213+
1> cn: User, Joe;
214+
1> description: Disabled Account;
215+
1> displayName: User, Joe;
216+
1> distinguishedName: CN=User\, Joe,OU=Migration,DC=corp,DC=company,DC=local;
217+
4> objectClass: top; person; organizationalPerson; user;
218+
1> objectGUID: <GUID>;
219+
1> name: User, Joe;
220+
```
221+
222+
Obtain the GUID of a server in the `corp.company.local` domain by running the following command:
223+
224+
```console
225+
repadmin /showreps <dcname>
226+
```
227+
228+
In this command, `<dcname>` is a placeholder for the name of a domain controller in the `corp.company.local` domain. Change the GUID in the **Objects-list.txt** file to match the GUID of the domain controller in the `corp.company.local` domain. In this example, the **Objects-list.txt** file will appear as:
229+
230+
`<GUID=<GUID>> : <GUID=<GUID>>`
231+
232+
The first `<GUID>` is the GUID of the domain controller in the `corp.company.local` domain. The second `<GUID>` is the GUID of the lingering object from the LDAP search.
233+
234+
When you run **Walk-servers.cmd**, the command now completes successfully without the "-2147016672" error.
235+
236+
If you can't resolve the errors in the log files by using these methods, you might be experiencing a different problem. Contact Microsoft Product Support Services for additional assistance.

support/windows-server/toc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,10 @@ items:
207207
href: ./active-directory/duplicate-active-directory-replication-connections.md
208208
- name: How to restrict RPC traffic to a specific port
209209
href: ./active-directory/restrict-ad-rpc-traffic-to-specific-port.md
210-
- name: lingering objects in a Windows Server Active Directory forest
210+
- name: Lingering objects in a Windows Server Active Directory forest
211211
href: ./active-directory/information-lingering-objects.md
212+
- name: Lingering objects manual removal
213+
href: ./active-directory/manually-remove-lingering-objects.md
212214
- name: Manually replicating data between domain controllers fails
213215
href: ./active-directory/target-principal-name-is-incorrect-when-replicating-data.md
214216
- name: Modify the default intra-site DC replication interval

0 commit comments

Comments
 (0)