Forum Discussion
nikitamobile855
Apr 14, 2022Brass Contributor
DFS replication issues
Hello everyone, We are running Windows Server 2016 as a Primary Domain Controller. We don't have DFS management tool installed however I'm getting 6002 errors in event viewer. Please advise on h...
- Apr 20, 2022
Thanks, Nikita. That helped a great deal and saved a lot of time.
I'll start at the end and work backwards.
You want to run these commands to clean up what is a very broken DFS-R configuration. I'll provide an in-depth explanation after the commands
Remove-ADObject -Identity "CN=45d9316b-1098-408e-a65d-8ce8449f0aaa,CN=DFSR-LocalSettings,CN=UZTASSRV01,OU=Domain Controllers,DC=sm,DC=local" -Recursive -Confirm:$false; Remove-ADObject -Identity "CN=a7297769-fdcd-4490-ae1c-c80808f44d36,CN=DFSR-LocalSettings,CN=UZTASSRV01,OU=Domain Controllers,DC=sm,DC=local" -Recursive -Confirm:$false; Remove-ADObject -Identity "CN=DFS,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local" -Recursive -Confirm:$false; Remove-ADObject -Identity "CN=DFS_IT,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local" -Recursive -Confirm:$false; Remove-ADObject -Identity "CN=UZTASSVR02,CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local" -Recursive -Confirm:$false;
Overview
What the JSON output you provided showed is:
- There are no DFS namespaces configured;
- The DFS replication group definitions are badly broken in places;
- The "built-in" SYSVOL DFS-R definition is fine but contains an orphaned reference to a domain controller no longer in existence (UZTASSVR02);
- Three DFS replications groups are defined:
- DFS;
- DFS_IT;
- Domain System Volume.
Approach
There were two options I could have pursued:
- Add the missing "MemberReference" values onto the existing "msDFSR-Subscriber" objects; or
- Delete the DFS and DFS_IT DFS replication groups.
I have chosen option 2 since:
- There is no associated DFS namespace;
- The replication groups would only have a single member, which is pointless;
- It provides you with the cleanest outcome, since you can always create new DFS namespaces and replication groups if you decide to later on, and you won't have to worry about old, corrupt data lingering around.
Explanation of each command
Line Comment 1 Removes the orphaned subscription to the "DFS" replication group from UZTASSRV01. 2 Removes the orphaned subscription to the "DFS_IT" replication group from UZTASSRV01. 3 Removes the "DFS" replication group. 4 Removes the "DFS_IT" replication group. 5 Removes the orphaned UZTASSVR02 reference from the "Domain System Volume" replication group. Once you have removed these objects, it will take DFS-R a little while to recognise the changes.
If you want to hurry the process up, you can do any one of the following:
- Restart UZTASSRV01 (since it's the only remaining host); or
- Restart the the "DFSR" service on UZTASSRV01; or
- Run the following command on UZTASSRV01 (it may not be installed though, which is fine):
dfsdiag pollad
Anyhow, once you've either waited a bit or hurried things up, you should find the Event Viewer errors stop.
Cheers,
Lain
LainRobertson
Apr 14, 2022Silver Contributor
Actually, I was going a bit too fast before without paying proper attention to detail. Specifically, the GUID from your Event Log error doesn't match anything below your ADSI Edit picture.
As such, the Event Log error isn't related at all to your ADSI Edit picture. This is actually good news though as I'll explain after speaking to the Event Log error.
The reference to UZTASSRV01.sm.local within the Event Viewer error is only saying which domain controller reported the issue, not that the domain controller is part of the issue.
Dealing with the Event Log error:
What we have from the Event Log error is a forward reference to the "msDFSR-Member" (i.e. objectClass = msDFSR-Member) object in AD. This object lives under the "CN=DFSR-GlobalSettings,CN=System" area, and it's this object that is missing a value for the "msDFSR-ComputerReference" attribute (which is what I was talking about before.)
The new part is this: You need to run a search to see if a matching "msDFSR-Subscriber" object with the same GUID value for the "cn" attribute exists. If it does, it will be nested below the computer we're trying to find in order to fix the missing "msDFSR-ComputerReference" error from the Event Log.
If you're familiar with PowerShell, you can find the msDFSR-Subscriber, and hence the missing computer reference using:
Get-ADObject -Filter { (objectClass -eq "msDFSR-Subscriber") -and (cn -eq "c3b24e94-239f-4621-b82b-b356d6cc9bed") } | select distinguishedName
If it does not exist then you should simply delete the object mentioned in the Event Log (i.e. "CN=<guid>,CN=Topology,CN=DFS,CN=DFSR-GlobalSettings, etc...".) Deleting the orphaned reference will stop event 6002 from being logged.
If it does exist, you will get a value back that looks like:
CN=c3b24e94-239f-4621-b82b-b356d6cc9bed,CN=DFSR-LocalSettings,CN=YourServerName,OU=SomeOU,...,DC=sm,DC=local
What you want to do now is:
- Copy from "CN=YourServerName," to the end of the line above into something like Notepad;
- In ADSI Edit, edit the properties of "CN=c3b24e94-239f-4621-b82b-b356d6cc9bed,CN=Topology,CN=DFS,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local";
- Set the value of the msDFSR-ComputerReference attribute to the value you copied into Notepad from Step 1;
- Click OK to accept the change.
These steps will put the missing computer reference back into the msDFSR-ComputerReference attribute, which will stop event 6002 from being logged.
About the ADSI Edit picture (purely additional information for education and has nothing to do with your event log error):
The GUIDs your looking at under the domain controller object in ADSI Edit are the forward references to the non-SYSVOL replicas to which the domain controller, UZTASSRV01.sm.local, is also a member.
You do not have to check those at all unless there's errors relating to them. You can if you'd like, but unless you're really unlucky, you will find matching "msDFSR-Member" objects matching the GUIDs from your ADSI Edit picture below one of the replica groups somewhere beneath "CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local".
Anyhow, as I say, this is purely additional information. The only thing you need to remember is that your ADSI Edit picture is totally unrelated to the Event Log error.
Cheers,
Lain
nikitamobile855
Apr 15, 2022Brass Contributor
Thanks a lot for your detailed response!
I have tried to run the PowerShell script and it doesn't return any values. And I didn't clearly understood how I can delete it now?
- LainRobertsonApr 16, 2022Silver Contributor
Okay, given you didn't get any values returned from that command, just delete the object listed in the Event Viewer error.
In other words, delete the following object from AD (make sure you check I haven't typed the GUID incorrectly - you can copy-and-paste it from the Event Viewer error if you like):
CN=c3b24e94-239f-4621-b82b-b356d6cc9bed,CN=Topology,CN=DFS,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local
Cheers,
Lain
- nikitamobile855Apr 19, 2022Brass Contributor
I still don't understand how I can delete the object if it doesn't appear either in AD or ADSI editor.
CN=c3b24e94-239f-4621-b82b-b356d6cc9bed,CN=Topology,CN=DFS,CN=DFSR-GlobalSettings,CN=System,DC=sm,DC=local
- LainRobertsonApr 19, 2022Silver Contributor
If you can't see it then the error doesn't make any sense, either.
Rather than trying to work through checking each object individually, I've written a quick script (inserted at the bottom of this post) to pull some of the DFS (-N and -R) configuration information from Active Directory.
If you can save it as "Get-DfsConfiguration.ps1", then run it as shown below and upload the JSON, that would help with the cross-referencing.
You can direct-message me the results if you'd prefer not to post them here, but there's nothing confidential about it, meaning others here may be able to offer insight if you choose to paste the results in here.
.\Get-DfsConfiguration.ps1 | ConvertTo-Json -Depth 3
If the script throws an error, let me know and I'll fix it as I didn't spend much time quality assuring it. But if it behaves, the output will help with both of your TechCommunity threads.
It does not need any special rights and can (and should) be run as a normal, unprivileged user.
Also, can you check that the DFS service is running on your domain controller? (i.e. "Get-Service -Name Dfs")
Cheers,
Lain
[cmdletbinding()] Param() #region Class definitions. class DfsrSubscriber { [string] $Status; [guid] $ObjectGUID; [string] $ObjectClass; [string] $Name; [string] $DistinguishedName; [string] $MemberReference; DfsrSubscriber([guid] $ObjectGUID, [string] $Name, [string] $DistinguishedName, [System.DirectoryServices.PropertyValueCollection] $MemberReference) { $this.ObjectGUID = $ObjectGUID; $this.ObjectClass = "msDFSR-Subscriber"; $this.Name = $Name; $this.DistinguishedName = $DistinguishedName; if (($MemberReference.Count -gt 0) -and ([adsi]::Exists("$($Script:AdsPrefix)/CN=SYSVOL Subscription,$DistinguishedName"))) { $this.Status = "Okay"; $this.MemberReference = $MemberReference[0]; } else { $this.Status = "Unhealthy"; $this.MemberReference = $null; } } } class DfsrSubscription { [string] $Status; [guid] $ObjectGUID; [string] $ObjectClass; [string] $Name; [string] $DistinguishedName; DfsrSubscription([guid] $ObjectGUID, [string] $Name, [string] $DistinguishedName) { $this.Status = "Okay"; $this.ObjectGUID = $ObjectGUID; $this.ObjectClass = "msDFSR-Subscription"; $this.Name = $Name; $this.DistinguishedName = $DistinguishedName; } } class DfsrReplicationGroup { [string] $Status; [guid] $ObjectGUID; [string] $ObjectClass; [string] $Name; [string] $DistinguishedName; DfsrReplicationGroup([guid] $ObjectGUID, [string] $Name, [string] $DistinguishedName) { $this.ObjectGUID = $ObjectGUID; $this.ObjectClass = "msDFSR-ReplicationGroup"; $this.Name = $Name; $this.DistinguishedName = $DistinguishedName; if ([adsi]::Exists("$($Script:AdsPrefix)/CN=Topology,$DistinguishedName")) { $this.Status = "Okay"; } else { $this.Status = "Unhealthy"; } } } class DfsrMember { [string] $Status; [guid] $ObjectGUID; [string] $ObjectClass; [string] $Name; [string] $DistinguishedName; [string] $ComputerReference; [string] $ServerReference; [string] $MembershipBL; DfsrMember([guid] $ObjectGUID, [string] $Name, [string] $DistinguishedName, [System.DirectoryServices.PropertyValueCollection] $ComputerReference, [System.DirectoryServices.PropertyValueCollection] $ServerReference, [System.DirectoryServices.PropertyValueCollection] $MembershipBL) { $this.ObjectGUID = $ObjectGUID; $this.ObjectClass = "msDFSR-Member"; $this.Name = $Name; $this.DistinguishedName = $DistinguishedName; $this.Status = "Okay"; $this.MembershipBL = $MembershipBL; #region Validate ComputerReference. if ($ComputerReference.Count -gt 0) { $this.ComputerReference = $ComputerReference[0]; } else { $this.Status = "Unhealthy"; $this.ComputerReference = $null; } #endregion #region Validate ServerReference. if ($ServerReference.Count -gt 0) { $this.ServerReference = $ServerReference[0]; } else { $this.Status = "Unhealthy"; $this.ServerReference = $null; } #endregion #region Validate MembershipBL. if ($MembershipBL.Count -gt 0) { $this.MembershipBL = $MembershipBL[0]; } else { $this.Status = "Unhealthy"; $this.MembershipBL = $null; } #endregion } } class DfsNamespaceV2 { [string] $Status; [guid] $ObjectGUID; [string] $ObjectClass; [string] $Name; [string] $DistinguishedName; [System.Collections.Generic.List[DfsNamespaceV2Target]] $Targets; DfsNamespaceV2([guid] $ObjectGUID, [string] $Name, [string] $DistinguishedName, [System.DirectoryServices.PropertyValueCollection] $Targets) { $this.ObjectGUID = $ObjectGUID; $this.ObjectClass = "msDFS-Namespacev2"; $this.Name = $Name; $this.DistinguishedName = $DistinguishedName; $this.Targets = Get-DfsV2Target -TargetListV2 $Targets; if ($this.Targets.Count -gt 0) { $this.Status = "Okay"; } else { $this.Status = "Unhealthy"; } } } class DfsNamespaceV2Target { [bool] $Online; [string] $Target; DfsNamespaceV2Target([string] $Status, [string] $Target) { $this.Online = $Status -eq "online"; $this.Target = $Target; } } #endregion #region Function definitions. function Get-DfsV2Target([System.DirectoryServices.PropertyValueCollection] $TargetListV2) { $Targets = [System.Collections.Generic.List[DfsNamespaceV2Target]]::new(); if ($TargetListV2.Count -gt 0) { $Xml = [xml]::new(); $Xml.LoadXml(([System.Text.Encoding]::Unicode.GetString($TargetListV2[0])).SubString(1)); foreach ($Entry in $Xml.DocumentElement.target) { $Targets.Add([DfsNamespaceV2Target]::new($Entry.state, $Entry.InnerText)); } } return($Targets); } #endregion #region Preamble. $RootDSE = [adsi]"LDAP://RootDSE"; $Server = $RootDSe.dNSHostName[0].ToLowerInvariant(); $DefaultNamingContext = $RootDSE.defaultNamingContext[0]; $AdsPrefix = "LDAP://$Server"; Write-Verbose "Connected to domain controller: $Server"; Write-Verbose "Default naming context: $DefaultNamingContext"; #endregion #region Enumerate domain controllers for SYSVOL DFS-R memberships. These represent the forward references pointing to the replication groups. Write-Warning "Enumerating domain controller SYSVOL DFS-R memberships:"; $SysvolTopology = [adsi]"$AdsPrefix/OU=Domain Controllers,$DefaultNamingContext"; foreach ($DomainController in $SysvolTopology.Children) { if (-not [adsi]::Exists("$AdsPrefix/CN=DFSR-LocalSettings,$($DomainController.distinguishedName)")) { continue; } foreach ($DfsrSubscriber in $DomainController.Children.Find("CN=DFSR-LocalSettings").Children) { $DfsrSubscriberSummary = [DfsrSubscriber]::new($DfsrSubscriber.objectGUID[0], $DfsrSubscriber.Name[0], $DfsrSubscriber.distinguishedName[0], $DfsrSubscriber.Properties['msDFSR-MemberReference']); $DfsrSubscriberSummary; if ($DfsrSubscriberSummary.Status.Equals("Okay", [System.StringComparison]::Ordinal)) { foreach ($DfsrSubscription in $DfsrSubscriber.Children) { # Arguably, this could be left out as it currently doesn't add much to the SYSVOL discussion. Only red flag would be if it were missing (given the subscriber implicitly exists.) [DfsrSubscription]::new($DfsrSubscription.objectGUID[0], $DfsrSubscription.Name[0], $DfsrSubscription.distinguishedName[0]); } } } } $SysvolTopology.Dispose(); #endregion #region Enumerate DFS-R replication groups. These contain the topology definitions, which in turn contain back-link references to the server objects' membership definitions. Write-Warning "Enumerating DFS-R replication group topologies:"; $DfsrGroups = [adsi]"$AdsPrefix/CN=DFSR-GlobalSettings,CN=System,$DefaultNamingContext"; foreach ($DfsrGroup in $DfsrGroups.Children) { $DfsrGroupSummary = [DfsrReplicationGroup]::new($DfsrGroup.objectGUID[0], $DfsrGroup.Name[0], $DfsrGroup.distinguishedName[0]); $DfsrGroupSummary; if ($DfsrGroupSummary.Status.Equals("Okay", [System.StringComparison]::Ordinal)) { foreach ($DfsrMember in $DfsrGroup.Children.Find("CN=Topology").Children) { [DfsrMember]::new($DfsrMember.objectGUID[0], $DfsrMember.Name[0], $DfsrMember.distinguishedName[0], $DfsrMember.'msDFSR-ComputerReference', $DfsrMember.serverReference, $DfsrMember.'msDFSR-MemberReferenceBL'); } } } $DfsrGroups.Dispose(); #endregion #region Enumerate DFS-N namespaces. Note: SYSVOL isn't defined here as that's handled differently. Write-Warning "Enumerating DFS-N namespaces:"; $DfsNamespaces = [adsi]"$AdsPrefix/CN=Dfs-Configuration,CN=System,$DefaultNamingContext"; foreach ($DfsNamespaceAnchor in $DfsNamespaces.Children) { if ($DfsNamespaceAnchor.Children.Count -eq 0) { continue; } foreach ($DfsNamespace in $DfsNamespaceAnchor.Children) { [DfsNamespaceV2]::new($DfsNamespace.objectGUID[0], $DfsNamespace.Name[0], $DfsNamespace.distinguishedName[0], $DfsNamespace.'msDFS-TargetListv2'); } } $DfsNamespaces.Dispose(); #endregion $RootDSE.Dispose();
Edited: 2022-06-11 to include a serverReference check on msDFSR-Member objects.