Public/Copy-DNSServerZone.ps1

Function Copy-DNSServerZone
{
   Param (
      [Parameter(Mandatory)]$ComputerName,
      [Parameter(Mandatory)]$SrcZone,
      [Parameter(Mandatory)]$DestServer,
      [Parameter(Mandatory)]$DestZone,
      $StaleDays = 21
   )

   # Calculate the new record name under the new destination zone.
   $src = Get-DnsServerResourceRecord -ComputerName $ComputerName -ZoneName $srcZone |
   Where-Object { $_.RecordType -ne 'NS' -and $_.RecordType -ne 'SOA' } |
   Select-Object @{name = 'Name'; expression = { If ($DestZone -eq $SrcZone) { $_.HostName } Else { "$($_.HostName).$($srcZone.Replace(".$DestZone",$null))" } } }, HostName, TimeStamp, RecordData, RecordType

   # Remove any delegations to the sub zone to be copied in, otherwise there will be an error.
   # We assume that this is a child zone being copied up into a parent zone.
   If ($SrcZone -ne $DestZone)
   {
      Try
      {
         Remove-DnsServerZoneDelegation -ComputerName $DestServer -Name $DestZone -ChildZoneName $SrcZone.Replace(".$DestZone", $null) -Force -PassThru -Verbose
      }
      Catch
      {
         Write-Warning "No delegation to delete for $($SrcZone.Replace(".$DestZone",$null))."
      }
   }

   # Bug in PSv2 will run a ForEach loop when the collection is NULL
   If (!$src)
   {
      Write-Warning "No records for zone $srcZone on server $ComputerName."
   }
   Else
   {
      ForEach ($srcRec in $src)
      {

         # Echo the source record data for logging
         $srcRec

         Switch ($srcRec.RecordType)
         {

            'PTR'
            {

               If ($srcRec.TimeStamp -eq $null)
               {
                  Add-DnsServerResourceRecord -Name $srcRec.Name -Ptr -ZoneName $destZone -AllowUpdateAny -PtrDomainName $srcRec.RecordData.PtrDomainName -ComputerName $DestServer
               }
               Else
               {
                  If ((New-TimeSpan $srcRec.TimeStamp).TotalDays -gt $StaleDays)
                  {
                     Write-Warning "Skipping stale record add: $($srcRec.Name)"
                  }
                  Else
                  {
                     # Add the entry with fresh aging
                     Add-DnsServerResourceRecord -Name $srcRec.Name -Ptr -ZoneName $destZone -AllowUpdateAny -PtrDomainName $srcRec.RecordData.PtrDomainName -ComputerName $DestServer -AgeRecord
                  }
               } # End If

            }

            'A'
            {

               If ($srcRec.TimeStamp -eq $null)
               {
                  Add-DnsServerResourceRecord -Name $srcRec.Name -A -ZoneName $destZone -AllowUpdateAny -IPv4Address $srcRec.RecordData.IPv4Address -ComputerName $DestServer
               }
               Else
               {
                  If ((New-TimeSpan $srcRec.TimeStamp).TotalDays -gt $StaleDays)
                  {
                     Write-Warning "Skipping stale record add: $($srcRec.Name)"
                  }
                  Else
                  {
                     # Add the entry with fresh aging
                     Add-DnsServerResourceRecord -Name $srcRec.Name -A -ZoneName $destZone -AllowUpdateAny -IPv4Address $srcRec.RecordData.IPv4Address -ComputerName $DestServer -AgeRecord
                  }
               } # End If

            }

            'SRV'
            {

               If ($srcRec.TimeStamp -eq $null)
               {
                  Add-DnsServerResourceRecord -Name $srcRec.Name -Srv -ZoneName $destZone -AllowUpdateAny -DomainName $srcRec.RecordData.DomainName -Port $srcRec.RecordData.Port -Priority $srcRec.RecordData.Priority -Weight $srcRec.RecordData.Weight -ComputerName $DestServer
               }
               Else
               {
                  If ((New-TimeSpan $srcRec.TimeStamp).TotalDays -gt $StaleDays)
                  {
                     Write-Warning "Skipping stale record add: $($srcRec.Name)"
                  }
                  Else
                  {
                     # Add the entry with fresh aging
                     Add-DnsServerResourceRecord -Name $srcRec.Name -Srv -ZoneName $destZone -AllowUpdateAny -DomainName $srcRec.RecordData.DomainName -Port $srcRec.RecordData.Port -Priority $srcRec.RecordData.Priority -Weight $srcRec.RecordData.Weight -ComputerName $DestServer -AgeRecord
                  }
               } # End If

            }

            'CNAME'
            {

               If ($srcRec.TimeStamp -eq $null)
               {
                  Add-DnsServerResourceRecord -Name $srcRec.Name -CName -HostNameAlias $srcRec.RecordData.HostNameAlias -ZoneName $destZone -AllowUpdateAny -ComputerName $DestServer
               }
               Else
               {
                  If ((New-TimeSpan $srcRec.TimeStamp).TotalDays -gt $StaleDays)
                  {
                     Write-Warning "Skipping stale record add: $($srcRec.Name)"
                  }
                  Else
                  {
                     # Add the entry with fresh aging
                     Add-DnsServerResourceRecord -Name $srcRec.Name -CName -HostNameAlias $srcRec.RecordData.HostNameAlias -ZoneName $destZone -AllowUpdateAny -ComputerName $DestServer -AgeRecord
                  }
               } # End If

            }

            'MX'
            {

               If ($null -eq $srcRec.TimeStamp)
               {
                  Add-DnsServerResourceRecord -Name $srcRec.Name -MX -MailExchange $srcRec.RecordData.MailExchange -Preference $srcRec.RecordData.Preference -ZoneName $destZone -AllowUpdateAny -ComputerName $DestServer
               }
               Else
               {
                  If ((New-TimeSpan $srcRec.TimeStamp).TotalDays -gt $StaleDays)
                  {
                     Write-Warning "Skipping stale record add: $($srcRec.Name)"
                  }
                  Else
                  {
                     # Add the entry with fresh aging
                     Add-DnsServerResourceRecord -Name $srcRec.Name -MX -MailExchange $srcRec.RecordData.MailExchange -Preference $srcRec.RecordData.Preference -ZoneName $destZone -AllowUpdateAny -ComputerName $DestServer -AgeRecord
                  }
               } # End If

            }

         } #end Switch class

      } #end ForEach source record
   } #end If src

}