From cf6e942e4eda65a7e2208be2508f9a1186d90420 Mon Sep 17 00:00:00 2001 From: Nicole Rappe Date: Wed, 16 Jul 2025 03:24:56 -0600 Subject: [PATCH] Add Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md --- .../DNS Hierarchy Correction.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md diff --git a/Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md b/Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md new file mode 100644 index 0000000..b288a1a --- /dev/null +++ b/Scripts/Powershell/General Purpose/DNS Hierarchy Correction.md @@ -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." +``` \ No newline at end of file