Fixing AD Subnets

Shaun VermaakCOG Lead Engineer
CERTIFIED EXPERT
My name is Shaun Vermaak and I have always been fascinated with technology and how we use it to enhance our lives and business.
Published:
Updated:
Correctly defined Active Directory sites and subnet allows for the optimized replication, nearest service location, and authentication to the correct server

Introduction


NoClientSites.exe is a NETLOGON.log parser that is used to get a list of all authentications that happened from clients where the Active Directory site is not defined.


These IP addresses can then, in turn, be used to add the appropriate sites and subnets into Active Directory Sites and Services.


Download


A compiled version of NoClientSites.exe can be downloaded here, or compiled from the code provided at the end of this article.

http://blog.ittelligence.com/wp-content/uploads/2018/07/NoClientSites.zip


Usage


NoClientSites.exe provides two methods to get IP addresses without client sites.


The first method allows parsing a whole folder that contains multiple NETLOGON.log files, pre-copied to a central location.

NoClientSites.exe [PATHTONETLOGONFILES]


Alternatively, the NoClientSites.exe tool can be directly executed on each Domain Controllers

NoClientSites.exe


The Code


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NoClientSites
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> netlogonFilePaths = new List<string>();

            if (args.Length == 1)
            {
                string logPath = args[0];
                if (Directory.Exists(logPath))
                {
                    foreach (string file in Directory.GetFiles(logPath, "*.log"))
                    {
                        netlogonFilePaths.Add(file);
                    }
                }
            }
            else
            {
                netlogonFilePaths.Add(Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "Debug", "netlogon.log"));
            }

            if (netlogonFilePaths.Count > 0)
            {
                SortedSet<string> ipAddressesWithoutSites = new SortedSet<string>();
                foreach (string netlogonFilePath in netlogonFilePaths)
                {
                    processNetlogon(netlogonFilePath, ref ipAddressesWithoutSites);
                }

                //Display IP addresses from SortedSet
                foreach (var ipAddress in ipAddressesWithoutSites)
                {
                    Console.WriteLine(ipAddress);
                }
            }
            else
            {
                ShowUsage();
            }
        }
        static void processNetlogon(string netlogonFilePath, ref SortedSet<string> ipAddressesWithoutSites)
        {
            //Read Netlogon.log file line by line and add IP addresses into HashSet
            try
            {
                StreamReader netlogonFile = new StreamReader(netlogonFilePath);

                string line;
                while ((line = netlogonFile.ReadLine()) != null)
                {
                    if (line.Contains("NO_CLIENT_SITE"))
                    {
                        ipAddressesWithoutSites.Add(line.Replace("NO_CLIENT_SITE: ", "|").Split('|')[1].Trim().Split(' ')[1]);
                    }
                }
            }
            catch
            {
                ShowUsage();
                Console.WriteLine($"Error reading file \"{netlogonFilePath}\"");
            }
        }
        private static void ShowUsage()
        {
            Console.WriteLine("");
            Console.WriteLine(" _____     _____ _ _         _   _____ _ _           ");
            Console.WriteLine("|   | |___|     | |_|___ ___| |_|   __|_| |_ ___ ___ ");
            Console.WriteLine("| | | | . |   --| | | -_|   |  _|__   | |  _| -_|_ -|");
            Console.WriteLine("|_|___|___|_____|_|_|___|_|_|_| |_____|_|_| |___|___|");
            Console.WriteLine("");
            Console.WriteLine("NoClientSites.exe [PATHTONETLOGONFILES]");
            Console.WriteLine("Or without a path directy on a Domain Controller");
            Console.WriteLine("NoClientSites.exe");
            Console.WriteLine("");
        }
    }
}


Demo Execution



I hope you found this tutorial useful. You are encouraged to ask questions, report any bugs or make any other comments about it below.

 

Note: If you need further "Support" about this topic, please consider using the Ask a Question feature of Experts Exchange. I monitor questions asked and would be pleased to provide any additional support required in questions asked in this manner, along with other EE experts...  

  

Please do not forget to press the "Thumb's Up" button if you think this article was helpful and valuable for EE members.

 

It also provides me with positive feedback. Thank you!

 

2
1,083 Views
Shaun VermaakCOG Lead Engineer
CERTIFIED EXPERT
My name is Shaun Vermaak and I have always been fascinated with technology and how we use it to enhance our lives and business.

Comments (2)

Albert WidjajaIT Professional
CERTIFIED EXPERT

Commented:
Hi Shaun,

Suppose I have 20+ domain controllers spread across the globe, do I need to manually RDP into each of the DCs and then run the NoClientSites.exe one by one?
Shaun VermaakCOG Lead Engineer
CERTIFIED EXPERT
Awarded 2017
Distinguished Expert 2019

Author

Commented:
Hi Senior IT System Engineer

What I do is Copy the NETLOGON files into a single location and then combine them

@Echo Off
Copy \\%1\C$\Windows\Debug\NETLOGN.log \\FileServer\SomeShare\%1_NETLOGON.log

Open in new window


then combine and run
Copy *.log Combined.log

Open in new window


Wrote this from memory so might have some syntax errors ;)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.