PowerShell ile Ağ Adaptörü ve IP Yönetimi

Ağ adaptörü yönetimi, özellikle onlarca sunucuyu aynı anda yapılandırmanız gereken ortamlarda, GUI üzerinden yapmak isteyeceğiniz son şey haline geliyor. Birkaç yıl önce, 40 sunucuya aynı anda statik IP ataması yapmam gerektiğinde ve her birini RDP ile açıp Network Adapter ayarlarına girmek zorunda kaldığımda, PowerShell’in bu alandaki gücünü gerçekten anladım. O günden bu yana ağ yapılandırmalarımın neredeyse tamamını PowerShell üzerinden yapıyorum. Bu yazıda, gerçek ortamlarda işe yarayan, production’da test edilmiş komutları ve senaryoları paylaşacağım.

Temel Kavramlar ve Başlangıç Noktası

Windows Server’da ağ adaptörü yönetimi için iki farklı modül var: eski nesil NetAdapter cmdlet’leri ve NetTCPIP modülü. Windows Server 2012 R2 ve sonrasında bu cmdlet’ler neredeyse her şeyi kapsıyor. netsh komutlarına artık çok nadir başvuruyorum, sadece eski ortamlarda karşıma çıktığında mecbur kalıyorum.

Önce mevcut adaptörlerin listesini çekelim:

# Sistemdeki tüm ağ adaptörlerini listele
Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed, MacAddress

# Sadece aktif adaptörleri göster
Get-NetAdapter | Where-Object { $_.Status -eq "Up" }

# Daha detaylı bilgi
Get-NetAdapter | Format-List *

Buradaki InterfaceDescription alanı kritik. Özellikle VMware veya Hyper-V ortamlarında çalışıyorsanız, hangi adaptörün hangi fiziksel veya sanal NIC’e karşılık geldiğini anlamak için bu alana bakıyorsunuz. Name alanı ise PowerShell komutlarında kullanacağınız kısa isim, mesela “Ethernet0” veya “Local Area Connection”.

IP Adresi Yapılandırması

Statik IP atamak, en sık yapılan işlemlerden biri. Şu an çalıştığınız sunucuya yanlış IP girdiğinizde bağlantınızın kesilmesi ihtimalini düşündüğünüzde, bu komutu doğru yazmak kritik hale geliyor.

# Mevcut IP yapılandırmasını görüntüle
Get-NetIPConfiguration -InterfaceAlias "Ethernet0"

# Statik IP adresi ata
New-NetIPAddress `
    -InterfaceAlias "Ethernet0" `
    -IPAddress "192.168.10.50" `
    -PrefixLength 24 `
    -DefaultGateway "192.168.10.1"

# DNS sunucularını ayarla
Set-DnsClientServerAddress `
    -InterfaceAlias "Ethernet0" `
    -ServerAddresses ("192.168.10.10", "192.168.10.11")

-InterfaceAlias: Adaptörün sistem üzerindeki adı, Get-NetAdapter çıktısındaki Name sütunundan alınır. -PrefixLength: Subnet mask’in bit cinsinden karşılığı. 255.255.255.0 için 24, 255.255.0.0 için 16 kullanıyorsunuz. -DefaultGateway: Sadece New-NetIPAddress ile birlikte kullanılır.

Eğer adaptörde zaten bir IP adresi varsa ve değiştirmeniz gerekiyorsa, önce mevcut adresi kaldırmanız gerekiyor:

# Mevcut IP adresini kaldır
Remove-NetIPAddress -InterfaceAlias "Ethernet0" -Confirm:$false

# Mevcut gateway'i kaldır
Remove-NetRoute -InterfaceAlias "Ethernet0" -DestinationPrefix "0.0.0.0/0" -Confirm:$false

# Yeni IP ata
New-NetIPAddress `
    -InterfaceAlias "Ethernet0" `
    -IPAddress "192.168.10.55" `
    -PrefixLength 24 `
    -DefaultGateway "192.168.10.1"

Bu akışı bir fonksiyon haline getirmek, birden fazla sunucuda çalışırken hayat kurtarıyor.

DHCP’den Statik IP’ye Geçiş Senaryosu

