Add Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				GitOps Automatic Deployment / GitOps Automatic Deployment (push) Successful in 7s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	GitOps Automatic Deployment / GitOps Automatic Deployment (push) Successful in 7s
				
			This commit is contained in:
		| @@ -0,0 +1,94 @@ | ||||
| ## Purpose | ||||
| When it comes to best-practices with Windows-based DNS servers, you never want to have `127.0.0.1` or the IP of the server itself as the primary DNS server, you want to have a *different* DNS server as primary, and `127.0.0.1` as the secondary or tertiary DNS server instead. | ||||
|  | ||||
| The following script will automatically detect which network interface has a default gateway (there should only ever be one default gateway on a server's networking).  Then it will check if the primary DNS server is the same IP as the localhost.  If it is, it checks for a secondary DNS server, if it finds one, it performs an `nslookup` on the secondary DNS server, and if it succeeds, it swaps the secondary DNS server as the primary, and the primary becomes the secondary (loopback). | ||||
|  | ||||
| ```powershell | ||||
| <# | ||||
|     Section: Information Gathering | ||||
|     - Gather the adapter(s) with an IP, DNS servers, AND a default gateway set via WMI. | ||||
| #> | ||||
| $adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where-Object { | ||||
|     $_.IPAddress -ne $null -and | ||||
|     $_.DNSServerSearchOrder -ne $null -and | ||||
|     $_.DefaultIPGateway -ne $null -and | ||||
|     $_.DefaultIPGateway.Count -gt 0 | ||||
| } | ||||
|  | ||||
| foreach ($adapter in $adapters) { | ||||
|     Write-Host "-----------------------------------------------------------" | ||||
|     Write-Host "Adapter Name: $($adapter.Description)" | ||||
|     Write-Host "IP Address: $($adapter.IPAddress -join ', ')" | ||||
|     Write-Host "Default Gateway: $($adapter.DefaultIPGateway -join ', ')" | ||||
|     Write-Host "DNS Server(s): $($adapter.DNSServerSearchOrder -join ', ')" | ||||
|  | ||||
|     $localIPs = $adapter.IPAddress + "127.0.0.1" | ||||
|  | ||||
|     <# | ||||
|         Section: Information Analysis | ||||
|         - Identify primary and secondary DNS. | ||||
|         - Check if primary DNS matches any local IP. | ||||
|     #> | ||||
|     $primaryDNS = $adapter.DNSServerSearchOrder[0] | ||||
|     $secondaryDNS = $null | ||||
|     if ($adapter.DNSServerSearchOrder.Count -ge 2) { | ||||
|         $secondaryDNS = $adapter.DNSServerSearchOrder[1] | ||||
|     } | ||||
|  | ||||
|     $isPrimaryLocal = $false | ||||
|     foreach ($local in $localIPs) { | ||||
|         if ($primaryDNS -eq $local) { | ||||
|             $isPrimaryLocal = $true | ||||
|             break | ||||
|         } | ||||
|     } | ||||
|     if ($isPrimaryLocal) { | ||||
|         Write-Host "Primary DNS matches local IP: Yes" | ||||
|     } else { | ||||
|         Write-Host "Primary DNS matches local IP: No" | ||||
|     } | ||||
|  | ||||
|     <# | ||||
|         Section: Information Processing | ||||
|         - If the primary DNS is a local IP and a secondary exists: | ||||
|             a. Test the secondary DNS with nslookup on google.com. | ||||
|             b. Only swap if nslookup is successful. | ||||
|     #> | ||||
|     if ($isPrimaryLocal -and $secondaryDNS) { | ||||
|         Write-Host "Testing nslookup on secondary DNS ($secondaryDNS)..." | ||||
|         $nslookupResult = nslookup google.com $secondaryDNS 2>&1 | ||||
|  | ||||
|         # Simple check for nslookup success | ||||
|         $nslookupSuccess = $false | ||||
|         if ($nslookupResult -match "Name:\s*google\.com") { $nslookupSuccess = $true } | ||||
|         if ($nslookupResult -match "Non-authoritative answer:") { $nslookupSuccess = $true } | ||||
|         if ($nslookupResult -match "Address:") { $nslookupSuccess = $true } | ||||
|  | ||||
|         if ($nslookupSuccess) { | ||||
|             Write-Host "NSlookup via secondary DNS: SUCCESS" | ||||
|             # Swap | ||||
|             $newDnsServers = @($secondaryDNS, $primaryDNS) | ||||
|             if ($adapter.DNSServerSearchOrder.Count -gt 2) { | ||||
|                 $newDnsServers += $adapter.DNSServerSearchOrder[2..($adapter.DNSServerSearchOrder.Count - 1)] | ||||
|             } | ||||
|             $result = $adapter.SetDNSServerSearchOrder($newDnsServers) | ||||
|             if ($result.ReturnValue -eq 0) { | ||||
|                 Write-Host "DNS servers swapped. New primary: $secondaryDNS, New secondary: $primaryDNS" | ||||
|             } else { | ||||
|                 Write-Host "Failed to set new DNS order. Return code: $($result.ReturnValue)" | ||||
|             } | ||||
|         } else { | ||||
|             Write-Host "NSlookup via secondary DNS: FAILED" | ||||
|             Write-Host "DNS servers NOT swapped." | ||||
|         } | ||||
|     } elseif ($isPrimaryLocal -and -not $secondaryDNS) { | ||||
|         Write-Host "No secondary DNS set. No changes made." | ||||
|     } else { | ||||
|         Write-Host "DNS servers are correct. No changes needed." | ||||
|     } | ||||
|  | ||||
|     Write-Host "-----------------------------------------------------------" | ||||
| } | ||||
|  | ||||
| Write-Host "DNS check and correction completed for adapters with a default gateway." | ||||
| ``` | ||||
		Reference in New Issue
	
	Block a user