1. Anasayfa
  2. Microsoft Exchange Server

Exchange 2016, 2019 Internal / External URL’leri (Virtual Directory) PowerShell ile Yapılandırmak


Virtual Directory (VDIR) Exchange’in istemcilere sunduğu HTTP(S) tabanlı servislerin (OWA, ECP, EWS, ActiveSync, MAPI/HTTP, OAB, PowerShell vb.) IIS (Internet Information Services) üzerindeki mantıksal uç noktalarıdır.
Outlook, mobil cihazlar ve tarayıcılar bu uç noktalara URL’ler üzerinden erişir.

Her VDIR; url (ör. /owa, /ecp), kimlik doğrulama yöntemleri, SSL zorunluluğu, iç/dış URL gibi ayarlara sahiptir.

Neden Virtual Directory’ler vardır?

  • Exchange’in web tabanlı tüm işlevleri IIS üzerinden sunulur.
  • Her işlev için ayrı VDIR tanımlamak güvenlik, ölçekleme, yönlendirme, yük dengeleme ve sorun gidermeyi kolaylaştırır.
  • Ortamda birden fazla Exchange sunucusu varsa her sunucunun kendi VDIR’leri olur (aynı rolleri barındırıyorsa).

Başlıca Virtual Directory’ler ve Amaçları

BileşenIIS Yolu (örnek)Amaç
OWA/owaWeb posta (Outlook Web App)
ECP (EAC)/ecpExchange yönetim konsolu (admin arayüzü)
EWS/EWS/Exchange.asmxUygulamalar/entegrasyonlar (Outlook özellikleri, servisler)
ActiveSync/Microsoft-Server-ActiveSyncMobil cihaz senkronizasyonu
MAPI/HTTP/mapiOutlook’un modern protokol uç noktası
OAB/OABOffline Address Book dağıtımı
PowerShell/PowerShellUzaktan Exchange yönetimi (WinRM/PS over HTTPS)
Autodiscover/Autodiscover/Autodiscover.xmlİstemcilere servis URL’lerini buldurur (SCP + DNS ile birlikte)

Not: Exchange 2016/2019’da Outlook Anywhere (RPC/HTTP) eski uyumluluk içindir modern Outlook’lar MAPI/HTTP kullanır.

InternalUrl vs ExternalUrl (Birleşik Ad Alanı Önerisi)

Her VDIR için iki URL mantığı vardır:

  • InternalUrl: İç ağdaki (LAN) istemcilerin bağlandığı adres.
  • ExternalUrl: İnternetten gelen istemcilerin bağlandığı adres.

En az sorun yaşanan model, içeride ve dışarıda aynı FQDN’i kullanmaktır (unified namespace). Örn:

  • İç/Dış: https://mail.kadirkozan.com/owa, https://mail.kadirkozan.com/EWS/Exchange.asmx
    Bu yaklaşım:
  • Sertifika yönetimini kolaylaştırır (tek ad),
  • Autodiscover/Outlook mantığını sadeleştirir,
  • LB/WAF/proxy topolojilerinde kararlılık sağlar.

Sertifika ve DNS bununla uyumlu olmalı: SAN’da mail.kadirkozan.com ve autodiscover.kadirkozan.com, split-DNS ile iç/dış aynı adlar doğru IP’lere çözünmeli.

Virtual Directory Ayarlarında Önemli Parametreler

  • InternalUrl / ExternalUrl: İstemcinin bağlandığı adresler.
  • Authentication: Basic, NTLM, Negotiate(Kerberos), OAuth (modern auth) kombinasyonları.
    • Dış ortamda mümkünse Basic’i kapatın, modern kimlik doğrulama tercih edin (özellikle hibrit/Azure AD senaryolarında).
  • SSL Require / Redirect: HTTPS’i zorunlu kılın, gerekiyorsa HTTP→HTTPS yönlendirmesi uygulayın (ters proxy/LB üzerinde).
  • IIS App Pool & Limits: Uygulama havuzu sağlığı, geri dönüşüm ayarları, istek boyut limitleri.
  • Segmentation (özellikle OWA): OWA’dan istenen özellikleri aç/kapatabilirsiniz (policy/segmentation).

Hedef domain: kadirkozan.com
Önerilen birleşik ad alanı (unified namespace): mail.kadirkozan.com (iç/dış aynı FQDN)

Outlook, OWA, ECP, EWS, ActiveSync, MAPI gibi Exchange istemcileri IIS üzerindeki sanal dizinlere (virtual directory) gider.

