DNS yönetimi, sistem yöneticilerinin günlük hayatında en sık karşılaştığı konulardan biri. Bir servis çalışmıyor, kullanıcılar bağlanamıyor, yeni bir sunucu devreye aldınız – hepsinin temelinde DNS var. PowerShell, Windows ortamında DNS sorgulama ve yönetimi için inanılmaz güçlü araçlar sunuyor. Hem hızlı troubleshooting hem de otomasyon senaryoları için bu araçları iyi bilmek, sizi ortalama bir sysadmin’den ayıran şeylerden biri.
Bu yazıda temel DNS sorgularından başlayıp, DNS sunucu yönetimine, toplu işlemlere ve gerçek dünya senaryolarına kadar her şeyi ele alacağız.
Temel DNS Sorgulama: Resolve-DnsName
PowerShell’de DNS sorgulamanın ana komutu Resolve-DnsName‘dir. Eski okul sysadminlerin nslookup’tan bildiği her şeyi yapıyor, üstüne de PowerShell’in tüm gücünü getiriyor.
# Basit A kaydı sorgusu
Resolve-DnsName -Name "www.example.com"
# Belirli bir DNS sunucusuna sorgu gönder
Resolve-DnsName -Name "www.example.com" -Server "8.8.8.8"
# Farklı kayıt tiplerini sorgula
Resolve-DnsName -Name "example.com" -Type MX
Resolve-DnsName -Name "example.com" -Type TXT
Resolve-DnsName -Name "example.com" -Type NS
Resolve-DnsName -Name "example.com" -Type SOA
# Ters DNS sorgusu (PTR)
Resolve-DnsName -Name "8.8.8.8" -Type PTR
Komutun temel parametreleri şunlar:
- -Name: Sorgulanacak hostname veya IP adresi
- -Type: DNS kayıt tipi (A, AAAA, MX, TXT, NS, SOA, PTR, CNAME, SRV)
- -Server: Kullanılacak DNS sunucusu IP’si veya hostname’i
- -DnsOnly: Yalnızca DNS üzerinden sorgula, hosts dosyasını yok say
- -NoHostsFile: Hosts dosyasını atlayarak direkt DNS’e git
- -TcpOnly: UDP yerine TCP kullanarak sorgula (büyük yanıtlar için)
Şimdi biraz daha işe yarar bir senaryo düşünelim. Sabah işe geldiniz, bir uygulama ekibi “bizim servis çalışmıyor” diye üstünüze çullanıyor. İlk adım DNS’i kontrol etmek:
# Kapsamlı DNS troubleshooting sorgusu
$hostname = "app.sirket.local"
Write-Host "=== DNS Troubleshooting: $hostname ===" -ForegroundColor Cyan
# Lokal DNS sunucusundan sorgula
Write-Host "`n[Lokal DNS]" -ForegroundColor Yellow
Resolve-DnsName -Name $hostname -ErrorAction SilentlyContinue |
Select-Object Name, Type, IPAddress, NameHost
# Google DNS ile karşılaştır
Write-Host "`n[Google DNS - 8.8.8.8]" -ForegroundColor Yellow
Resolve-DnsName -Name $hostname -Server "8.8.8.8" -ErrorAction SilentlyContinue |
Select-Object Name, Type, IPAddress, NameHost
# Cloudflare DNS ile karşılaştır
Write-Host "`n[Cloudflare DNS - 1.1.1.1]" -ForegroundColor Yellow
Resolve-DnsName -Name $hostname -Server "1.1.1.1" -ErrorAction SilentlyContinue |
Select-Object Name, Type, IPAddress, NameHost
Bu script birkaç farklı DNS sunucusundan aynı sorguyu yapıyor. Eğer lokal DNS farklı bir şey dönüyorsa, orada sorun var demektir. Basit ama hayat kurtarıcı.
DNS Kayıt Tiplerini Anlamak ve Sorgulamak
Her kayıt tipinin farklı kullanım senaryosu var. Bunları tek tek ele alalım.
Mail Sunucusu (MX) Kayıtları
E-posta problemi mi var? MX kayıtlarından başlayın:
# MX kayıtlarını öncelik sırasına göre listele
$domain = "example.com"
$mxRecords = Resolve-DnsName -Name $domain -Type MX |
Sort-Object Preference
foreach ($record in $mxRecords) {
Write-Host "Öncelik: $($record.Preference) - Sunucu: $($record.NameExchange)"
# Her MX sunucusunun IP'sini de çöz
$ip = Resolve-DnsName -Name $record.NameExchange -Type A -ErrorAction SilentlyContinue
if ($ip) {
Write-Host " IP: $($ip.IPAddress)"
}
}
SPF ve DKIM Kontrolü
E-posta güvenliği için TXT kayıtlarını düzenli kontrol etmek gerekiyor:
# SPF kaydını kontrol et
$domain = "example.com"
$txtRecords = Resolve-DnsName -Name $domain -Type TXT
foreach ($record in $txtRecords) {
if ($record.Strings -like "*v=spf1*") {
Write-Host "SPF Kaydı Bulundu:" -ForegroundColor Green
Write-Host $record.Strings
}
if ($record.Strings -like "*v=DMARC1*") {
Write-Host "DMARC Kaydı Bulundu:" -ForegroundColor Green
Write-Host $record.Strings
}
}
# DKIM için selector sorgula
$selector = "default"
Resolve-DnsName -Name "$selector._domainkey.$domain" -Type TXT -ErrorAction SilentlyContinue
Windows DNS Sunucusu Yönetimi: DnsServer Modülü
Eğer bir Windows DNS sunucusu yönetiyorsanız, DnsServer modülü tam size göre. Bu modül RSAT ile birlikte geliyor ve DNS sunucusunu uzaktan yönetmenizi sağlıyor.
Önce modülün yüklü olup olmadığını kontrol edin:
# Modülü kontrol et ve yükle
if (-not (Get-Module -ListAvailable -Name DnsServer)) {
Write-Host "DnsServer modülü bulunamadı. RSAT yükleniyor..." -ForegroundColor Yellow
Add-WindowsFeature RSAT-DNS-Server
}
Import-Module DnsServer
# DNS sunucusundaki zone'ları listele
Get-DnsServerZone -ComputerName "dns-sunucu01"
# Belirli bir zone'daki tüm kayıtları getir
Get-DnsServerResourceRecord -ZoneName "sirket.local" -ComputerName "dns-sunucu01"
# Sadece A kayıtlarını getir
Get-DnsServerResourceRecord -ZoneName "sirket.local" -RRType A -ComputerName "dns-sunucu01"
Kayıt Ekleme, Güncelleme ve Silme
Günlük operasyonların belki de en sık yapılan kısmı DNS kayıtlarını yönetmek:
# Yeni A kaydı ekle
Add-DnsServerResourceRecordA `
-ZoneName "sirket.local" `
-Name "yeni-sunucu" `
-IPv4Address "192.168.1.50" `
-TimeToLive 01:00:00 `
-ComputerName "dns-sunucu01"
# CNAME kaydı ekle
Add-DnsServerResourceRecordCName `
-ZoneName "sirket.local" `
-Name "app" `
-HostNameAlias "yeni-sunucu.sirket.local" `
-ComputerName "dns-sunucu01"
# PTR kaydı ekle (ters DNS)
Add-DnsServerResourceRecordPtr `
-ZoneName "1.168.192.in-addr.arpa" `
-Name "50" `
-PtrDomainName "yeni-sunucu.sirket.local" `
-ComputerName "dns-sunucu01"
# Kaydı sil
Remove-DnsServerResourceRecord `
-ZoneName "sirket.local" `
-Name "eski-sunucu" `
-RRType A `
-RecordData "192.168.1.30" `
-ComputerName "dns-sunucu01" `
-Force
Gerçek Dünya Senaryosu 1: Toplu Sunucu DNS Kaydı Oluşturma
Yeni bir proje devreye alınıyor ve 20 yeni sanal makine oluşturuldu. Hepsinin DNS kaydını tek tek girmek yerine, bir CSV dosyasından okuyarak otomatize edelim:
# sunucular.csv formatı:
# Hostname,IP,Tip
# web-01,192.168.10.11,A
# db-01,192.168.10.20,A
# app-proxy,web-01.sirket.local,CNAME
$csvDosyasi = "C:Scriptssunucular.csv"
$zone = "sirket.local"
$dnsSunucu = "dns-sunucu01"
$logDosyasi = "C:Scriptsdns-log-$(Get-Date -Format 'yyyyMMdd').txt"
$sunucular = Import-Csv -Path $csvDosyasi
$basarili = 0
$basarisiz = 0
foreach ($sunucu in $sunucular) {
try {
# Kayıt zaten var mı kontrol et
$mevcutKayit = Get-DnsServerResourceRecord `
-ZoneName $zone `
-Name $sunucu.Hostname `
-ComputerName $dnsSunucu `
-ErrorAction SilentlyContinue
if ($mevcutKayit) {
Write-Host "UYARI: $($sunucu.Hostname) zaten mevcut, atlanıyor." -ForegroundColor Yellow
Add-Content $logDosyasi "$(Get-Date) - UYARI: $($sunucu.Hostname) zaten mevcut"
continue
}
if ($sunucu.Tip -eq "A") {
Add-DnsServerResourceRecordA `
-ZoneName $zone `
-Name $sunucu.Hostname `
-IPv4Address $sunucu.IP `
-ComputerName $dnsSunucu
}
elseif ($sunucu.Tip -eq "CNAME") {
Add-DnsServerResourceRecordCName `
-ZoneName $zone `
-Name $sunucu.Hostname `
-HostNameAlias $sunucu.IP `
-ComputerName $dnsSunucu
}
Write-Host "BASARILI: $($sunucu.Hostname) eklendi" -ForegroundColor Green
Add-Content $logDosyasi "$(Get-Date) - BASARILI: $($sunucu.Hostname) eklendi"
$basarili++
}
catch {
Write-Host "HATA: $($sunucu.Hostname) eklenemedi - $($_.Exception.Message)" -ForegroundColor Red
Add-Content $logDosyasi "$(Get-Date) - HATA: $($sunucu.Hostname) - $($_.Exception.Message)"
$basarisiz++
}
}
Write-Host "`nSonuç: $basarili başarılı, $basarisiz başarısız" -ForegroundColor Cyan
Gerçek Dünya Senaryosu 2: DNS Tutarlılık Kontrolü
Birden fazla DNS sunucunuz varsa, zone transferlerinin düzgün çalışıp çalışmadığını düzenli kontrol etmek önemli. Bu script, primary ve secondary sunucular arasındaki kayıt farklılıklarını bulur:
# DNS tutarlılık kontrolü - Primary vs Secondary
$primaryDns = "dns-primary01"
$secondaryDns = "dns-secondary01"
$zone = "sirket.local"
Write-Host "DNS Tutarlılık Kontrolü Başlıyor..." -ForegroundColor Cyan
# Primary'deki kayıtları al
$primaryKayitlar = Get-DnsServerResourceRecord `
-ZoneName $zone `
-ComputerName $primaryDns |
Where-Object { $_.RecordType -in @("A", "CNAME", "MX", "TXT") }
# Secondary'deki kayıtları al
$secondaryKayitlar = Get-DnsServerResourceRecord `
-ZoneName $zone `
-ComputerName $secondaryDns |
Where-Object { $_.RecordType -in @("A", "CNAME", "MX", "TXT") }
# Primary'de olup Secondary'de olmayan kayıtlar
$primaryde_olan = $primaryKayitlar |
Where-Object { $_.HostName -notin $secondaryKayitlar.HostName }
if ($primaryde_olan) {
Write-Host "`nSadece Primary'de olan kayıtlar:" -ForegroundColor Red
$primaryde_olan | Select-Object HostName, RecordType | Format-List
} else {
Write-Host "`nTüm kayıtlar Secondary'de mevcut." -ForegroundColor Green
}
# SOA serial numaralarını karşılaştır
$primarySOA = Get-DnsServerResourceRecord -ZoneName $zone -ComputerName $primaryDns -RRType SOA
$secondarySOA = Get-DnsServerResourceRecord -ZoneName $zone -ComputerName $secondaryDns -RRType SOA
Write-Host "`nSOA Kontrolü:" -ForegroundColor Yellow
Write-Host "Primary Serial: $($primarySOA.RecordData.SerialNumber)"
Write-Host "Secondary Serial: $($secondarySOA.RecordData.SerialNumber)"
if ($primarySOA.RecordData.SerialNumber -ne $secondarySOA.RecordData.SerialNumber) {
Write-Host "UYARI: Serial numaraları farklı! Zone transfer sorunu olabilir." -ForegroundColor Red
}
DNS Cache Yönetimi
DNS cache sorunları troubleshooting’de sıkça karşılaşılan bir durum. PowerShell ile hem istemci hem de sunucu tarafında cache yönetimi yapabilirsiniz:
# İstemci DNS cache'ini görüntüle
Get-DnsClientCache
# Belirli bir kayıt için cache kontrolü
Get-DnsClientCache | Where-Object { $_.Entry -like "*example*" }
# İstemci DNS cache'ini temizle
Clear-DnsClientCache
Write-Host "DNS cache temizlendi." -ForegroundColor Green
# DNS sunucusundaki cache'i yönet (sunucu tarafı)
# Sunucudaki tüm cache kayıtlarını görüntüle
Get-DnsServerCache -ComputerName "dns-sunucu01"
# Sunucu cache'ini temizle
Clear-DnsServerCache -ComputerName "dns-sunucu01" -Force
Write-Host "Sunucu DNS cache'i temizlendi." -ForegroundColor Green
# Belirli bir kaydı cache'den sil
Clear-DnsServerCache -ComputerName "dns-sunucu01" -Force
DNS Zone Yönetimi
Zone oluşturma ve yapılandırma işlemleri de PowerShell ile kolayca yapılabiliyor:
# Yeni primary zone oluştur
Add-DnsServerPrimaryZone `
-Name "yeniprojekt.local" `
-ReplicationScope "Forest" `
-DynamicUpdate Secure `
-ComputerName "dns-sunucu01"
# Secondary zone oluştur
Add-DnsServerSecondaryZone `
-Name "partner.local" `
-ZoneFile "partner.local.dns" `
-MasterServers "10.0.0.1" `
-ComputerName "dns-sunucu01"
# Stub zone oluştur
Add-DnsServerStubZone `
-Name "harici.local" `
-MasterServers "172.16.0.1" `
-ReplicationScope "Forest" `
-ComputerName "dns-sunucu01"
# Zone özelliklerini görüntüle
Get-DnsServerZone -Name "sirket.local" -ComputerName "dns-sunucu01" |
Select-Object ZoneName, ZoneType, DynamicUpdate, ReplicationScope, IsDsIntegrated
# Zone'u sil (dikkatli kullanın!)
# Remove-DnsServerZone -Name "eskizone.local" -ComputerName "dns-sunucu01" -Force
Monitoring ve Raporlama
DNS sağlığını izlemek için düzenli çalışan bir script hazırlamak iyi bir pratik:
# DNS Sağlık Raporu
function Get-DnsHealthReport {
param(
[string[]]$DnsSunuculari = @("dns-sunucu01", "dns-sunucu02"),
[string]$ZoneName = "sirket.local",
[string]$RaporDosyasi = "C:Raporlardns-rapor-$(Get-Date -Format 'yyyyMMdd-HHmm').html"
)
$rapor = @()
foreach ($sunucu in $DnsSunuculari) {
$sunucuRapor = [PSCustomObject]@{
Sunucu = $sunucu
Durum = "Bilinmiyor"
TotalKayit = 0
AKayit = 0
CNAMEKayit = 0
SOASerial = 0
ZoneDurumu = "Bilinmiyor"
}
try {
# Zone bilgilerini al
$zone = Get-DnsServerZone -Name $ZoneName -ComputerName $sunucu -ErrorAction Stop
$sunucuRapor.ZoneDurumu = $zone.ZoneType
# Kayıt sayılarını al
$tumKayitlar = Get-DnsServerResourceRecord -ZoneName $ZoneName -ComputerName $sunucu
$sunucuRapor.TotalKayit = $tumKayitlar.Count
$sunucuRapor.AKayit = ($tumKayitlar | Where-Object RecordType -eq "A").Count
$sunucuRapor.CNAMEKayit = ($tumKayitlar | Where-Object RecordType -eq "CNAME").Count
# SOA serial
$soa = $tumKayitlar | Where-Object RecordType -eq "SOA"
$sunucuRapor.SOASerial = $soa.RecordData.SerialNumber
$sunucuRapor.Durum = "OK"
Write-Host "$sunucu - OK" -ForegroundColor Green
}
catch {
$sunucuRapor.Durum = "HATA: $($_.Exception.Message)"
Write-Host "$sunucu - HATA" -ForegroundColor Red
}
$rapor += $sunucuRapor
}
# Sonuçları göster
$rapor | Format-List
# CSV olarak kaydet
$rapor | Export-Csv -Path ($RaporDosyasi -replace ".html$", ".csv") -NoTypeInformation -Encoding UTF8
Write-Host "`nRapor kaydedildi." -ForegroundColor Cyan
return $rapor
}
# Fonksiyonu çalıştır
Get-DnsHealthReport -DnsSunuculari @("dns-sunucu01", "dns-sunucu02") -ZoneName "sirket.local"
Forwarder Yönetimi
DNS forwarder’ları yönetmek de sık karşılaşılan bir görev:
# Mevcut forwarder'ları listele
Get-DnsServerForwarder -ComputerName "dns-sunucu01"
# Yeni forwarder ekle
Add-DnsServerForwarder -IPAddress "8.8.8.8" -ComputerName "dns-sunucu01"
Add-DnsServerForwarder -IPAddress "8.8.4.4" -ComputerName "dns-sunucu01"
# Forwarder sil
Remove-DnsServerForwarder -IPAddress "8.8.8.8" -ComputerName "dns-sunucu01" -Force
# Conditional forwarder ekle (belirli domain için farklı DNS kullan)
Add-DnsServerConditionalForwarderZone `
-Name "partner-sirket.local" `
-MasterServers "10.100.0.1", "10.100.0.2" `
-ComputerName "dns-sunucu01"
# Tüm conditional forwarder'ları listele
Get-DnsServerZone -ComputerName "dns-sunucu01" |
Where-Object ZoneType -eq "Forwarder" |
Select-Object ZoneName, MasterServers
Karşılaşılan Yaygın Sorunlar ve Çözümleri
DNS yanıt vermiyor: Resolve-DnsName timeout veriyorsa önce network bağlantısını, sonra DNS servisinin çalışıp çalışmadığını kontrol edin. Test-NetConnection -ComputerName "dns-sunucu01" -Port 53 ile port kontrolü yapın.
Cache tutarsızlıkları: Özellikle IP değişikliklerinden sonra hem sunucu hem istemci cache’ini temizlemek gerekiyor. Bunu otomatize etmek için Clear-DnsClientCache komutunu GPO script olarak dağıtabilirsiniz.
Zone transfer hataları: Serial numaraları aynı ama kayıtlar farklıysa, zone transfer’ı manuel tetikleyin. Start-DnsServerZoneTransfer -Name "sirket.local" -ComputerName "dns-secondary01" ile bunu yapabilirsiniz.
Scavenging ve Aging: Eski A kayıtları sistemde birikmesin diye DNS Aging/Scavenging’i etkinleştirmek gerekiyor:
# Zone için aging'i etkinleştir
Set-DnsServerZoneAging `
-Name "sirket.local" `
-Aging $true `
-ScavengeServers "dns-sunucu01" `
-ComputerName "dns-sunucu01"
# Scavenging ayarlarını görüntüle
Get-DnsServerZoneAging -Name "sirket.local" -ComputerName "dns-sunucu01"
Sonuç
PowerShell ile DNS yönetimi, hem troubleshooting hem de günlük operasyonlar açısından size büyük bir verimlilik artışı sağlar. Resolve-DnsName ile hızlı sorgular yapabilir, DnsServer modülü ile sunucu yönetimini otomatize edebilir, toplu işlemlerle saat süren manuel görevleri dakikalar içinde tamamlayabilirsiniz.
Özellikle CSV bazlı toplu kayıt oluşturma ve tutarlılık kontrol scriptleri, büyük ortamlarda gerçekten hayat kurtarıcı. Bu scriptleri kendi ortamınıza uyarlayın, Task Scheduler ile düzenli çalışacak şekilde ayarlayın ve DNS sorunlarını reaktif değil proaktif şekilde yönetmeye başlayın.
Son olarak şunu söyleyeyim: DNS konusunda en büyük tehlike “çalışıyor, dokunma” sendromudur. Düzenli raporlar çalıştırmak, eski kayıtları temizlemek ve tutarlılık kontrolü yapmak, büyük bir kriz çıkmadan önce sorunları yakalamanızı sağlar. PowerShell bu işleri otomatize etmek için tam olarak ihtiyacınız olan araç.