SyntaxHighlighter.config.bloggerMode=true; SyntaxHighlighter.all();
Showing posts with label Scripting. Show all posts
Showing posts with label Scripting. Show all posts

Monday, February 9, 2015

DNS Scavenging using Powershell

Solving a potential DNS Scavenging Mess!
I used to work for a company that had a very large AD-Integrated DNS zone with more than 100,000 A records in it. We, the Engineering team, decided to enable DNS Scavenging in the zone to delete the stale records. In other words, records that for one reason or another, would not update themselves and the Timestamp was already older than what we wanted. We had a very mixed environment with mostly 65% of the computers were Macs and over 100 Linux servers. Although those machines were bound to the domain and were always connected to the network, many would still fail to update the records in DNS. This behavior caused an issue where the automatic Windows DNS Scavenging deleted legit records of our Linux servers and it caused and great problem. (Thank God for backups!).

I decided to come up with a workaround... Instead of using the default DNS Scavenging provided in DNS manager, I decided to write a Powershell script that would get the stale records from the zone and match them with the computer object in AD. Then use, the OperatingSystem field value of that computer object to decide whether I would delete the A record or not. In the end, you can have the script send you an email with the report so you can have a Windows scheduled task do that for you every Saturday or so!

Below is the code:

<#
Written by Mr. Hiraldo - Tips4teks.blogspot.com.
This script is provided AS IS and I am not responsible for any damages caused. Removing DNS records could be a problem on your network. Contact your administrator and REALLY think this through before using it.
#>
Import-Module activedirectory
#Change value DeletingEnabled to $true if you want to delete the Stale DNS Records
$DeletingEnabled = $true
Function DeleteDNSRecord($Record)
{
    $Owner = $Record.OwnerName
    $IPAddress = $Record.IPAddress

    Write-host "Deleting $Owner $IPAddress"
    Get-WmiObject -Computer $ServerName -Namespace "root\MicrosoftDNS" -Class "MicrosoftDNS_AType" -Filter "IPAddress = '$IPAddress' AND OwnerName = '$Owner'" | Remove-WmiObject
    if($?)
    {
        return "Yes"
    }
    else
    {
        return "No"
    }
}

#The variable Pathdir is used for logging later. Configure to whatever folder you'd like.
$Pathdir = "C:\Scripts\DNSScavenging"
$reportObject = @()
$NotInAD = @()
$TotalAgingInterval = 14 #It will delete records older than what specified here.
$Date = get-date -format 'yyyy.MM.dd'
$ServerName = "DC1.tips4teks.net" #Choose your DNS server here.
$ContainerName = "tips4teks.net"
$DomainZone = "DomainDNSZones." + $ContainerName

$MinTimeStamp = [Int](New-TimeSpan `
  -Start $(Get-Date("01/01/1601 00:00")) `
  -End $((Get-Date).AddDays(-$TotalAgingInterval))).TotalHours
