Delete/Add A/PTR Record script

JoeyD 1 Reputation point
2023-03-31T05:20:21.5033333+00:00
I need help with below script and what is wrong with it



param(
  [Parameter(Mandatory=$true)]
  [string]$ARecord,
  [Parameter(Mandatory=$true)]
  [string]$Zone,
  [Parameter(Mandatory=$true)]
  [string]$DnsServer
)

# Check if A Record Exist
$ARecordcheck = Get-DnsServerResourceRecord -ZoneName $Zone -RRType A -Name $ARecord -ComputerName $DnsServer -ErrorAction SilentlyContinue
if (!$ARecordcheck) {
  Write-Error "A record $ARecord does not exist in DNS zone $Zone."
  return
}

$FQDN = "$ARecord.$Zone"

# Get IP Address from DNS
$IP = Resolve-DnsName -Name $ARecord -Type A | Select-Object -ExpandProperty IPAddress

# Get reverse lookup zone and IP
$reverselookupIP = Resolve-DnsName -Type PTR $IP | Select-Object -ExpandProperty Name
$reversezone = $reverselookupIP.Substring(($reverselookupIP.IndexOf('.') + 1))
$PTRLastOctet = $IP.Split('.')[-1]

$PtrRecord = Get-DnsServerResourceRecord -ZoneName $reversezone -RRType PTR -ComputerName $DnsServer -Name $PTRLastOctet
if (!$PtrRecord) {
  Write-Error "PTR record for $IP does not exist in DNS zone $reversezone."
  return
}

