locked
Remove Old Name Servers from reverse lookup zones in DNS- PowerShell RRS feed

  • Question

  • Hello Scripting Guys,

    I'm a long-time fan. Please let me know if I have included enough information for you to provide some guidance. Thank you!

    Here is what I am attempting to do:

    import a .csv file which contains zoneName,hostname,RecordType and then delete the name server entries from the reverse lookup zones.

    Why:

    There are hundreds of zones and 80+ name servers in each for a total of about 25,000 records to be removed. I have the list of zones and the list of name servers which I want to remove from the zones.

    Environment:

    I am running PowerShell as a Domain Admin with access to DNS. Zones allow secure updates only (if that matters here). I am running it from a Server 2012 R2 server with the DNS admin tools installed against Server 2008 R2 DNS servers. Current AD functional level Windows Server 2003. All DC are DNS server and GC's.

    What I have tried:

    The following works to return all the Name Server records in a zone:

    .csv file format

    zoneName,hostname,RecordType
    1.112.170.in-addr.arpa,nameserver1.contoso.com.,Ns
    1.112.170.in-addr.arpa,nameserver2.contoso.com.,Ns
    1.112.170.in-addr.arpa,nameserver3.contoso.com.,Ns
    2.112.170.in-addr.arpa,nameserver1.contoso.com.,Ns
    2.112.170.in-addr.arpa,nameserver2.contoso.com.,Ns
    2.112.170.in-addr.arpa,nameserver3.contoso.com.,Ns

    Script\Command:

    Import-Module DnsServer

    $PDCE = Get-ADDomainController -Discover -Service PrimaryDC

    import-csv c:\temp\OldNSrecords-test.csv | foreach {

    Get-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -computerName $PDCE -Node

    }

    OutPut to screen:

    HostName RecordType Timestamp TimeToLive RecordData
    -------- ---------- --------- ---------- ----------
    @ NS 0 1:00:00 Nameserver1.contoso.com
    @ NS 0 1:00:00 Nameserver2.contoso.com

    However, replacing the business line (in green above after foreach) with the remove command (in red below) does not work to delete the specific record listed in the .csv, even though it follows the pattern from MS TechNet:

    Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -name $_.hostname -computerName $PDCE

    Error:

    PS C:\Windows\system32> C:\Temp\OldNSCleanup.ps1
    Remove-DnsServerResourceRecord : Failed to get nameserver1.contoso.com. record in
    1.112.170.in-addr.arpa zone on PDCE server.
    At C:\Temp\OldNSCleanup.ps1:4 char:1
    + Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -name $_.name ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (PDCE:root/Microsoft/...rResourceRecord) [Remove-
    DnsServerResourceRecord], CimException
    + FullyQualifiedErrorId : WIN32 9714,Remove-DnsServerResourceRecord​

    When I remove the use of the .csv and put the names of the zone and server in the command, I get the same results. Fail.

    It's as if the record does not exist, but I can browse to it in the GUI. I found this about Missing Glue records, but it does not seem to apply to reverse lookup NS records. I'm thinking that I need to first load each zone into an assembly and then do the removal, but I'm not sure how to do that in PowerShell. I tried piping the get command for the zone to the remove command, but that did not work or I did not have the correct syntax.

    I have attempted to use DNSCMD to do the same and that command appears to work, but then fails to actually remove the record.

    Here is an example of that command:

    import-csv C:\Temp\OldNSrecords-test.csv | foreach {dnscmd.exe "DNSServer.contoso.com" /Recorddelete $_.ZoneName $_.hostname $_.recordType /f}

    Output:

    Deleted Ns record(s) at 1.112.170.in-addr.arpa
    Command completed successfully. [But not really, the NS record is still there]

    I have researched several sites including the suggest one here, but this does not fit my requirement.

    http://social.technet.microsoft.com/Forums/scriptcenter/en-US/97070ff2-59e2-4f34-9c39-054048e008af/automatically-delete-removed-dcname-servers-and-automatically-add-new-dcname-servers-in-reverse?forum=winserverDS

    http://technet.microsoft.com/en-us/library/jj649872.aspx




    Thursday, May 8, 2014 3:42 PM