Bu dizinlerin InternalUrl (LAN) ve ExternalUrl (internet) adresleri tutarlı değilse; kimlik doğrulama döngüleri, sertifika uyarıları ve bağlantı sorunları kaçınılmaz olur. En sorunsuz model içeride ve dışarıda aynı FQDN kullanmaktır: mail.kadirkozan.com.

Önkoşullar (kritik)

1. Sertifika (IIS/SMTP)

  • Sertifikanızın Subject veya SAN alanlarında en az şu adlar olmalı:
    • mail.kadirkozan.com
    • autodiscover.kadirkozan.com
  • Sertifikayı Exchange’e yükledikten sonra IIS/SMTP’ye bağlamayı unutmayın: Enable-ExchangeCertificate -Thumbprint <CERT_THUMBPRINT> -Services IIS,SMTP Değiştirirken önce yeni sertifika ile erişimi doğrulayın, eskisini sonra kaldırın.

2. DNS (Split DNS önerilir)

  • Dış DNS:
    • mail.kadirkozan.com → (WAF/LB ya da yayın yaptığınız dış IP)
    • autodiscover.kadirkozan.com → aynı dış IP
  • İç DNS (Active Directory DNS):
    • mail.kadirkozan.com → iç VIP ya da ilgili Exchange CAS rolü IP’si
    • autodiscover.kadirkozan.com → iç VIP
  • (Opsiyonel) SRV kaydı: Dış ortamda A kaydı kullanmak istemezseniz _autodiscover._tcp.kadirkozan.comautodiscover.kadirkozan.com:443 (çoğu senaryoda autodiscover A kaydı yeterlidir).

3. Bağlantı / Güvenlik

  • 443/TCP (HTTPS) erişimi; ters proxy/LB varsa timeout ve header ayarları Exchange dokümantasyonuna uygun olmalı.
  • Exchange 2016/2019’da Outlook, MAPI/HTTP’yi kullanır (Outlook Anywhere eski istemciler için kalır).

Hangi sanal dizinler?

  • OWA /owa – Web posta
  • ECP (EAC) /ecp – Yönetim konsolu
  • EWS /EWS/Exchange.asmx – Uygulama/entegrasyon uç noktası
  • ActiveSync /Microsoft-Server-ActiveSync – Mobil senkronizasyon
  • MAPI /mapi – Outlook MAPI/HTTP
  • OAB /OAB – Offline address book dağıtımı
  • PowerShell /PowerShell – Uzaktan Exchange yönetimi
  • Autodiscover https://autodiscover.kadirkozan.com/Autodiscover/Autodiscover.xml (SCP + DNS)

Bu Yapılamdırmaya Özel PowerShell betiği

Aşağıdaki betik; tek/çok sunucu için tekrar çalıştırmaya dayanıklı, kadirkozan.com’a göre düzenlenmiştir. İç/dış FQDN aynı tutulmuştur (unified). Dilersen iç ve dış FQDN’leri ayrı değişkenlerle farklılaştırabilirsin.

# ================== Parametreler ==================
$Servers        = @("EX01-2019")          # Birden fazla sunucu: @("EX01-2019","EX02-2019")
$Domain         = "kadirkozan.com"
$WebSubdomain   = "mail"                  # web servisi için FQDN: mail.domain
$AutoSubdomain  = "autodiscover"          # autodiscover FQDN: autodiscover.domain

# Unified namespace: içeride/dışarıda aynı adres
$ExternalFqdn   = "$WebSubdomain.$Domain"
$InternalFqdn   = "$WebSubdomain.$Domain"

$AutodiscoverUri = "https://$AutoSubdomain.$Domain/Autodiscover/Autodiscover.xml"

# ================== Yardımcı fonksiyon ==================
function Show-SetResult {
    param($Name,$Before,$After)
    Write-Host ("`n[ {0} ]" -f $Name) -ForegroundColor Cyan
    Write-Host ("  Before: {0}" -f $Before)
    Write-Host ("  After : {0}" -f $After) -ForegroundColor Green
}

