Public/New-DNSServerMissingReverseZones.ps1

Function New-DNSServerMissingReverseZones
{
   Set-StrictMode -Version Latest

   #force on
   $PSDefaultParameterValues = @{"*:Verbose" = $True }
   $ErrorActionPreference = 'SilentlyContinue'
   $ConfirmPreference = "High"

   #needs to run from an elevated PowerShell session
   $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent() )

   If ($currentPrincipal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ))
   {
      Write-Verbose "$(Get-Date): This is an elevated PowerShell session"
   }
   Else
   {
      Write-Error "
    `n`n
    `t`t
    This is NOT an elevated PowerShell session.
    `n`n
    `t`t
    Script will exit.
    `n`n
    "

      Exit
   }

   $Script:pwdpath = $pwd.Path

   If ($Script:pwdpath.EndsWith("\"))
   {
      #remove the trailing \
      $Script:pwdpath = $Script:pwdpath.SubString(0, ($Script:pwdpath.Length - 1))
   }


   region script start function
   Function ProcessScriptSetup
   {
      $script:startTime = Get-Date
      [string]$Script:RunningOS = (Get-WmiObject -class Win32_OperatingSystem -EA 0).Caption

      #find PDCe DC
      $Script:ServerName = (Get-ADDomain -EA 0).PDCEmulator

      If ($null -eq $Script:ServerName -or $Script:ServerName -eq "")
      {
         Write-Error "
        `n`n
        `t`t
        Unable to find the PDCe Domain Controller.
        `n`n
        `t`t
        Script cannot continue.
        `n`n
        "

      }

      Write-Verbose "$(Get-Date): Will use Domain Controller $Script:ServerName"

      $Script:Title = "Update Reverse Zones from Subnets_$(Get-Date -f yyyy-MM-dd_HHmm)"
   }
   #endregion

   #region process subnets
   Function ProcessSubnets
   {
      $Results = Get-ADReplicationSubnet -Filter * -Server $Script:ServerName -EA 0

      If (!$?)
      {
         Write-Warning "Unable to retrieve AD Sites & Service Subnets"
      }
      ElseIf ($? -and $Null -eq $Results)
      {
         Write-Warning "There were no AD Sites & Service Subnets found"
      }
      Else
      {
         $Subnets = @(Get-ADReplicationSubnet -Filter * -Server $Script:ServerName -EA 0).name

         $DNSResults = New-Object System.Collections.ArrayList

         If ($WhatIfPreference)
         {
            $null = $DNSResults.Add("WhatIf Enabled for this script run. No changes made.")
            $null = $DNSResults.Add("")
         }

         $cnt = 1
         If ($Subnets -is [array])
         {
            $cnt = $Subnets.Count
         }

         $Subnets = $Subnets | Sort-Object

         Write-Verbose "$(Get-Date): Successfully retrieved $cnt AD Sites & Service Subnets"
         Write-Verbose "$(Get-Date): "

         ForEach ($Subnet in $Subnets)
         {
            Write-Verbose "$(Get-Date): Processing subnet $Subnet"

            $null = $DNSResults.Add("Processing subnet $Subnet.")

            $SubnetArray = $Subnet.split("./")
            $SubnetMask = [int]$SubnetArray[($SubnetArray.count - 1)]

            If ($SubnetMask -le 8)
            {
               $RevZone = "$($SubnetArray[0]).in-addr.arpa"
            }
            ElseIf ($SubnetMask -le 16)
            {
               $RevZone = "$($SubnetArray[1]).$($SubnetArray[0]).in-addr.arpa"
            }
            ElseIf ($SubnetMask -le 24)
            {
               $RevZone = "$($SubnetArray[2]).$($SubnetArray[1]).$($SubnetArray[0]).in-addr.arpa"
            }
            Else
            {
               $RevZone = "$($SubnetArray[3]).$($SubnetArray[2]).$($SubnetArray[1]).$($SubnetArray[0]).in-addr.arpa"
            }

            Write-Verbose "$(Get-Date): `tSearch for Reverse Lookup Zone $RevZone"
            $null = $DNSResults.Add("`tSearch for Reverse Lookup Zone $RevZone.")

            $Results = Get-DnsServerZone -Name $RevZone -ComputerName $Script:ServerName -EA 0

            If ($? -and $null -ne $results)
            {
               Write-Verbose "$(Get-Date): `t`t$RevZone was found, nothing to do."
               $null = $DNSResults.Add("`t`t$RevZone was found, nothing to do.")
            }
            Else
            {
               Write-Verbose "$(Get-Date): `t`t$RevZone was not found. Attempt to create it."
               $null = $DNSResults.Add("`t`t$RevZone was not found. Attempt to create it.")

               If ($PSCmdlet.ShouldProcess($Subnet, 'Create Reverse Lookup Zone'))
               {
                  Try
                  {
                     $Results = Add-DnsServerPrimaryZone -NetworkId $Subnet -ReplicationScope "Domain" -DynamicUpdate "Secure" -ComputerName $Script:ServerName -PassThru -EA 0 *>$Null

                     Write-Verbose "$(Get-Date): `t`t`tSuccessfully created Reverse Lookup Zone $RevZone for subnet $Subnet"
                     $null = $DNSResults.Add("`t`t`tSuccessfully created Reverse Lookup Zone $RevZone for subnet $Subnet.")
                  }

                  Catch
                  {
                     Write-Warning "`t`t`tFailed to create Reverse Lookup Zone $RevZone for subnet $Subnet"
                     $null = $DNSResults.Add("`t`t`tFailed to create Reverse Lookup Zone $RevZone for subnet $Subnet.")
                  }
               }
               Else
               {
                  If ($WhatIfPreference)
                  {
                     $null = $DNSResults.Add("`t`t`tWhatIf used so no creating Reverse Lookup Zone $RevZone for subnet $Subnet.")
                  }
                  Else
                  {
                     #negative response to confirm
                     $null = $DNSResults.Add("`t`t`tAnswered NO to Confirm prompt for creating Reverse Lookup Zone $RevZone for subnet $Subnet.")
                  }
               }
            }
         }

         $File = Join-Path $Script:pwdpath "UpdateReverseZonesFromSubnetsScriptResults_$(Get-Date -f yyyy-MM-dd_HHmm).txt"
         $DNSResults | Out-File -FilePath $File -Force -WhatIf:$False *>$Null
         Write-Verbose "$(Get-Date): "
         Write-Verbose "$(Get-Date): $File is ready for use"
         Write-Verbose "$(Get-Date): "
      }
   }
   #cleanup obj variables
   $Script:Output = $Null
   $runtime = $Null
   $Str = $Null
}