Missing Subnets

When a computer is joined to a domain It knows for sure of which AD domain it is a member. However once the computer is joined to the domain, It may or may not know which AD site it belongs to. Even if it thinks it knows the AD site, it may not even be in the correct AD site (e.g. because it was moved, AD site was renamed, Subnet not declared, Subnet was removed from a site and add to another…etc.).

Fixing this issue
In the Active Directory Sites and Services console, your need to associate create all of your subnets inthese subnets with the appropriate site(s). It is important to note that with Windows Server 2012 R2 some new cmdlets are available with the Active Directory module to manage the Site subnets:Get-ADReplicationSubnet,New-ADReplicationSubnet,Set-ADReplicationSubnetandRemove-ADReplicationSubnet.
### NETLOGON.log
If some subnets are not declared in your Active Directory and/or not assigned to Site, you might start to see those kind of message in your NetLogon.log file.
Path of the NETLOGON.log file on a Domain Controller:
\\\admin$\debug\netlogon.log</i></b>
Missing subnets errors in NetLogon.log
```
10/02 10:02:32 FX: NO_CLIENT_SITE: WORKSTATION01 10.126.76.146
10/02 10:02:32 FX: NO_CLIENT_SITE: WORKSTATION02 172.16.32.16
10/02 10:03:07 FX: NO_CLIENT_SITE: WORKSTATION03 1.2.3.4
```
A NetLogon.log exists on all the Domain Controllers of your domain, so you need to check every single of them to have the full list of subnets to add.
### PowerShell Reporting
So I created a PowerShell script to handle this task and report all the Missing subnets automatically (every month in my case). Here is a screenshot of the final report. In my opinion, this does not need to run everyday or every week.
### How the script work
*
* Get the list of Domain Controllers in the Domain using .NET
* Get the Last 200 Lines from the NETLOGON.log on each Domain controllers (200 is default)
* Process Logs and Compile in one list and keep one entry per IP
* Export the AD Missing Subnet to a CSV file locally
*
* Exported in: $scriptPathOutput\$DateFormat-AD-SITE-MissingSubnets.csv
* Send an Email Report.
The report will contains:
* One table with the Missings Subnets from all the Domain Controllers
* The other error(s) found in the last 200 lines of each NETLOGON.log on each Domain Controllers(200 is default)
### Requirement
* A Task scheduler to execute the script every x weeks
* Permission to Read \\DC\admin$, a basic account without specific rights will do it
* Permission to write locally in the Output folder ($ScriptPath\Output)
### Running the script

Validating the Email Addresses

[Parameter(Mandatory=$true,HelpMessage="You must specify the Sender Email Address")]
[ValidatePattern("[a-z0-9!#\$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")]
[String]$EmailFrom,
[Parameter(Mandatory=$true,HelpMessage="You must specify the Destination Email Address")]
[ValidatePattern("[a-z0-9!#\$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")]
[String[]]$EmailTo,
```
For the email addresses validation, at first I wanted to use the [mailaddress] class, but this only work since PowerShell v3.0 so I decided to add the previous regex so it is supported on PowerShell v2.0 too.
Note that I also use the [ValidatePattern] attribute declaration, which is super useful!+Jeffery Hicks wrote a great article about it last year.