Answers

  • The issue is that “name” is usually “(same as parent folder)”… apparently the “@” matches on that. Or as "jrv" mentioned it's a "self reference". What you want to match on is –RecordData …  I noticed the “@” for the –Name parameter here: http://cbfive.com/blog/tag/remove-dnsserverresourcerecord/

     

    So, this should work…

     

    Import-Module DnsServer

    $PDCE = Get-ADDomainController -Discover -Service PrimaryDC

    import-csv c:\temp\OldNSrecords-test.csv | foreach { 

    $zone = Get-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -computerName $PDCE.HostName -Node

        ForEach-Object {Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" –Name “@” -RecordData $_.name -computerName $PDCE}

    • Marked as answer by DownTown-MTB Thursday, May 8, 2014 7:35 PM
    Thursday, May 8, 2014 7:26 PM

All replies

  • What is in the variable?

     $_.hostname


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 5:50 PM
  • $_.hostname is the FQDN of the old Name Server which I would like to remove, for example nameserver1.contoso.com. in the case of my example .csv
    Thursday, May 8, 2014 6:19 PM
  • Look at this:

    HostName RecordType Timestamp TimeToLive RecordData
    -------- ---------- --------- ---------- ----------
    @ NS 0 1:00:00 Nameserver1.contoso.com
    @ NS 0 1:00:00 Nameserver2.contoso.com

    Hostname is '@'
    RecordType is NS
    ....
    RecordData is 'Nameserver1.contoso.com'

    I think this is closer to what you want:

    Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType $_.RecordType -name $_.HostName -computerName $PDCE

    Host name refers to the allocated name of the record.  '@' is self reference.

    The recordtype will not all be NS.  They could be AType or AAType.  NS is only name server records.


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 6:36 PM
  • You cannot get what doesn't exist:

    CategoryInfo          : ObjectNotFound: (sevmmaster01.dorseylaw.corp.:root/Microsoft

    Object not found means there is no such object.  The zone was found. No record with that identity of that type was found.

    This is my guess as to your problem: RRType "Ns"

    Why do you expect every record to be an NS record?


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 7:07 PM
  • The issue is that “name” is usually “(same as parent folder)”… apparently the “@” matches on that. Or as "jrv" mentioned it's a "self reference". What you want to match on is –RecordData …  I noticed the “@” for the –Name parameter here: http://cbfive.com/blog/tag/remove-dnsserverresourcerecord/

     

    So, this should work…

     

    Import-Module DnsServer

    $PDCE = Get-ADDomainController -Discover -Service PrimaryDC

    import-csv c:\temp\OldNSrecords-test.csv | foreach { 

    $zone = Get-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -computerName $PDCE.HostName -Node

        ForEach-Object {Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" –Name “@” -RecordData $_.name -computerName $PDCE}

    • Marked as answer by DownTown-MTB Thursday, May 8, 2014 7:35 PM
    Thursday, May 8, 2014 7:26 PM
  • No. Name I snot Recorddata. It is the reference.   With NS it is the FQDN of a name server.  For an AType it is the IP of the host. For a TXTType it is the multiline text data.  For a CNAME it is the FQDN being 'aliased'.

    If you look in the backup file or the text files used to store non-AD zones you will see the same layout.


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 7:53 PM
  • Here is a backing store for the root servers in the DNS format:

    ; formerly NS.INTERNIC.NET
    ;
    .                        3600000  IN  NS    A.ROOT-SERVERS.NET.
    A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
    ;
    ; formerly NS1.ISI.EDU
    ;
    .                        3600000      NS    B.ROOT-SERVERS.NET.
    B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
    ;
    ; formerly C.PSI.NET
    ;
    .                        3600000      NS    C.ROOT-SERVERS.NET.
    C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
    ;
    ; formerly TERP.UMD.EDU
    ;
    .                        3600000      NS    D.ROOT-SERVERS.NET.
    D.ROOT-SERVERS.NET.      3600000      A     128.8.10.90
    ;
    ; formerly NS.NASA.GOV
    ;
    .                        3600000      NS    E.ROOT-SERVERS.NET.
    E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
    ;
    ; formerly NS.ISC.ORG
    ;
    .                        3600000      NS    F.ROOT-SERVERS.NET.
    F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
    ;
    ; formerly NS.NIC.DDN.MIL
    ;
    .                        3600000      NS    G.ROOT-SERVERS.NET.
    G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
    ;
    ; formerly AOS.ARL.ARMY.MIL
    ;
    .                        3600000      NS    H.ROOT-SERVERS.NE

    Notice that each is a pair.

    One is the NS and the secon is the A record.

    .                        3600000      NS    G.ROOT-SERVERS.NET.
    G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4

    In this case the dot represents the self reference to the A record.  These are the records that bootstrap all of the Internet.  Remove them and you ae lost.

    The CSV uses the @ to anchor the local domain.  Perhaps the DNS CmdLets prefer the dot.  The @ is what appears on the screen when we use the GUI. Note the dot at the end of the FQDN.  It is required.  Even browser use it but they add it if you forget.


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 8:02 PM
  • So when in doubt read the instructions.  Guessing is to much work:

    -RRType<String>

    Specifies the type of resource record.

    The acceptable values for this parameter are: 
    -- HInfo
    -- Afsdb
    -- Atma
    -- Isdn
    -- Key
    -- Mb
    -- Md
    -- Mf
    -- Mg
    -- MInfo
    -- Mr
    -- Mx
    -- NsNxt
    -- Rp
    -- Rt
    -- Wks
    -- X25
    -- A
    -- AAAA
    -- CName
    -- Ptr
    -- Srv
    -- Txt
    -- Wins
    -- WinsR
    -- Ns
    -- Soa
    -- NasP
    -- NasPtr
    -- DName
    -- Gpos
    -- Loc
    -- DhcId
    -- Naptr
    -- RRSig
    -- DnsKey
    -- DS
    -- NSec
    -- NSec3
    -- NSec3Param


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 8:05 PM
  • Now we discover another little truth:

    -ZoneName<String>

    Specifies the name of a DNS zone.

    Aliases

    ForwardLookupZone

    Note that it specifically states "ForwardLookupZone"

    You are using reverse lookup zones.

    1.112.170.in-addr.arpa,nameserver1.contoso.com.,Ns

    This should be:

    PS C:\> Remove-DnsServerResourceRecord -ZoneName "contoso.com" -RRType "A" -Name "nameserver1" -RecordData "112.170.112.1.??"


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 8:15 PM
  • The issue is that “name” is usually “(same as parent folder)”… apparently the “@” matches on that. Or as "jrv" mentioned it's a "self reference". What you want to match on is –RecordData …  I noticed the “@” for the –Name parameter here: http://cbfive.com/blog/tag/remove-dnsserverresourcerecord/

     

    So, this should work…

     

    Import-Module DnsServer

    $PDCE = Get-ADDomainController -Discover -Service PrimaryDC

    import-csv c:\temp\OldNSrecords-test.csv | foreach { 

    $zone = Get-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" -computerName $PDCE.HostName -Node

        ForEach-Object {Remove-DnsServerResourceRecord -ZoneName $_.zoneName -RRType "Ns" –Name “@” -RecordData $_.name -computerName $PDCE}

    That Is pretty much what I posted at the same time.  I didn't see yours because the server is slow updating to day.

    Yes - That is what we were trying to get across.  Your CSV file needs a little fixing before it will work.

    G.L.


    ¯\_(ツ)_/¯

    Thursday, May 8, 2014 8:17 PM