foreach ($Server in $Servers) {
    Write-Host "`n=== Sunucu: $Server ===" -ForegroundColor Yellow

    # 1) Autodiscover Service Connection Point (SCP)
    try {
        $before = (Get-ClientAccessService -Identity $Server).AutoDiscoverServiceInternalUri
        Get-ClientAccessService -Identity $Server | Set-ClientAccessService -AutoDiscoverServiceInternalUri $AutodiscoverUri
        $after  = (Get-ClientAccessService -Identity $Server).AutoDiscoverServiceInternalUri
        Show-SetResult "Autodiscover (SCP)" $before $after
    } catch {
        Write-Warning "Get-ClientAccessService başarısız; eski sürümlerde CAS cmdlet'leri kullanılabilir."
        try {
            $before = (Get-ClientAccessServer -Identity $Server).AutoDiscoverServiceInternalUri
            Get-ClientAccessServer -Identity $Server | Set-ClientAccessServer -AutoDiscoverServiceInternalUri $AutodiscoverUri
            $after  = (Get-ClientAccessServer -Identity $Server).AutoDiscoverServiceInternalUri
            Show-SetResult "Autodiscover (SCP - CAS)" $before $after
        } catch { Write-Error $_ }
    }

    # Ortak URL tabanı
    $intBase = "https://$InternalFqdn"
    $extBase = "https://$ExternalFqdn"

    # 2) ECP
    Get-EcpVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-EcpVirtualDirectory -InternalUrl "$intBase/ecp" -ExternalUrl "$extBase/ecp"
        $after  = (Get-EcpVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "ECP $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 3) OWA
    Get-OwaVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-OwaVirtualDirectory -InternalUrl "$intBase/owa" -ExternalUrl "$extBase/owa"
        $after  = (Get-OwaVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "OWA $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 4) EWS
    Get-WebServicesVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-WebServicesVirtualDirectory -InternalUrl "$intBase/EWS/Exchange.asmx" -ExternalUrl "$extBase/EWS/Exchange.asmx"
        $after  = (Get-WebServicesVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "EWS $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 5) ActiveSync
    Get-ActiveSyncVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-ActiveSyncVirtualDirectory -InternalUrl "$intBase/Microsoft-Server-ActiveSync" -ExternalUrl "$extBase/Microsoft-Server-ActiveSync"
        $after  = (Get-ActiveSyncVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "ActiveSync $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 6) OAB
    Get-OabVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-OabVirtualDirectory -InternalUrl "$intBase/OAB" -ExternalUrl "$extBase/OAB"
        $after  = (Get-OabVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "OAB $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 7) MAPI (Outlook için kritik)
    Get-MapiVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-MapiVirtualDirectory -InternalUrl "$intBase/mapi" -ExternalUrl "$extBase/mapi"
        $after  = (Get-MapiVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "MAPI $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 8) PowerShell (uzaktan yönetim)
    Get-PowerShellVirtualDirectory -Server $Server | ForEach-Object {
        $before = $_ | Select-Object InternalUrl,ExternalUrl
        $_ | Set-PowerShellVirtualDirectory -InternalUrl "$intBase/powershell" -ExternalUrl "$extBase/powershell"
        $after  = (Get-PowerShellVirtualDirectory -Identity $_.Identity) | Select-Object InternalUrl,ExternalUrl
        Show-SetResult "PowerShell VDir $($_.Identity)" ($before | Out-String) ($after | Out-String)
    }

    # 9) Outlook Anywhere (eski istemciler için; modern Outlook MAPI/HTTP kullanır)
    try {
        $oa = Get-OutlookAnywhere -Server $Server -ErrorAction Stop
        $oa | ForEach-Object {
            $before = $_ | Select-Object ExternalHostname,InternalHostname,ExternalClientsRequireSsl,InternalClientsRequireSsl,DefaultAuthenticationMethod
            $_ | Set-OutlookAnywhere `
                -ExternalHostname $ExternalFqdn `
                -InternalHostname $InternalFqdn `
                -ExternalClientsRequireSsl $true `
                -InternalClientsRequireSsl $true `
                -DefaultAuthenticationMethod NTLM
            $after = (Get-OutlookAnywhere -Identity $_.Identity) | Select-Object ExternalHostname,InternalHostname,ExternalClientsRequireSsl,InternalClientsRequireSsl,DefaultAuthenticationMethod
            Show-SetResult "OutlookAnywhere $($_.Identity)" ($before | Out-String) ($after | Out-String)
        }
    } catch {
        Write-Host "OutlookAnywhere bulunamadı/uygulanmadı: modern Outlook MAPI/HTTP kullanıyor olabilir." -ForegroundColor DarkYellow
    }
}

Write-Host "`nİşlemler tamamlandı. IIS’yi geri dönüştürmek için: iisreset /noforce" -ForegroundColor Green

Notlar
• Exchange 2016/2019’da Get/Set-ClientAccessService tercih edilir; eski dökümanlarda Get/Set-ClientAccessServer görünebilir.
• Çok sunuculu/LB mimaride $ExternalFqdn ve $InternalFqdn tek FQDN olmalı ve VIP’ye çözülmeli.
• URL değişikliklerinden sonra IIS reset (veya ilgili app pool recycle) önerilir.

Değişiklik sonrası doğrulama (komut + tarayıcı)

1. Virtual Directory çıktılarını kontrol et

Get-OwaVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-EcpVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-WebServicesVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-MapiVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-ActiveSyncVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-OabVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
Get-PowerShellVirtualDirectory -Server EX01-2019 | fl InternalUrl,ExternalUrl
(Get-ClientAccessService -Identity EX01-2019).AutoDiscoverServiceInternalUri

2. Sağlık testleri

Test-ServiceHealth
Get-ServerComponentState EX01-2019

# İşlevsel testler (kimlik bilgisi gerekebilir)
Test-OwaConnectivity -ClientAccessServer EX01-2019 -HostName mail.kadirkozan.com -TrustAnySSLCertificate:$true
Test-WebServicesConnectivity -ClientAccessServer EX01-2019 -TrustAnySSLCertificate:$true
Test-ActiveSyncConnectivity -MailboxCredential (Get-Credential)
Test-MapiConnectivity

3. Tarayıcı testleri

  • https://mail.kadirkozan.com/owa → OWA açılıyor, sertifika hatası yok
  • https://mail.kadirkozan.com/ecp → EAC açılıyor
  • https://autodiscover.kadirkozan.com/Autodiscover/Autodiscover.xml → 401 benzeri yetkilendirme prompt’u görmeniz normaldir (uç nokta erişilebilir)

En iyi uygulamalar (best practices)

  • Birleşik ad alanı (unified namespace) ile iç/dış tek FQDN kullanın (işletim ve sertifika yönetimi kolaylaşır).
  • Sertifika yenileme süreçlerinde kesinti yaşamamak için yeni sertifikayı IIS/SMTP’ye bağlayıp test ettikten sonra eskisini kaldırın.
  • Autodiscover SCP tüm sunucularda https://autodiscover.kadirkozan.com/Autodiscover/Autodiscover.xml olmalı.
  • LB/WAF kullanıyorsanız: idle timeout, cookie persistence, header geçişleri (X-Forwarded-For) Exchange dokümanlarına uygun olmalı.
  • DNS TTL değerlerini geçiş dönemlerinde düşük tutmak (300 sn gibi) yönetimi kolaylaştırır.
  • Güvenlik sertleştirme (TLS1.2/modern cipher set) yapacaksanız Exchange destek matrisini izleyin. HSTS/ek header’ları varsa WAF/Reverse Proxy üzerinde uygulayın.

Sık hatalar ve pratik çözümler

  • Outlook sürekli parola istiyor / bağlanmıyor → MAPI URL’leri, Autodiscover kaydı, sertifika adları (CN/SAN) ve zincir güvenini kontrol edin.
  • EAC/OWA içeride açılıyor, dışarıda açılmıyor → Dış DNS, 443 yayın, WAF/LB kuralları, gerekirse proxy üzerinde TLS offload/reencrypt yapılarını gözden geçirin.
  • EWS kullanan uygulamalar (Teams/3rd party) hata veriyor/EWS/Exchange.asmx URL’leri ve auth (NTLM/Negotiate) ayarlarını doğrulayın.
  • ActiveSync senkron olmuyor/Microsoft-Server-ActiveSync URL, sertifika zinciri ve cihaz politikaları.
  • Autodiscover loop → İç/Dış DNS tutarlılığı, SRV/A kaydı, SCP URL’lerinin doğruluğu.

Yük Dengeleyici (Load Balance) / WAF / Reverse Proxy Kullanımı

  • Health Probe: Basit bir uç nokta kullanın (ör. /healthcheck.htm).
  • Stickiness / Affinity: ECP/OWA oturumlarında genellikle gerekli olur (cookie-based persistence).
  • Timeout’lar: MAPI/HTTP ve EWS uzun süreli bağlantılar kurabilir—LB timeout’larını Exchange kılavuzlarına göre ayarlayın.
  • SSL Offload / Re-encrypt: Sertifika zinciri, TLS sürümleri ve header’lar (X-Forwarded-For) doğru iletilmeli.
İlginizi Çekebilir