# ping test
$result = Test-NetConnection -InformationLevel Quiet -ComputerName $IP -Port 53
if (!$result) {
  Write-Host "Deleting DNS record $ARecord and PTR record $PTRLastOctet.$reversezone."
  Remove-DnsServerResourceRecord @{'ZoneName' = $Zone; 'Name' = $ARecord; 'RRType' = 'A'; 'ComputerName' = $DnsServer; 'Confirm' = $false}
  Remove-DnsServerResourceRecord @{'ZoneName' = $reversezone; 'Name' = $PTRLastOctet; 'RRType' = 'PTR'; 'RecordData' = $FQDN; 'ComputerName' = $DnsServer; 'Confirm' = $false}
}
else {
  Write-Host "The IP address $IP is alive. Please check."
}

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,322 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  2. Rich Matheisen 44,416 Reputation points
    2023-04-03T02:01:36.1266667+00:00

    This script uses your script as its base. It's a rough cut and could use some polishing, but it adds some checking for things like multiple A records for the same name, and multiple PTR records for the same IP address. It does get the correct reverse lookup zone, though.

    Your script looks like it depends on there being only reverse lookup zones are totally classful (e.g., there has to be a zone a three-octet zone for each Class "C" network (192.168.1, 192.168.2, etc.). You can't have a single "168.192.in-addr.arpa" zone that holds all of the addresses in the 192.168.0-254 range. Your script also doesn't take into account that there might be Class "B" (or even "A") networks that would use more than one octet to identify a particular host in a reverse lookup zone.

    I added a "WhatIf" parameter to the script (and to the two "Remove" DNS cmdlets) so you can run tests without actually removing anything from DNS.

    param(
        [Parameter(Mandatory = $true)]
        [string]$ARecord,
        [Parameter(Mandatory = $true)]
        [string]$Zone,
        [Parameter(Mandatory = $true)]
        [string]$DnsServer,
        [switch]$WhatIf = $true
    )
        
    # Check if A Record Exist
        
    $ARecordcheck = Get-DnsServerResourceRecord -ZoneName $Zone -RRType A -Name $ARecord -ComputerName $DnsServer -ErrorAction SilentlyContinue
    if (!$ARecordcheck) {
        Write-Error "'A' record for '$ARecord' does not exist in DNS zone '$Zone'."
        return
    }
    if ($ARecordcheck -is [array]) {
        Write-Error "Multiple 'A' records exist for '$ARecord' in zone '$Zone'."
        Write-Error $ARecordcheck
        return
    }
        
    $FQDN = "{0}.{1}" -f ($ARecordcheck.HostName), $Zone
    # Get IP Address from A record
    $IP = $ARecordcheck.RecordData.IPv4Address.IPAddressToString
        
    # Get reverse lookup zones
    $zones = @{}
    Get-DnsServerZone |
    ForEach-Object {
        if ($_.IsReverseLookupZone) {
            $z = $_.zonename.substring(0, $_.zonename.IndexOf(".in-addr.arpa"))   # just get the parts up to '.in-addr.arpa'
            $ipaddr = $z -split '\.'
            $len = $ipaddr.count
            [array]::Reverse($ipaddr)
            $ipaddr = "{0}." -f ($ipaddr -join '.')     # add dot at end to avoid matching 192.168.1 with, say, 192.168.11
            if ($zones.ContainsKey($len)) {
                $zones.$len += $ipaddr
            }
            else {
                $zones[$len] = , $ipaddr     # Note: 'magic comma'!
            }
        }
    }
        
    $reverselookupName = Resolve-DnsName -Type PTR $IP -Server $DnsServer | Select-Object -ExpandProperty Name
    if (-NOT $reverselookupName) {
        Write-Error "Unable to resolve IPv4 address ($IP) for 'A' record ($ARecord) to PTR record."
        return
    }
    if ($reverselookupName -is [array]) {
        Write-Error "Multiple 'PTR' record exist for IPv4 address '$IP' of 'A' record for '$ARecord."
        Write-Error $reverselookupName
        return
    }
    
    
    $reversezoneIPString = $reverselookupName.Substring(0, ($reverselookupName.IndexOf('.in-addr.arpa')))
    $reversezoneIPArray = $reversezoneIPString -split '\.'      # E.g., 251,1,168,192"
    $reversezoneArray = $reversezoneIPString -split '\.'        # E.g., 251,1,168,192" (but will be transformed)
    [array]::Reverse($reversezoneArray)                         # now it's a typical IPv4 quad in an array. E.g., 192,168,1,251
    $reversezoneString = $reversezoneArray -join '.'            # now it's a typical dotted quad string. E.g., "192.168.1.251"
    $zonematch = ""
    $lastoctets = ""
    for ($i = 3; $i -gt 0; $i--) {
        # find longest matching reverse zone
        if ($zones.ContainsKey($i)) {
            foreach ($z in $zones.$i) {
                if ($reversezoneString -like "$z*") {
                    # is the machine's IP like the zones's IP?
                    $zonematch = $z                             # remember the zone
                    $lastoctets = $reversezoneIPArray[0..(4 - ($i + 1))] -join '.'  # get the octets that represent the machine within the zone (may be 1, 2, or 3 0ctets)
                    break
                }
            }
            if ($lastoctets.length -gt 0) {
                # must contain at least single-digit"
                break
            }
        }
    }
    if ($zonematch.length -lt 2) {
        Write-Error "Unable to find reverse lookup zone to match "
    }
    $x = $zonematch.TrimEnd('.') -split '\.'
    [array]::Reverse($x)
    $reverseZoneName = "{0}.in-addr.arpa" -f ($x -join '.')
    
    #    $PTRLastOctet = $IP.Split('.')[-1]     # repkaced by $lastoctets
        
    $PtrRecord = Get-DnsServerResourceRecord -ZoneName $reverseZoneName -RRType PTR -ComputerName $DnsServer -Name $lastoctets
    if (!$PtrRecord) {
        Write-Error "PTR record for $IP does not exist in DNS zone $reversezone."
        return
    }
    # make sure the PTR belongs to the same FQDN as was specified in the parameters for the script
    if (($PtrRecord.RecordData.PtrDomainName.TrimEnd('.')) -ne $FQDN) {
        Write-Error "The PTR record for IPv4 address '$IP' in '$reverseZoneName' is $($PtrRecord.RecordData.PtrDomainName.TrimEnd('.')) which is not the same as '$FQDN'"
        return
    }
    # ping test
    $result = Test-NetConnection -InformationLevel Quiet -ComputerName $IP -Port 53     # Why port 53? What if the machine isn't a DNS server?????
    if (!$result) {
        # what if the machine is just not online at the time?????
        Write-Host "Deleting DNS record $ARecord and PTR record $reverselookupName."
        Remove-DnsServerResourceRecord -ZoneName $Zone -Name $ARecord -RRType A -ComputerName $DnsServer -Confirm:$false -WhatIf:$WhatIf
        Remove-DnsServerResourceRecord -ZoneName $reversezonename -Name $lastoctets -RRType PTR -RecordData $FQDN -ComputerName $DnsServer -Confirm:$false -WhatIf:$WhatIf
    }
    else {
        Write-Host "The IP address $IP is alive. Please check."
    }
    
    0 comments No comments

  3. JoeyD 1 Reputation point
    2023-04-13T15:11:26.4766667+00:00

    Hi I only want to verify these checks

    1. ping if A record is online
    2. if A record exist
    3. if reverse lookup zone exist (class C is fine)
    4. check if PTR record exist I know the checks you prvided are good and comprehensive but I only need those 3
    0 comments No comments