Public/Test-DNSServerScavenging.ps1

#Requires -Version 5.0
#Requires -Module ActiveDirectory
#Requires -Module DnsServer

Function Test-DNSServerScavenging
{
   Param(
      [Parameter(Position = 0, Mandatory, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
      [String]$ZoneName,
      [String]$RRType = '',
      [Nullable[TimeSpan]]$NoRefreshInterval = $null,
      [Nullable[TimeSpan]]$RefreshInterval = $null,
      [ValidateSet('NoRefresh', 'Refresh', 'Stale')]
      [String]$Type = 'Stale',
      [Parameter(Mandatory)][String]$ComputerName
   )

   Get-Process
   {
      try
      {
         # DNS records are time stamped with the date accurate to the current hour, get the current date here in the same format for calculation later
         $Now = (Get-Date(Get-Date -Format 'yyyy-MM-dd HH:00:00'))

         $Aging = Get-DnsServerZoneAging -Name $ZoneName -ComputerName $ComputerName -EA Stop
         if ($Aging.AgingEnabled -eq $false)
         {
            Write-Warning "Aging is not enabled for the zone $ZoneName, resource record timestamps will not be replicated."
         }

         if ($NoRefreshInterval -eq $null) { $NoRefreshInterval = $Aging.NoRefreshInterval }
         if ($RefreshInterval -eq $null) { $RefreshInterval = $Aging.RefreshInterval }
         if ($NoRefreshInterval.TotalHours -lt 1 -or $RefreshInterval.TotalHours -lt 1)
         {
            throw "The No-refresh and Refresh intervals must be at least 1 hour."
         }

         # stale records will be those older than the No-refresh and Refresh intervals combined
         $StaleThreshold = ($NoRefreshInterval + $RefreshInterval)

         $DnsParams = @{
            'ComputerName' = $ComputerName;
            'ZoneName'     = $ZoneName;
            'ErrorAction'  = 'Stop'
         }
         if ($RRType) { $DnsParams['RRType'] = $RRType }

         # return an array of DNS records filtered by the type requested
         switch ($Type)
         {
            'NoRefresh' { Get-DnsServerResourceRecord @DnsParams | Where-Object { $_.TimeStamp -is [DateTime] -and $_.Timestamp -ge $Now.AddHours('-' + $NoRefreshInterval.TotalHours) } }
            'Refresh' { Get-DnsServerResourceRecord @DnsParams | Where-Object { $_.TimeStamp -is [DateTime] -and $_.Timestamp -ge $Now.AddHours('-' + $StaleThreshold.TotalHours) -and $_.Timestamp -lt $Now.AddHours('-' + $NoRefreshInterval.TotalHours) } }
            'Stale' { Get-DnsServerResourceRecord @DnsParams | Where-Object { $_.TimeStamp -is [DateTime] -and $_.Timestamp -lt $Now.AddHours('-' + $StaleThreshold.TotalHours) } }
         }
      }
      catch [Microsoft.Management.Infrastructure.CimException]
      {
         # there appear to be some standard message IDs in the CimException objects
         if ($_.Exception.MessageId -eq 'WIN32 9601')
         {
            # raise a non-terminating error for an invalid zone name
            Write-Error "The DNS zone $ZoneName was not found. $($_.Exception.Message)"
         }
         elseif ($_.Exception.MessageId -eq 'WIN32 1722' -or $_.Exception.MessageId -eq 'WIN32 1753')
         {
            # raise a terminating error for an invalid computer name
            throw "Computer $ComputerName is not a DNS server or is not responding. $($_.Exception.Message)"
         }
         else
         {
            # raise a terminating error for any other CimException exceptions
            throw $_.Exception.Message
         }
      }
   }
}