nrpt-clean.ps1 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # winnet-ops :: nrpt-clean.ps1
  2. # Safely remove orphaned NRPT catch-all rules left behind by disconnected VPNs.
  3. # NEVER removes Tailscale MagicDNS rules.
  4. #
  5. # Defaults to DRY RUN — pass -Apply to actually delete.
  6. # Requires elevated PowerShell (Administrator).
  7. param(
  8. [switch]$Apply,
  9. [string[]]$ProtectNameServers = @("100.100.100.100","fd7a:115c:a1e0::53")
  10. )
  11. # Admin check
  12. $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
  13. if (!$isAdmin) {
  14. Write-Error "Must run as Administrator. Open elevated PowerShell."
  15. exit 1
  16. }
  17. Write-Output "=== BEFORE ==="
  18. $all = Get-DnsClientNrptRule
  19. $all | Format-Table Name, Namespace, NameServers, Comment -AutoSize -Wrap | Out-String | Write-Output
  20. # Find catch-all rules NOT pointing at protected (Tailscale) servers
  21. $targets = $all | Where-Object {
  22. $_.Namespace -eq "." -and
  23. (-not ($_.NameServers | Where-Object { $ProtectNameServers -contains $_ }))
  24. }
  25. if (!$targets) {
  26. Write-Output ""
  27. Write-Output "No orphaned catch-all rules found. Nothing to clean."
  28. exit 0
  29. }
  30. Write-Output ""
  31. Write-Output "=== TARGETS FOR REMOVAL ==="
  32. $targets | Format-List Name, Namespace, NameServers, Comment
  33. if (!$Apply) {
  34. Write-Output ""
  35. Write-Output "DRY RUN — pass -Apply to actually remove the rules above."
  36. exit 0
  37. }
  38. Write-Output ""
  39. Write-Output "=== REMOVING ==="
  40. foreach ($t in $targets) {
  41. try {
  42. Remove-DnsClientNrptRule -Name $t.Name -Force -ErrorAction Stop
  43. Write-Output ("[OK] Removed " + $t.Name)
  44. } catch {
  45. Write-Output ("[FAIL] " + $t.Name + " :: " + $_.Exception.Message)
  46. }
  47. }
  48. Write-Output ""
  49. Write-Output "=== FLUSHING DNS CACHE ==="
  50. Clear-DnsClientCache
  51. ipconfig /flushdns | Select-String "Successfully|Could" | Select-Object -First 1
  52. Write-Output ""
  53. Write-Output "=== VERIFICATION ==="
  54. try {
  55. $r = Resolve-DnsName google.com -Type A -QuickTimeout -ErrorAction Stop
  56. $ips = ($r | Where-Object { $_.Type -eq "A" } | Select-Object -ExpandProperty IPAddress) -join ", "
  57. Write-Output ("[PASS] Resolve-DnsName google.com -> " + $ips)
  58. } catch {
  59. Write-Output ("[FAIL] Resolve-DnsName still broken: " + $_.Exception.Message)
  60. Write-Output " Drill into WFP filters / hosts file / DNS Client service."
  61. }
  62. try {
  63. $r = Invoke-WebRequest -Uri "https://www.google.com" -TimeoutSec 8 -UseBasicParsing
  64. Write-Output ("[PASS] HTTPS google.com -> HTTP " + $r.StatusCode)
  65. } catch {
  66. Write-Output ("[FAIL] HTTPS still broken: " + $_.Exception.Message)
  67. }
  68. Write-Output ""
  69. Write-Output "=== AFTER ==="
  70. Get-DnsClientNrptRule | Format-Table Name, Namespace, NameServers, Comment -AutoSize -Wrap | Out-String | Write-Output