Gerçek dünyada en sık karşılaştığım senaryo bu: DHCP ile başlatılan bir sunucuyu statik IP’ye geçirmek. Yeni kurulan bir sunucuyu domain’e almadan önce genellikle bu adımı yapıyorum.

# DHCP ile atanmış IP'yi kontrol et
$adapter = Get-NetAdapter -Name "Ethernet0"
$currentIP = Get-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -AddressFamily IPv4

Write-Host "Mevcut IP: $($currentIP.IPAddress)"
Write-Host "Prefix Length: $($currentIP.PrefixLength)"

# DHCP'yi devre dışı bırak ve statik geç
Set-NetIPInterface -InterfaceAlias "Ethernet0" -Dhcp Disabled

# Mevcut adresleri temizle
Remove-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
Remove-NetRoute -InterfaceIndex $adapter.InterfaceIndex -DestinationPrefix "0.0.0.0/0" `
    -Confirm:$false -ErrorAction SilentlyContinue

# Statik IP ata
New-NetIPAddress `
    -InterfaceIndex $adapter.InterfaceIndex `
    -IPAddress "10.0.1.100" `
    -PrefixLength 24 `
    -DefaultGateway "10.0.1.1"

# DNS ayarla
Set-DnsClientServerAddress `
    -InterfaceIndex $adapter.InterfaceIndex `
    -ServerAddresses @("10.0.1.10", "8.8.8.8")

# Doğrulama
Get-NetIPConfiguration -InterfaceAlias "Ethernet0"

-ErrorAction SilentlyContinue kullanımına dikkat edin. Adaptörde hiç IP yoksa veya route yoksa komutun hata vermesi yerine sessizce devam etmesini istiyoruz. Ama bunu her yerde kullanmayın, kritik adımlarda hatayı görmek istersiniz.

Çoklu Sunucu Yönetimi: Gerçek Senaryo

40 sunucuyu tek seferde yapılandırmam gereken o gece bu scripti yazmıştım. O gün öğrendiğim şey: sunucu listesini ve IP bilgilerini bir CSV dosyasına koyup scripti üzerinden beslemek, hem hataları azaltıyor hem de ne yapıldığını dokümante etmiş oluyorsunuz.

CSV dosyası şu formatta:

# servers.csv içeriği örneği (comment satırı değil, bilgi amaçlı)
# ServerName,IPAddress,PrefixLength,Gateway,DNS1,DNS2
# WEB01,192.168.1.101,24,192.168.1.1,192.168.1.10,192.168.1.11
# DB01,192.168.1.102,24,192.168.1.1,192.168.1.10,192.168.1.11

$servers = Import-Csv -Path "C:Scriptsservers.csv"

foreach ($server in $servers) {
    Write-Host "Yapılandırılıyor: $($server.ServerName)" -ForegroundColor Cyan
    
    try {
        Invoke-Command -ComputerName $server.ServerName -ScriptBlock {
            param($ip, $prefix, $gw, $dns1, $dns2)
            
            $adapter = Get-NetAdapter | Where-Object { $_.Status -eq "Up" } | Select-Object -First 1
            
            Remove-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
            Remove-NetRoute -InterfaceIndex $adapter.InterfaceIndex -DestinationPrefix "0.0.0.0/0" `
                -Confirm:$false -ErrorAction SilentlyContinue
            
            New-NetIPAddress `
                -InterfaceIndex $adapter.InterfaceIndex `
                -IPAddress $ip `
                -PrefixLength $prefix `
                -DefaultGateway $gw
            
            Set-DnsClientServerAddress `
                -InterfaceIndex $adapter.InterfaceIndex `
                -ServerAddresses @($dns1, $dns2)
                
        } -ArgumentList $server.IPAddress, $server.PrefixLength, $server.Gateway, $server.DNS1, $server.DNS2
        
        Write-Host "Tamamlandı: $($server.ServerName)" -ForegroundColor Green
    }
    catch {
        Write-Host "HATA - $($server.ServerName): $_" -ForegroundColor Red
    }
}

