Exchange Server Sağlık Kontrolü: Test-ServiceHealth Komutu ile Servis Durumu İzleme

Sabah 08:00’de işe geldiğinizde ilk yapmanız gereken şeylerden biri Exchange ortamınızın genel sağlık durumunu kontrol etmektir. Bunu yapmak için onlarca farklı araç var, ancak Microsoft’un yerleşik olarak sunduğu Test-ServiceHealth cmdlet’i, hızlı bir ön kontrol için hala en pratik yollardan biri. Özellikle büyük ortamlarda sabah rutininin vazgeçilmez bir parçası haline gelmiş bu komut hakkında bugün elimdeki her şeyi paylaşacağım.

Test-ServiceHealth Nedir ve Ne İşe Yarar

Test-ServiceHealth, Exchange Management Shell üzerinden çalıştırılan bir PowerShell cmdlet’idir. Temel amacı, Exchange Server’ın düzgün çalışması için gerekli olan Windows servislerinin beklenen durumda olup olmadığını kontrol etmektir. Yani bu komut size doğrudan “Exchange çalışıyor mu?” sorusunun cevabını vermekten ziyade, “Exchange’in çalışması için gereken alt servisler ayakta mı?” sorusunu yanıtlar.

Bu iki şeyin farkını anlamak önemli. Örneğin Microsoft Exchange Transport servisi durmuş olabilir ama diğer servisler çalışıyor olduğu için Exchange’e bağlanabilirsiniz. Ancak mail akışı tamamen durmuş olur. İşte Test-ServiceHealth bu tür sorunları ilk etapta yakalamanızı sağlar.

Exchange 2013, 2016 ve 2019 sürümlerinde çalışan bu cmdlet, sunucu rollerine göre hangi servislerin çalışıyor olması gerektiğini bilir ve bunları tek tek kontrol eder. Yönetilen kullanılabilirlik (Managed Availability) altyapısının dışında, manuel kontrol için hala kullanışlı bir araçtır.

Temel Kullanım

En basit haliyle komutu Exchange Management Shell’de şöyle çalıştırırsınız:

Test-ServiceHealth

Bu komut çalıştırıldığında, üzerinde bulunduğunuz Exchange sunucusunun tüm rollerini kontrol eder ve her rol için çalışması gereken servislerin listesini, bunların durumunu döner. Çıktı şuna benzer bir şey olacaktır:

Test-ServiceHealth | Format-List

Çıktıda her satırda şunları görürsünüz: rol adı, gerekli servisler, çalışmayan servisler ve genel durum. RequiredServicesRunning değeri False ise o rol için bir sorun var demektir.

Belirli bir sunucu için uzaktan bu kontrolü yapmak istiyorsanız:

Test-ServiceHealth -Server EXCH02

Bu komut özellikle DAG (Database Availability Group) ortamlarında tüm üyeleri sırayla kontrol etmek istediğinizde işinize çok yarar. Tek tek sunucu başına gidip oturum açmak zorunda kalmazsınız.

Çıktıyı Anlamlandırmak

Ham çıktı bazen kafa karıştırıcı olabilir. Şimdi bunu biraz daha okunabilir hale getirelim. Aşağıdaki komut, sadece sorunlu rolleri filtreler ve size sadece dikkat etmeniz gerekenleri gösterir:

Test-ServiceHealth | Where-Object { $_.RequiredServicesRunning -eq $false }

Bu komut sessiz çalışır ve eğer her şey yolundaysa hiçbir çıktı vermez. Ama bir sorun varsa doğruca o sorunun üstüne gider. Sabah rutininde bu şekilde kullanmak çok daha verimli.

Biraz daha detay istiyorsanız ve hangi servislerin durduğunu görmek istiyorsanız:

Test-ServiceHealth | Select-Object Role, RequiredServicesRunning, ServicesNotRunning | Format-Table -AutoSize

ServicesNotRunning kolonu size tam olarak hangi servisin problem çıkardığını söyler. Oradan doğrudan aksiyon alabilirsiniz.

DAG Ortamında Toplu Kontrol