Write-Host "Gathering DNS A Records... Please wait" -ForegroundColor Yellow
Get-WMIObject -Computer $ServerName `
  -Namespace "root\MicrosoftDNS" -Class "MicrosoftDNS_AType" `
  -Filter `
  "ContainerName='$ContainerName' AND TimeStamp<$MinTimeStamp AND TimeStamp<>0" `
 | Select-Object OwnerName, `
  @{n="TimeStamp";e={(Get-Date("01/01/1601")).AddHours($_.TimeStamp)}}, IPAddress, TTL | Export-csv -path "$Pathdir\AllStaleDNSRecords.csv"
Write-Host "Gathering DNS A Records completed!" -ForegroundColor Green
Write-Host "Searching DNS A Records in AD... Please wait" -ForegroundColor Yellow
  $DNSRecords = Import-Csv -Path "$Pathdir\AllStaleDNSRecords.csv"
  foreach ($Record in $DNSRecords)
  {
      if (($Record.OwnerName -ne $ContainerName)-and ($Record.OwnerName -ne $DomainZone))
      {
          $hostname = $Record.OwnerName
          $IPAddress = $Record.IPAddress
          $ADObject = Get-ADComputer -filter {(DNSHostName -like $hostname)} -Properties OperatingSystem, DistinguishedName
          if($ADObject -ne $null)
          {
              if(($ADObject.OperatingSystem -ne $null) -and (($ADObject.Operatingsystem -like "*Windows XP*") -or ($ADObject.OperatingSystem -like "*Windows 7*") -or ($ADObject.OperatingSystem -like "*Windows 8*") -or ($ADObject.OperatingSystem -like "Mac OS X")))
              {
                  $output = "" | Select DNSOwnerName, ADName,OperatingSystem, IPAddress, TTL, TimeStamp, Deleted, DistinguishedName
                  $output.DNSOwnerName = $hostname
                  $output.ADName = $ADObject.Name
                  $output.OperatingSystem = $ADObject.OperatingSystem
                  $output.IPAddress = $IPAddress
                  $output.TTL = $Record.TTL
                  $output.TimeStamp = $Record.TimeStamp
                  $output.DistinguishedName = $ADObject.DistinguishedName              
                  if ($DeletingEnabled -eq $true)
                  {
                    $output.Deleted = DeleteDNSRecord($Record)
                  }
                  else
                  {
                    $output.Deleted = "Deleting Not Enabled"
                  }
               
                  $reportObject += $output

              }
           

          }
          else
              {
                Write-Host "Record doesn't exist in AD and will be deleted." $hostname
                $Erroutput = "" | Select DNSOwnerName, IPAddress, TTL, TimeStamp, Deleted
                $Erroutput.DNSOwnerName = $Record.OwnerName
                $Erroutput.IPAddress = $Record.IPAddress
                $Erroutput.TTL = $Record.TTL
                $Erroutput.TimeStamp = $Record.TimeStamp
                if ($DeletingEnabled -eq $true)
                {
                    $Erroutput.Deleted = DeleteDNSRecord($Record)
                }
                else
                {
                    $Erroutput.Deleted = "Deleting Not Enabled"
                }
   
                $NotInAD += $Erroutput
              }

      }

  }
  Write-Host "Scavenging Maintenance Complete! Exporting to CSV.." -ForegroundColor Green
  $reportObject | Export-csv -path "$Pathdir\DNSRecords-to-delete-with-ADinfo-$Date.csv"
  $NotInAD | Export-csv -path "$Pathdir\DNSRecords-NotInAD-Deleted-$Date.csv"

$to = "MrHiraldo@tips4teks.net"
$Subject = "DNS Scavenging Report for $Date"
$Body = "Hello Team,`nThe following reports attached show the DNS records scanvenged from zone $ContainerName"
$Relay = "relay.tips4teks.net"
$From = "DNSScavenging@tips4teks.net"
$Attach = "$Pathdir\DNSRecords-to-delete-with-ADinfo-$Date.csv", "$Pathdir\DNSRecords-NotInAD-Deleted-$Date.csv"
#Send the Email and attachment
Send-MailMessage -to $to -Subject $Subject -Body $Body -SmtpServer $Relay -Attachments $Attach -From $From

Tuesday, June 25, 2013

Recently, I was in the need to change the description on multiple Active Directory accounts that I had exported from an OU to CSV. They were over 500 so doing it one by one would have been a time consuming task. That's when I decided to do a simple by working script to accomplish this task.

I'm using Powershell but you can other languages such as VBS. I prefer Powershell because it's more robust yet simpler to use and understand and it's the future of Windows Scripting.


Here's the script:

##############################################################
# Change-Description-To-Users.ps1                                                                 #
# Created by tips4teks.blogspot.com                                                                #
# This script changes the description of AD accounts to whatever is specified # 
##############################################################

Import-module ActiveDirectory
#Declare the path to the CSV file where you have the accounts by Distinguished Name. 
#The first row of the column should be named "DistinguishedName" without quotes.
$CSV='C:\users-to-edit.csv'

#Declare the new description that will be applied to all the accounts in the CSV file.
$Description='Account Disabled by tips4teks.blogspot.com'

#Read the CSV file and change the description to each user object based on the parameters specified.
import-csv -path $CSV | foreach-object { Set-ADUser -identity $_.DistinguishedName -Description $Description}
Content belongs to Tips4teks.blogspot.com. All Rights Reserved. Powered by Blogger.