mqsft.dnsexternal.psm1

# ==============================================================================
# mqsft.dnsexternal.psm1 - AUTO-GENERATED by Create_Module_0_0_5.ps1 v0.0.5
# ------------------------------------------------------------------------------
# Module Version : 1.0.3
# Script Version : 0.0.5
# Built : 2026-02-24 17:16:49
# Source : C:\Modules\functions\mqsft.dnsexternal
#
# DO NOT EDIT THIS FILE DIRECTLY.
# Edit source files in C:\Modules\functions\mqsft.dnsexternal and re-run Create_Module_0_0_5.ps1.
# ==============================================================================

Set-StrictMode -Version Latest

# --- Source: Monitor-NameServerChange.ps1 --------------------------------
function Monitor-NameServerChange {

<#

.SYNOPSIS

Monitors a domain for DNS nameserver (NS) record changes.



.DESCRIPTION

Continuously queries the specified domain for NS records and compares them

against the initial baseline set retrieved at startup.



The function will loop at a defined interval until:

- A change in nameservers is detected (returns $true), or

- The optional maximum number of checks is reached (returns $false).



Useful for:

- Tracking DNS propagation

- Monitoring domain migrations

- Validating registrar or hosting changes

- Change verification during cutovers



.PARAMETER Domain

The domain name to monitor (e.g. example.com).



This parameter is mandatory.



.PARAMETER CheckInterval

Number of seconds between DNS checks.



Default value is 10 seconds.



.PARAMETER MaxChecks

Maximum number of checks before stopping.



Default is 0, which means run indefinitely until a change is detected.



.PARAMETER ShowProgress

If specified, displays the current nameserver values during each check.



.EXAMPLE

Monitor-NameServerChange -Domain example.com



Monitors example.com every 10 seconds until a nameserver change is detected.



.EXAMPLE

Monitor-NameServerChange -Domain example.com -CheckInterval 30 -ShowProgress



Checks every 30 seconds and displays current NS records each cycle.



.EXAMPLE

Monitor-NameServerChange -Domain example.com -MaxChecks 20



Checks up to 20 times, then exits if no change is detected.



.OUTPUTS

System.Boolean



Returns:

- $true if a nameserver change is detected

- $false if maximum checks are reached or initial lookup fails



.NOTES

Author: Mike Quick

Requires: Resolve-DnsName (PowerShell 4.0+)

Intended for DNS monitoring and change validation scenarios.



#>




    [CmdletBinding()]

    param(

        [Parameter(Mandatory=$true)]

        [string]$Domain,

        

        [Parameter(Mandatory=$false)]

        [int]$CheckInterval = 10,

        

        [Parameter(Mandatory=$false)]

        [int]$MaxChecks = 0,

        

        [Parameter(Mandatory=$false)]

        [switch]$ShowProgress

    )

    

    Write-Host "Starting nameserver monitoring for: $Domain" -ForegroundColor Cyan

    Write-Host "Check interval: $CheckInterval seconds" -ForegroundColor Cyan

    Write-Host ""

    

    # Get initial nameservers

    Write-Host "Getting initial nameservers..." -ForegroundColor Yellow

    

    try {

        $nsRecords = Resolve-DnsName -Name $Domain -Type NS -ErrorAction Stop

        $baselineNS = $nsRecords | 

            Where-Object { $_.Type -eq 'NS' } | 

            Select-Object -ExpandProperty NameHost | 

            ForEach-Object { $_.TrimEnd('.').ToLower() } |

            Sort-Object -Unique

    }

    catch {

        Write-Host "ERROR: Could not retrieve initial nameservers for $Domain" -ForegroundColor Red

        Write-Host "Error: $_" -ForegroundColor Red

        return $false

    }

    

    if (-not $baselineNS) {

        Write-Host "ERROR: No nameservers found for $Domain" -ForegroundColor Red

        return $false

    }

    

    Write-Host "Baseline nameservers (watching for changes):" -ForegroundColor Yellow

    $baselineNS | ForEach-Object { Write-Host " - $_" -ForegroundColor White }

    Write-Host ""

    Write-Host "Monitoring for changes..." -ForegroundColor Cyan

    Write-Host ""

    

    $checkCount = 0

    $startTime = Get-Date

    

    # Monitoring loop

    while ($true) {

        $checkCount++

        $currentTime = Get-Date

        $elapsed = $currentTime - $startTime

        

        # Query current nameservers

        try {

            $nsRecords = Resolve-DnsName -Name $Domain -Type NS -ErrorAction Stop

            $currentNS = $nsRecords | 

                Where-Object { $_.Type -eq 'NS' } | 

                Select-Object -ExpandProperty NameHost | 

                ForEach-Object { $_.TrimEnd('.').ToLower() } |

                Sort-Object -Unique

        }

        catch {

            Write-Host "[$checkCount] $(Get-Date -Format 'HH:mm:ss') - Failed to query nameservers" -ForegroundColor Red

            $currentNS = $null

        }

        

        if ($null -eq $currentNS) {

            # Continue on error

        }

        else {

            # Compare nameservers

            $match = ($currentNS.Count -eq $baselineNS.Count) -and 

                     ($baselineNS | ForEach-Object { $_ -in $currentNS } | Where-Object { -not $_ }).Count -eq 0

            

            if (-not $match) {

                # Change detected!

                Write-Host ""

                Write-Host "SUCCESS! Nameserver change detected!" -ForegroundColor Green

                Write-Host "Domain: $Domain" -ForegroundColor Green

                Write-Host ""

                Write-Host "Original nameservers:" -ForegroundColor Yellow

                $baselineNS | ForEach-Object { Write-Host " - $_" -ForegroundColor White }

                Write-Host ""

                Write-Host "New nameservers:" -ForegroundColor Green

                $currentNS | ForEach-Object { Write-Host " - $_" -ForegroundColor White }

                Write-Host ""

                Write-Host "Total checks: $checkCount" -ForegroundColor Cyan

                Write-Host "Total time elapsed: $($elapsed.ToString('hh\:mm\:ss'))" -ForegroundColor Cyan

                Write-Host "Change detected at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan

                return $true

            }

            else {

                $status = "[$checkCount] $(Get-Date -Format 'HH:mm:ss') - No change detected"

                

                if ($ShowProgress) {

                    Write-Host $status -ForegroundColor Gray

                    Write-Host " Current: $($currentNS -join ', ')" -ForegroundColor DarkGray

                }

                else {

                    Write-Host $status -ForegroundColor Gray

                }

            }

        }

        

        # Check if max checks reached

        if ($MaxChecks -gt 0 -and $checkCount -ge $MaxChecks) {

            Write-Host ""

            Write-Host "Maximum checks ($MaxChecks) reached without detecting change" -ForegroundColor Red

            Write-Host "Total time elapsed: $($elapsed.ToString('hh\:mm\:ss'))" -ForegroundColor Cyan

            return $false

        }

        

        Start-Sleep -Seconds $CheckInterval

    }

}