I think I’ve identified the bug in PowerShell’s handling of NAPTR records.

Bug #1: All NAPTR records at a label are deleted, even if you specify one.

How to reproduce:

  1. Manually create 2 or more NAPTR records using the gui.
  2. Use PowerShell to single out one record and delete it.
  3. Desired result: The specific record is removed.
  4. Actual result: All NAPTR records at that label are removed.

Proof:

Step 1: Manually create 2 or more NAPTR records for label “foo”.

I did this in the GUI. Here’s the result:

1
2
3
4
5
6
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR

HostName                  RecordType Type       Timestamp            TimeToLive      RecordData
--------                  ---------- ----       ---------            ----------      ----------
foo                       NAPTR      35         0                    01:00:00
foo                       NAPTR      35         0                    01:00:00

I can also should you the two records this way:

1
2
3
4
5
> $OldObj = Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType naptr
> $OldObj[0].RecordData.Data
010001000155036F6E65036F6E6500
> $OldObj[1].RecordData.Data
0200020001550374776F0374776F00

Step 2: Select 1 record:

1
2
3
4
5
6
7
8
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR | 
    Where-Object { 
        $PSItem.HostName -eq "foo" -and $PSItem.RecordData.Data -eq "0200020001550374776F0374776F00"
    }  | Select-Object -First 1

HostName                  RecordType Type       Timestamp            TimeToLive      RecordData
--------                  ---------- ----       ---------            ----------      ----------
foo                       NAPTR      35         0                    01:00:00

Step 2 (continued): Remove that record:

NB: The first 2 commands didn’t work, but I’m including them because they’re interesting for other reasons.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR | Where-Object { $PSItem.HostName -eq "foo" -and $PSItem.RecordData.Data -eq "0200020001550374776F0374776F00" }  | Select-Object -First 1 | Remove-DnsServerResourceRecord -WhatIf
Remove-DnsServerResourceRecord: The input object cannot be bound because it did not contain the information required to bind all mandatory parameters:  ZoneName
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR | Where-Object { $PSItem.HostName -eq "foo" -and $PSItem.RecordData.Data -eq "0200020001550374776F0374776F00" }  | Select-Object -First 1 | Remove-DnsServerResourceRecord -WhatIf -Name "foo" -ZoneName "example.com"
What if: Removing DNS resource record set by name foo of type NAPTR from zone example.com on TOMDEV server.
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR | Where-Object { $PSItem.HostName -eq "foo" -and $PSItem.RecordData.Data -eq "0200020001550374776F0374776F00" }  | Select-Object -First 1 | Remove-DnsServerResourceRecord -Name "foo" -ZoneName "example.com"

Confirm
Removing DNS resource record set by name foo of type NAPTR from zone example.com on TOMDEV server. Do you want to
continue?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y

Ah ha! It worked… but if you notice, the prompt mentions a “record set by name foo of type NAPTR”. A record set is multiple records, not one!

1
2
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -RRType NAPTR
>

As you can see, all the NAPTR records were deleted. Not just one.


Here’s the same thing with A records. In this case, things work as expected.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo"

HostName                  RecordType Type       Timestamp            TimeToLive      RecordData
--------                  ---------- ----       ---------            ----------      ----------
foo                       A          1          0                    01:00:00        1.2.3.4
foo                       A          1          0                    01:00:00        4.5.6.7

> Remove-DnsServerResourceRecord -ZoneName "example.com" -Name "foo" -rrtype "A" -RecordData "1.2.3.4"

Confirm
Removing DNS resource record foo of type A from zone example.com on TOMDEV server. Do you want to continue?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y
> Get-DnsServerResourceRecord -ZoneName "example.com" -Name "foo"

HostName                  RecordType Type       Timestamp            TimeToLive      RecordData
--------                  ---------- ----       ---------            ----------      ----------
foo                       A          1          0                    01:00:00        4.5.6.7

As you can see, we were able to delete a single record.


Here’s other things that don’t work:

You can’t specify the -RecordData flag on Remove-DnsServerResourceRecord:

1
2
3
4
5
6
7
8
> Remove-DnsServerResourceRecord -WhatIf -ZoneName "example.com" -Name "testrec" -rrtype "NAPTR" -RecordData 1,1,"U","one","one",""
Remove-DnsServerResourceRecord: Cannot validate argument on parameter 'RecordData'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.
> Remove-DnsServerResourceRecord -WhatIf -ZoneName "example.com" -Name "testrec" -rrtype "NAPTR" -RecordData 1,1,"U","one","one"
Remove-DnsServerResourceRecord: InputObject for resource record has an invalid value. Failed to remove the resource record on TOMDEV server. Please check extended error for additional details.
> Remove-DnsServerResourceRecord -WhatIf -ZoneName "example.com" -Name "testrec" -rrtype "NAPTR" -RecordData "1","1","U","one","one"
Remove-DnsServerResourceRecord: InputObject for resource record has an invalid value. Failed to remove the resource record on TOMDEV server. Please check extended error for additional details.
> Remove-DnsServerResourceRecord -WhatIf -ZoneName "example.com" -Name "testrec" -rrtype "NAPTR" -RecordData "1","1","U","one","one",""
Remove-DnsServerResourceRecord: Cannot validate argument on parameter 'RecordData'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command again.

You can’t create an NAPTR record from PowerShell:

1
2
> Add-DnsServerResourceRecord -ZoneName "example.com" -Name "testrec" -NAPTR
Add-DnsServerResourceRecord: A parameter cannot be found that matches parameter name 'NAPTR'.

The bottom line is we’re trying to do the following 3 tasks and have not found a way to do them in PowerShell:

  1. Create an NAPTR record using PowerShell.
  2. Remove a single NAPTR record using PowerShell (there may be multiple NAPTR records on a label. Deleteing them all works; deleting just one doesn’t.)
  3. Get an NAPTR record (workaround: combine Get-DnsServerResourceRecord with Where-Object)