Bu scriptte Invoke-Command ile remote execution kullanıyoruz. WinRM’nin açık olması gerekiyor, büyük ortamlarda bu genellikle Group Policy ile yapılmış oluyor.

NIC Teaming (LBFO) PowerShell ile

Fiziksel sunucularda yüksek erişilebilirlik ve bant genişliği için NIC teaming yapıyoruz. GUI üzerinden yapmak yerine PowerShell tercihim çünkü yapılandırmayı script olarak saklayabiliyorum.

# Mevcut fiziksel adaptörleri listele
Get-NetAdapter -Physical | Select-Object Name, InterfaceDescription, Status, LinkSpeed

# Yeni bir NIC Team oluştur
New-NetLbfoTeam `
    -Name "TeamProduction" `
    -TeamMembers @("Ethernet0", "Ethernet1") `
    -TeamingMode SwitchIndependent `
    -LoadBalancingAlgorithm Dynamic

# Team oluşturulduktan sonra kontrol et
Get-NetLbfoTeam

# Team'e IP adresi ata
New-NetIPAddress `
    -InterfaceAlias "TeamProduction" `
    -IPAddress "10.0.0.50" `
    -PrefixLength 24 `
    -DefaultGateway "10.0.0.1"

TeamingMode için seçenekler:

  • SwitchIndependent: Switch tarafında yapılandırma gerektirmez, en yaygın kullanılan mod
  • Lacp: IEEE 802.3ad standardı, switch tarafında da yapılandırma gerekir
  • Static: Switch ile statik agregasyon, bazı eski switch’lerde LACP yoksa bu kullanılır

LoadBalancingAlgorithm seçenekleri:

  • Dynamic: Hem inbound hem outbound trafiği dengeler, Windows Server 2012 R2+ destekler
  • HyperVPort: Hyper-V ortamlarında sanal switch portlarına göre dağıtım yapar
  • IPAddresses: Kaynak/hedef IP’ye göre dağıtım

Adaptör Özelliklerini Optimizasyon için Değiştirme

Sadece IP yapılandırması değil, adaptörün kendisinin özelliklerini de PowerShell ile değiştirebilirsiniz. Yüksek performans gerektiren ortamlarda, örneğin SQL Server veya yüksek trafikli web sunucularında, bazı NIC özelliklerini tune etmek fark yaratıyor.

# Adaptör özelliklerini listele
Get-NetAdapterAdvancedProperty -Name "Ethernet0" | 
    Select-Object DisplayName, DisplayValue

# Jumbo Frame ayarla (9014 byte için)
Set-NetAdapterAdvancedProperty `
    -Name "Ethernet0" `
    -DisplayName "Jumbo Packet" `
    -DisplayValue "9014 Bytes"

# Receive Side Scaling (RSS) etkinleştir
Enable-NetAdapterRss -Name "Ethernet0"

# RSS için kullanılacak işlemci sayısını ayarla
Set-NetAdapterRss -Name "Ethernet0" -NumberOfReceiveQueues 4

# Interrupt Moderation ayarı (latency vs throughput dengesi)
Set-NetAdapterAdvancedProperty `
    -Name "Ethernet0" `
    -DisplayName "Interrupt Moderation" `
    -DisplayValue "Enabled"

# Mevcut ayarları doğrula
Get-NetAdapterRss -Name "Ethernet0" | Select-Object Name, Enabled, NumberOfReceiveQueues

Jumbo Frame ayarı yapmadan önce ağınızdaki tüm cihazların (switch, router, karşı taraftaki sunucular) bunu desteklediğinden emin olun. Desteklemeyen bir noktada paket fragmentation başlar ve performansı artırmak yerine düşürmüş olursunuz.

Ağ Adaptörü Monitoring ve Troubleshooting

Sorun yaşandığında hızlıca durumu görmek için kullandığım komutlar:

# Adaptör istatistiklerini izle
$adapter = "Ethernet0"

# Anlık istatistikler
Get-NetAdapterStatistics -Name $adapter | 
    Select-Object Name, ReceivedBytes, SentBytes, ReceivedUnicastPackets, SentUnicastPackets

# Hata istatistikleri - paket kaybı var mı?
Get-NetAdapterStatistics -Name $adapter | 
    Select-Object Name, ReceivedDiscardedPackets, ReceivedPacketErrors, OutboundDiscardedPackets