Tek sunucu ortamlarında Test-ServiceHealth oldukça basit kullanılır. Ama gerçek hayatta çoğumuz birden fazla Exchange sunucusu olan ortamlarda çalışıyoruz. Özellikle 4-6 node’lu DAG yapılarında her sunucuya teker teker bağlanmak zaman kaybıdır. Aşağıdaki script tüm Exchange sunucularını döngüye alıp her biri için sağlık kontrolü yapar:

$ExchangeServers = Get-ExchangeServer | Where-Object { $_.ServerRole -ne "Edge" }

foreach ($Server in $ExchangeServers) {
    Write-Host "Kontrol ediliyor: $($Server.Name)" -ForegroundColor Cyan
    $Result = Test-ServiceHealth -Server $Server.Name
    $Failed = $Result | Where-Object { $_.RequiredServicesRunning -eq $false }
    
    if ($Failed) {
        Write-Host "UYARI - Sorunlu roller bulundu:" -ForegroundColor Red
        $Failed | Select-Object Role, ServicesNotRunning | Format-List
    } else {
        Write-Host "Tum roller saglikli." -ForegroundColor Green
    }
}

Bu script’i sabah mesai başında çalıştırdığınızda tüm ortamınızın anlık bir fotoğrafını alırsınız. Edge Transport sunucularını filtreledim çünkü o sunuculara genellikle doğrudan erişim farklı bir yapı üzerinden gerçekleşiyor ve bu cmdlet orada düzgün çalışmayabiliyor.

Sonuçları Rapora Dönüştürmek

Birçok kurumda sysadmin’ler günlük sabah raporları hazırlamak zorunda. Exchange sağlık durumunu hem ekrana yazan hem de bir log dosyasına kaydeden şu script bu işi otomatik hale getirir:

$LogPath = "C:LogsExchangeHealthCheck_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
$Output = @()

$ExchangeServers = Get-ExchangeServer | Where-Object { $_.IsMailboxServer -eq $true -or $_.IsClientAccessServer -eq $true }

foreach ($Server in $ExchangeServers) {
    $Result = Test-ServiceHealth -Server $Server.Name
    foreach ($Role in $Result) {
        $Output += [PSCustomObject]@{
            Sunucu          = $Server.Name
            Rol             = $Role.Role
            Durum           = if ($Role.RequiredServicesRunning) { "OK" } else { "HATA" }
            SorunluServis   = ($Role.ServicesNotRunning -join ", ")
            KontrolZamani   = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        }
    }
}

$Output | Export-Csv -Path $LogPath -NoTypeInformation -Encoding UTF8
Write-Host "Rapor olusturuldu: $LogPath" -ForegroundColor Yellow

$SorunluSatirlar = $Output | Where-Object { $_.Durum -eq "HATA" }
if ($SorunluSatirlar) {
    Write-Host "`nDIKKAT - Asagidaki roller sorunlu:" -ForegroundColor Red
    $SorunluSatirlar | Format-Table -AutoSize
}

Bu script’i Task Scheduler üzerinden her sabah 07:30’da çalışacak şekilde ayarlarsanız, işe geldiğinizde zaten rapor hazır olur. CSV formatında kaydedildiği için Excel’de de açabilirsiniz ya da bir sonraki adımda e-posta ile gönderebilirsiniz.

E-posta Bildirimi ile Entegrasyon

Tamam, rapor dosyasına yazmak güzel. Ama ya sorun gece yarısı çıkarsa? İzleme sistemleri devreye girmeden önce erken bir uyarı almak için şu yaklaşımı kullanabilirsiniz:

$SmtpServer  = "localhost"
$KimiGonder  = "[email protected]"
$KimineSend  = "[email protected]"

$SorunluRoller = @()
$ExchangeServers = Get-ExchangeServer | Where-Object { $_.ServerRole -ne "Edge" }

foreach ($Server in $ExchangeServers) {
    $Result = Test-ServiceHealth -Server $Server.Name
    $Failed = $Result | Where-Object { $_.RequiredServicesRunning -eq $false }
    if ($Failed) {
        foreach ($F in $Failed) {
            $SorunluRoller += "$($Server.Name) - $($F.Role): $($F.ServicesNotRunning -join ', ')"
        }
    }
}

