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şen | IIS Yolu (örnek) | Amaç |
|---|---|---|
| OWA | /owa | Web posta (Outlook Web App) |
| ECP (EAC) | /ecp | Exchange yönetim konsolu (admin arayüzü) |
| EWS | /EWS/Exchange.asmx | Uygulamalar/entegrasyonlar (Outlook özellikleri, servisler) |
| ActiveSync | /Microsoft-Server-ActiveSync | Mobil cihaz senkronizasyonu |
| MAPI/HTTP | /mapi | Outlook’un modern protokol uç noktası |
| OAB | /OAB | Offline Address Book dağıtımı |
| PowerShell | /PowerShell | Uzaktan 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. ve kadirkozan.comautodiscover., split-DNS ile iç/dış aynı adlar doğru IP’lere çözünmeli.kadirkozan.com
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.comautodiscover.kadirkozan.com
- Sertifikayı Exchange’e yükledikten sonra IIS/SMTP’ye bağlamayı unutmayın:
Enable-ExchangeCertificate -Thumbprint <CERT_THUMBPRINT> -Services IIS,SMTPDeğ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’siautodiscover.kadirkozan.com→ iç VIP
- (Opsiyonel) SRV kaydı: Dış ortamda A kaydı kullanmak istemezseniz
_autodiscover._tcp.kadirkozan.com→autodiscover.kadirkozan.com:443(çoğu senaryodaautodiscoverA 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ı yokhttps://mail.kadirkozan.com/ecp→ EAC açılıyorhttps://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.xmlolmalı. - 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.asmxURL’leri ve auth (NTLM/Negotiate) ayarlarını doğrulayın. - ActiveSync senkron olmuyor →
/Microsoft-Server-ActiveSyncURL, 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.