# Bağlantı durumu değişikliklerini izle (5 saniyede bir kontrol)
$previousStatus = $null
while ($true) {
    $currentAdapter = Get-NetAdapter -Name $adapter
    $currentStatus = $currentAdapter.Status
    
    if ($currentStatus -ne $previousStatus) {
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        Write-Host "[$timestamp] Durum değişti: $previousStatus -> $currentStatus" -ForegroundColor Yellow
        $previousStatus = $currentStatus
    }
    Start-Sleep -Seconds 5
}

Bu monitoring loop’u production’da bir servis olarak değil, geçici troubleshooting sırasında bir PowerShell oturumunda çalıştırıyorum. Ctrl+C ile durduruluyor.

Bağlantı sorunlarını hızlıca diagnose etmek için şu script işime yaradı:

# Ağ adaptörü sağlık kontrolü
function Test-NetworkAdapterHealth {
    param([string]$AdapterName)
    
    $adapter = Get-NetAdapter -Name $AdapterName -ErrorAction Stop
    $ipConfig = Get-NetIPConfiguration -InterfaceAlias $AdapterName
    $stats = Get-NetAdapterStatistics -Name $AdapterName
    
    Write-Host "`n=== $AdapterName Adaptör Raporu ===" -ForegroundColor Cyan
    
    # Durum kontrolü
    $statusColor = if ($adapter.Status -eq "Up") { "Green" } else { "Red" }
    Write-Host "Durum: $($adapter.Status)" -ForegroundColor $statusColor
    Write-Host "Hız: $($adapter.LinkSpeed)"
    Write-Host "MAC: $($adapter.MacAddress)"
    
    # IP bilgisi
    if ($ipConfig.IPv4Address) {
        Write-Host "IP: $($ipConfig.IPv4Address.IPAddress)/$($ipConfig.IPv4Address.PrefixLength)"
        Write-Host "Gateway: $($ipConfig.IPv4DefaultGateway.NextHop)"
    } else {
        Write-Host "IP adresi yok!" -ForegroundColor Red
    }
    
    # DNS
    Write-Host "DNS: $($ipConfig.DNSServer.ServerAddresses -join ', ')"
    
    # Hata istatistikleri
    if ($stats.ReceivedPacketErrors -gt 0 -or $stats.OutboundDiscardedPackets -gt 0) {
        Write-Host "UYARI: Hata/Discard paketleri var!" -ForegroundColor Yellow
        Write-Host "  RX Hata: $($stats.ReceivedPacketErrors)"
        Write-Host "  TX Discard: $($stats.OutboundDiscardedPackets)"
    } else {
        Write-Host "Paket hataları: Yok" -ForegroundColor Green
    }
    
    # Gateway erişim testi
    $gwPing = Test-Connection -ComputerName $ipConfig.IPv4DefaultGateway.NextHop `
        -Count 2 -Quiet -ErrorAction SilentlyContinue
    $pingColor = if ($gwPing) { "Green" } else { "Red" }
    Write-Host "Gateway ping: $(if ($gwPing) {'OK'} else {'FAIL'})" -ForegroundColor $pingColor
}

# Kullanım
Test-NetworkAdapterHealth -AdapterName "Ethernet0"

Bu fonksiyonu $PROFILE dosyama ekledim, her oturumda hazır geliyor.

VLAN Yapılandırması

Hyper-V veya fiziksel ortamlarda VLAN yapılandırması da sıkça karşıma çıkıyor:

# Adaptöre VLAN ID ata
Set-NetAdapterAdvancedProperty `
    -Name "Ethernet0" `
    -DisplayName "VLAN ID" `
    -DisplayValue "100"

# Alternatif yöntem
Add-NetLbfoTeamNic `
    -Team "TeamProduction" `
    -VlanID 200

# Hyper-V ortamında VM adaptörüne VLAN ata
Set-VMNetworkAdapterVlan `
    -VMName "WebServer01" `
    -VlanId 100 `
    -Access

# Hyper-V host adaptörü için VLAN
Set-VMNetworkAdapterVlan `
    -ManagementOS `
    -VMNetworkAdapterName "Management" `
    -VlanId 10 `
    -Access

IPv6 Yönetimi

Pek çok ortamda IPv6 devre dışı bırakma veya yönetme ihtiyacı oluyor. Özellikle eski uygulamaların IPv6 ile uyumsuzluk yaşadığı senaryolarda:

# IPv6'yı belirli bir adaptörde devre dışı bırak
Disable-NetAdapterBinding `
    -Name "Ethernet0" `
    -ComponentID ms_tcpip6

# IPv6'yı tekrar etkinleştir
Enable-NetAdapterBinding `
    -Name "Ethernet0" `
    -ComponentID ms_tcpip6

# Mevcut binding durumunu kontrol et
Get-NetAdapterBinding -Name "Ethernet0" | 
    Where-Object { $_.ComponentID -eq "ms_tcpip6" } |
    Select-Object Name, ComponentID, Enabled

# Tüm adaptörlerde IPv6 durumunu göster
Get-NetAdapterBinding | 
    Where-Object { $_.ComponentID -eq "ms_tcpip6" } |
    Select-Object Name, Enabled

IPv6’yı tamamen devre dışı bırakmak Windows’un kendi iç iletişimini olumsuz etkileyebilir, özellikle DirectAccess veya bazı cluster senaryolarında sorun yaratıyor. Bu yüzden gerçekten gerekmedikçe önerilen yaklaşım adaptörden kaldırmak değil, routing’i düzenlemek.

Yapılandırmaları Yedekleme ve Geri Yükleme

Değişiklik yapmadan önce mevcut yapılandırmayı kaydetmek, gece yarısı kurtarıcınız olabilir:

# Mevcut ağ yapılandırmasını dışa aktar
$networkConfig = @{
    Adapters = Get-NetAdapter | Select-Object Name, InterfaceDescription, MacAddress, Status
    IPAddresses = Get-NetIPAddress | Select-Object InterfaceAlias, IPAddress, PrefixLength, AddressFamily
    Routes = Get-NetRoute | Select-Object InterfaceAlias, DestinationPrefix, NextHop, RouteMetric
    DNS = Get-DnsClientServerAddress | Select-Object InterfaceAlias, ServerAddresses, AddressFamily
}

$networkConfig | ConvertTo-Json -Depth 5 | 
    Out-File -FilePath "C:BackupNetworkConfig_$(Get-Date -Format 'yyyyMMdd_HHmmss').json"

Write-Host "Yapılandırma yedeklendi." -ForegroundColor Green

Bu JSON dosyasını değişiklik öncesinde alın. Geri yükleme tam otomatik yapılamıyor çünkü her ortamın adaptör isimleri farklı, ama en azından ne olduğunu biliyorsunuz ve manuel olarak hızlıca döndürebiliyorsunuz.

Sonuç

PowerShell ile ağ adaptörü yönetimi, başta birkaç cmdlet öğrenmek gibi görünse de zamanla kendi araç kutunuzu oluşturuyorsunuz. Get-NetAdapter, New-NetIPAddress, Set-DnsClientServerAddress üçlüsü günlük işlerin büyük çoğunluğunu karşılıyor. Buna Invoke-Command eklenince onlarca sunucuyu tek scriptle yönetmeye başlıyorsunuz.

Paylaştığım Test-NetworkAdapterHealth fonksiyonu gibi araçları kendi ortamınıza göre geliştirin ve $PROFILE dosyanıza ekleyin. Her sorun yaşadığınızda tekrar araştırmak yerine hazır araçlara ulaşmak, hem zaman kazandırıyor hem de baskı altında hata yapma ihtimalini düşürüyor.

Son olarak: yapılandırma değişikliklerini production’a uygulamadan önce mutlaka test ortamında deneyin ve değişiklik öncesi yedek alın. Basit görünen bir IP değişikliği bile yanlış parametreyle yapıldığında sunucuya erişiminizi kesebilir. Out-of-band yönetim imkanınız yoksa (IPMI, iDRAC, vb.), remote IP değişikliği yaparken ekstra dikkatli olun.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir