My Remote Desktop Session Host build process is now pretty slick. I can easily rebuild a lot of RDSH VMs very quickly. The process basically involved powering off the existing VM, deleting both it and its Active Directory account, and provisioning a new VM. However this causes a slight issue because the AD DNS record is left behind from the old VM, with the security to update it still assigned to the old VM. This means that if I change the allocated IP address for an RDSH server as part of the rebuild, the new VM doesn’t have permission to update the DNS A and PTR records for itself (security is done by AD SID, DNS just works on names/IP addresses).
So, time to use Get-DnsServerResourceRecord and Remove-DnsServerResourceRecord.
Doing the A record is easy:
$NodeToDelete = "rdsh01" $DNSServer = "dns01.rcmtech.co.uk" $ZoneName = "rcmtech.co.uk" $NodeDNS = $null $NodeDNS = Get-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -Node $NodeToDelete -RRType A -ErrorAction SilentlyContinue if($NodeDNS -eq $null){ Write-Host "No DNS record found" } else { Remove-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -InputObject $NodeDNS -Force }
So we try and get the DNS record we’re interested in. If the record is found, we delete it. I was originally doing this not using an -ErrorAction of ”SilentlyContinue” but a “Stop”, which worked to a point but was inconsistent: If the DNS name I was trying to get had never existed (i.e. I made something up) it worked fine, but if I created an A record, ran the script to delete it, then tried the script again with the same DNS name to delete, the Get-DnsServerResourceRecord didn’t error. It didn’t return anything either, and hence why this is coded to use an if statement to check whether $NodeDNS is $null or not, rather than using a try/catch as was my original plan.
The PTR record is a little more fiddly. Now, getting PTR info via nslookup is easy:
C:\> nslookup 192.168.1.123 Server: dns01.rcmtech.co.uk Address: 192.168.1.10 Name: rdsh01.rcmtech.co.uk Address 192.168.1.123
Not so with PowerShell… You have to specify the reverse lookup zone, and also give the right bit of the IP address in the right order.
For example, I want to find the name of the machine with IP address 192.168.1.123, and let’s assume my internet class B address range is 192.168.0.0.
Get-DnsServerResourceRecord -ZoneName "168.192.in-addr.arpa" -ComputerName "dns01.rcmtech.co.uk" -Node "123.1" -RRtype Ptr
…nice. You can’t just pass it the full IP address as you can with nslookup. Oh no, we have to be a little more “creative”.
What I’ve ended up doing is using Get-DnsServerResourceRecord to look up the A record of the server to get its IP address, split this into an array – each element containing an octet of the address, then delete the PTR record and finally the A record.
param($NodeToDelete= "") if($NodeToDelete-eq ""){ Write-Error "You need to specify a name to delete" -Category NotSpecified -CategoryReason "Need a name to delete" -CategoryTargetName "Missing parameter" -CategoryTargetType "DNS name" return } $DNSServer = "dns01.rcmtech.co.uk" $ZoneName = "rcmtech.co.uk" $ReverseZoneName = "168.192.in-addr.arpa" $NodeARecord = $null $NodePTRRecord = $null Write-Host "Check for existing DNS record(s)" $NodeARecord = Get-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -Node $NodeToDelete-RRType A -ErrorAction SilentlyContinue if($NodeARecord -eq $null){ Write-Host "No A record found" } else { $IPAddress = $NodeARecord.RecordData.IPv4Address.IPAddressToString $IPAddressArray = $IPAddress.Split(".") $IPAddressFormatted = ($IPAddressArray[3]+"."+$IPAddressArray[2]) $NodePTRRecord = Get-DnsServerResourceRecord -ZoneName $ReverseZoneName -ComputerName $DNSServer -Node $IPAddressFormatted -RRType Ptr -ErrorAction SilentlyContinue if($NodePTRRecord -eq $null){ Write-Host "No PTR record found" } else { Remove-DnsServerResourceRecord -ZoneName $ReverseZoneName -ComputerName $DNSServer -InputObject $NodePTRRecord -Force Write-Host ("PTR gone: "+$IPAddressFormatted) } Remove-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $DNSServer -InputObject $NodeARecord -Force Write-Host ("A gone: "+$NodeARecord.HostName) }