if ($SorunluRoller.Count -gt 0) {
    $MailBody = "Asagidaki Exchange servisleri calismıyor:`n`n"
    $MailBody += $SorunluRoller -join "`n"
    $MailBody += "`n`nKontrol Zamani: $(Get-Date)"
    
    Send-MailMessage -SmtpServer $SmtpServer `
                     -From $KimiGonder `
                     -To $KimineSend `
                     -Subject "UYARI: Exchange Servis Sorunu Tespit Edildi" `
                     -Body $MailBody `
                     -Encoding UTF8
}

Bu script’i 5 dakikada bir çalışacak şekilde Task Scheduler’a alırsanız, mail akışı kesildiğinde SMS ya da push notification yerine e-posta alırsınız. Tabii mail servisi durduğunda e-posta alamazsınız, bu nedenle bunu harici bir relay veya farklı bir SMTP sunucusu üzerinden göndermenizi öneririm.

Gerçek Hayatta Karşılaşılan Senaryolar

Senaryo 1: Sabah Gelen Şikayet

Bir pazartesi sabahı kullanıcılar “mail gönderemiyoruz” diye şikayet etmeye başladı. İlk refleks olarak Test-ServiceHealth çalıştırdım:

Test-ServiceHealth -Server EXCH01 | Where-Object { $_.RequiredServicesRunning -eq $false }

Çıktıda Hub Transport rolünün Microsoft Exchange Transport servisinin çalışmadığını gördüm. Nedeni araştırdığımda C: diskinin dolduğu ve servisin bu yüzden crash ettiği ortaya çıktı. Disk temizliği yapıp servisi yeniden başlattıktan sonra her şey normale döndü. Eğer bu kontrolü yapmasaydım daha uzun süre hata ayıklamaya çalışacaktım.

Senaryo 2: Planlı Bakım Sonrası Doğrulama

Patch Tuesday sonrasında sunucu yeniden başlatıldığında bazı Exchange servisleri kendiliğinden başlamıyordu. Artık bakım penceresinin sonunda standart prosedürümüz şu hale geldi:

$CheckInterval = 30
$MaxAttempt    = 10
$Attempt       = 0

do {
    $Attempt++
    Write-Host "Deneme $Attempt / $MaxAttempt" -ForegroundColor Yellow
    $Failed = Test-ServiceHealth | Where-Object { $_.RequiredServicesRunning -eq $false }
    
    if ($Failed) {
        Write-Host "Bekleniyor... ($CheckInterval saniye)" -ForegroundColor Gray
        Start-Sleep -Seconds $CheckInterval
    }
} while ($Failed -and $Attempt -lt $MaxAttempt)

if ($Failed) {
    Write-Host "Sunucu tam olarak ayaga kalkmadi. Manuel kontrol gerekli." -ForegroundColor Red
} else {
    Write-Host "Tum servisler calisiyor. Bakim tamamlandi." -ForegroundColor Green
}

Bu döngü, sunucu yeniden başlarken servislerin ayağa kalkmasını bekler ve belirli deneme sayısına kadar kontrol eder. Bakım sonrası “her şey tamam mı?” sorusuna otomatik yanıt alıyoruz artık.

Test-ServiceHealth’in Sınırları

Bu cmdlet’i çok seviyorum ama dürüst olmak gerekirse bazı kısıtları da var. Bunları bilmeden sadece bu araca bel bağlamak yanıltıcı olabilir.

Sadece servis durumunu kontrol eder: Mail kuyruğundaki birikmiş mesajlar, veritabanı mount durumu veya sertifika geçerliliği hakkında hiçbir şey söylemez. Servisler çalışıyor ama mail akışı yine de bozuk olabilir.

Ağ bağlantısını test etmez: Connector’lar, DNS çözümleme sorunları veya güvenlik duvarı kuralları hakkında bilgi vermez.

Uygulama katmanı sağlığını göstermez: Outlook Anywhere bağlantısı, ActiveSync servisi veya OWA erişimi için farklı test cmdlet’leri kullanmanız gerekir (Test-OutlookConnectivity, Test-ActiveSyncConnectivity gibi).

Zaman aşımı sorunları: Ağ gecikmesi yüksek ortamlarda veya sunucu yoğun yük altındayken hatalı sonuç döndürebilir.

Bu yüzden Test-ServiceHealth tek başına yeterli değildir. Kapsamlı bir Exchange sağlık kontrolü için şu cmdlet’leri de repertuarınıza eklemenizi öneririm: Get-MailboxDatabaseCopyStatus, Test-MailFlow, Get-Queue ve Test-MAPIConnectivity.

Managed Availability ile İlişkisi

Exchange 2013 ve sonrasında Microsoft, Managed Availability adında yerleşik bir izleme ve kurtarma altyapısı getirdi. Bu sistem arka planda sürekli sağlık kontrolleri yapar ve sorun tespit ettiğinde otomatik kurtarma eylemleri başlatır. Peki Test-ServiceHealth bu sistemle nasıl bir ilişki içinde?

Test-ServiceHealth aslında Managed Availability’nin yaptığı kontrollerin bir alt kümesini manuel olarak yapmanızı sağlar. Yani Managed Availability zaten bu servisleri izliyor ve gerektiğinde yeniden başlatmayı deniyordur. Ancak şunu fark ettim: Managed Availability bazen servis sorununu kendi halleder ve siz hiç haberdar olmazsınız. Bu iyi bir şey gibi görünse de sorunun kök nedenini bulmak açısından tehlikeli olabilir. Tekrarlayan servis yeniden başlatmaları varsa Get-ServerHealth ve Get-HealthReport ile Managed Availability loglarını da incelemenizi öneririm.

Otomasyon için İpuçları

Birkaç yıllık Exchange yönetim deneyiminden edindiğim pratik ipuçları:

Credential yönetimi: Script’leri Task Scheduler’dan çalıştırırken Exchange yönetici hesabı yerine ayrı bir servis hesabı kullanın ve yalnızca gerekli rolleri verin. Test-ServiceHealth için View-Only Organization Management rolü yeterlidir.

PowerShell remoting ile kullanım: Exchange Management Shell yerine standart PowerShell’den bu cmdlet’i kullanmak isterseniz önce Exchange snap-in’ini yükleyin:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
$Result = Test-ServiceHealth -Server "EXCH01"
$Result | Where-Object { $_.RequiredServicesRunning -eq $false }

Sonuçları Windows Event Log’a yazmak: Bazı ortamlarda SIEM sistemleri Windows Event Log’u dinler. Sorunları oraya yazmak merkezi izleme açısından pratiktir:

$Failed = Test-ServiceHealth | Where-Object { $_.RequiredServicesRunning -eq $false }

if ($Failed) {
    $EventMessage = "Exchange servis sorunu: "
    $EventMessage += ($Failed | ForEach-Object { "$($_.Role): $($_.ServicesNotRunning -join ',')" }) -join " | "
    
    Write-EventLog -LogName Application `
                   -Source "Exchange Health Monitor" `
                   -EventId 9001 `
                   -EntryType Warning `
                   -Message $EventMessage
}

Bu yaklaşım özellikle Splunk veya Elastic Stack kullanan ortamlarda Exchange uyarılarını merkezi log yönetimiyle entegre etmenizi sağlar.

Sonuç

Test-ServiceHealth, Exchange yönetiminde alet çantanızda bulunması gereken temel araçlardan biri. Tek başına her şeyi çözmez, ama sabah rutininin ilk adımı olarak, bakım sonrası doğrulama aracı olarak ve basit izleme scriptlerinin çekirdeği olarak son derece güvenilirdir.

Önemli olan bu cmdlet’i izole bir araç olarak değil, daha büyük bir izleme ve operasyon prosedürünün parçası olarak kullanmak. Yukarıdaki script’leri kendi ortamınıza göre uyarlayın, Task Scheduler’a alın ve her sabah işe geldiğinizde ortamınızın size nasıl bir sürpriz hazırladığını öğrenmek yerine, sizi bekleyen hazır bir raporla güne başlayın.

Exchange yönetimi reaktif değil proaktif olunca hem siz daha az stres yaşarsınız, hem de kullanıcılar mail sorunlarını size şikayet etmeden önce siz zaten çözmüş olursunuz. Bu farkı yaratan şey çoğu zaman bu tür küçük ama tutarlı otomasyonlardır.

Bir yanıt yazın

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