Exchange Server 2019 Active Directory PowerShell ImportExcel  |  Okuma süresi: ~18 dakika

Exchange Server 2019 Kurulum Serisi
Bölüm 6: Toplu Kullanıcı Oluşturma ve Posta Kutusu Etkinleştirme

Bu bölümde neler yapacaksınız?
Excel dosyasındaki kullanıcı listesini okuyarak Active Directory'de toplu kullanıcı hesapları oluşturacak, ardından bu hesaplar için Exchange posta kutularını etkinleştireceksiniz. Tüm süreç PowerShell ile otomatikleştirilecek; hatalı veya eksik kayıtlar atlama mantığıyla yönetilecektir.
? Seri Navigasyonu: Bölüm 1 – Ortam Hazırlığı  |  Bölüm 2 – Active Directory Kurulumu  |  Bölüm 3 – Exchange Ön Gereksinimleri  |  Bölüm 4 – Exchange Kurulumu  |  Bölüm 5 – Exchange Konfigürasyonu  |  Bölüm 6 – Toplu Kullanıcı Oluşturma ← (şu an buradasınız)

1. Genel Bakış ve Mimari

Toplu kullanıcı işlemi iki ayrı aşamadan oluşur ve bu aşamalar farklı sunucularda çalıştırılır:

[AŞAMA 1] DC01 üzerinde çalıştırılır Excel → ImportExcel modülü → New-ADUser cmdlet'i Sonuç: AD kullanıcı hesapları oluşturulur ↓ [AŞAMA 2] MAIL01 üzerinde çalıştırılır AD kullanıcıları → Enable-Mailbox cmdlet'i Sonuç: Her kullanıcı için Exchange posta kutusu etkinleştirilir
ℹ️ Neden İki Farklı Sunucu? New-ADUser komutu Domain Controller üzerinde doğrudan ya da uzaktan çalışır. Ancak Exchange cmdlet'leri (Enable-Mailbox gibi) MAIL01 üzerindeki Exchange snap-in'i gerektirir. Ağ oturumu üzerinden her iki sunucuya aynı anda kimlik doğrulaması yapılması (double-hop) WinRM kısıtları nedeniyle sorunludur; bu yüzden adımları ayrı çalıştırıyoruz.

2. Excel Dosyasının Hazırlanması

Kullanıcı listesi aşağıdaki sütun başlıklarını içeren bir Excel (.xlsx) dosyası olarak hazırlanmalıdır:

Sütun Adı Açıklama Örnek Değer Zorunlu
Display name Tam görünen ad Ali Yılmaz Evet
User principal name UPN (e-posta adresi formatında) ali.yilmaz@sirket.com Evet
First name Ad Ali Hayır
Last name Soyad Yılmaz Hayır
Title Unvan / Pozisyon Yazılım Geliştirici Hayır
Department Departman Bilgi İşlem Hayır
⚠️ Sütun Adları Büyük/Küçük Harf Duyarlıdır. Script sütun adlarını birebir okur. User principal name ile user principal name farklı algılanır. Dosyanızı hazırlarken sütun başlıklarını tablodakiyle aynı yazın.
Adım 2.1 — Dosyayı Hedef Sunucuya Kopyalama

Excel dosyasını yerel makinenizden DC01 sunucusuna kopyalayın:

# Yerel makinenizden çalıştırın
$cred = Get-Credential  # SIRKET\administrator
Copy-Item -Path "C:\Kullanicilar\kullanici-listesi.xlsx" `
          -Destination "\\192.168.1.10\c$\kullanici.xlsx" `
          -Credential $cred

Veya uzak oturumla kopyalayın:

$session = New-PSSession -ComputerName 192.168.1.10 -Credential $cred
Copy-Item -Path "C:\Kullanicilar\kullanici-listesi.xlsx" `
          -Destination "C:\kullanici.xlsx" `
          -ToSession $session
Remove-PSSession $session

3. ImportExcel Modülünün Kurulumu

Excel dosyasını PowerShell'den okumak için ImportExcel modülü kullanılır. Bu modül, Microsoft Excel kurulumu gerektirmeden .xlsx dosyalarını okur ve yazar.

Adım 3.1 — DC01 Üzerinde Modülü Kur

DC01 sunucusunda PowerShell'i yönetici olarak açın:

# İnternet bağlantısı varsa doğrudan kur
Install-Module ImportExcel -Force -Scope AllUsers

# Kurulumu doğrula
Get-Module ImportExcel -ListAvailable | Select-Object Name, Version
Name Version ---- ------- ImportExcel 7.8.9
ℹ️ İnternet Bağlantısı Yoksa: Modülü internete bağlı başka bir makinede Save-Module ImportExcel -Path C:\Modules ile indirip, DC01'e kopyalayarak C:\Program Files\WindowsPowerShell\Modules\ImportExcel klasörüne yerleştirebilirsiniz.

4. AD Kullanıcılarını Toplu Oluşturma

Adım 4.1 — Toplu Kullanıcı Oluşturma Scripti

Aşağıdaki scripti DC01 üzerinde C:\create-users.ps1 olarak kaydedin ve çalıştırın:

# create-users.ps1 — DC01 üzerinde çalıştırılır
Import-Module ImportExcel
Import-Module ActiveDirectory

$excelPath    = "C:\kullanici.xlsx"
$defaultPass  = ConvertTo-SecureString "Sirket2026!" -AsPlainText -Force
$logPath      = "C:\create-users-log.txt"
$targetDomain = "@sirket.com"

$olusturulan = 0
$atlanan     = 0
$hatali      = 0

"Başlangıç: $(Get-Date)" | Out-File $logPath

$users = Import-Excel -Path $excelPath

foreach ($user in $users) {
    $upn         = $user.'User principal name'
    $displayName = $user.'Display name'
    $firstName   = $user.'First name'
    $lastName    = $user.'Last name'
    $title       = $user.'Title'
    $department  = $user.'Department'

    # UPN boş veya hedef domain dışındaysa atla
    if (-not $upn -or $upn -notlike "*$targetDomain") {
        "ATLANDI (domain uyuşmuyor): $upn" | Out-File $logPath -Append
        $atlanan++
        continue
    }

    # SamAccountName: UPN'in @ öncesi, - kaldır, . yerine _ koy, max 20 karakter
    $sam = ($upn.Split("@")[0]).Replace("-","").Replace(".","_")
    if ($sam.Length -gt 20) { $sam = $sam.Substring(0, 20) }

    # Kullanıcı zaten varsa atla
    if (Get-ADUser -Filter { SamAccountName -eq $sam } -ErrorAction SilentlyContinue) {
        "ATLANDI (zaten var): $sam / $upn" | Out-File $logPath -Append
        $atlanan++
        continue
    }

    try {
        $params = @{
            Name                  = $displayName
            GivenName             = $firstName
            Surname               = $lastName
            UserPrincipalName     = $upn
            SamAccountName        = $sam
            AccountPassword       = $defaultPass
            Enabled               = $true
            ChangePasswordAtLogon = $true
        }
        if ($title)      { $params['Title']      = $title }
        if ($department) { $params['Department'] = $department }

        New-ADUser @params
        "OLUŞTURULDU: $sam / $upn" | Out-File $logPath -Append
        $olusturulan++
    }
    catch {
        "HATA: $upn — $($_.Exception.Message)" | Out-File $logPath -Append
        $hatali++
    }
}

$ozet = "Tamamlandı: $(Get-Date) | Oluşturulan: $olusturulan | Atlanan: $atlanan | Hata: $hatali"
$ozet | Out-File $logPath -Append
Write-Host $ozet -ForegroundColor Cyan
Adım 4.2 — Scripti Çalıştır ve Sonuçları İzle
powershell.exe -ExecutionPolicy Bypass -File "C:\create-users.ps1"

Tamamlandığında özet çıktısı görünür:

Tamamlandı: 05/15/2026 14:23:47 | Oluşturulan: 285 | Atlanan: 5 | Hata: 0

Log dosyasını inceleyin:

Get-Content C:\create-users-log.txt | Select-Object -Last 30
Adım 4.3 — Oluşturulan Kullanıcıları Doğrula
# Toplam kullanıcı sayısını kontrol et
(Get-ADUser -Filter * -SearchBase "DC=sirket,DC=local").Count

# @sirket.com UPN'li kullanıcıları listele (ilk 10)
Get-ADUser -Filter { UserPrincipalName -like "*@sirket.com" } `
    -Properties UserPrincipalName, Department, Title |
    Select-Object Name, UserPrincipalName, Department, Title |
    Sort-Object Name |
    Select-Object -First 10 |
    Format-Table -AutoSize
Name UserPrincipalName Department Title ---- ----------------- ---------- ----- Ahmet Demir ahmet.demir@sirket.com Muhasebe Muhasebe Uzmanı Ali Yılmaz ali.yilmaz@sirket.com Bilgi İşlem Yazılım Geliştirici Ayşe Kaya ayse.kaya@sirket.com İK İK Uzmanı ...

5. Exchange Posta Kutularını Toplu Etkinleştirme

AD kullanıcıları oluşturulduktan sonra Exchange posta kutularını etkinleştirme adımı MAIL01 üzerinde çalıştırılır. Bu işlem için Exchange Management Shell gereklidir.

Adım 5.1 — Posta Kutusu Etkinleştirme Scripti

MAIL01 sunucusunda C:\enable-mailboxes.ps1 olarak kaydedin:

# enable-mailboxes.ps1 — MAIL01 üzerinde, Exchange Management Shell ile çalıştırılır
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction SilentlyContinue

$logPath     = "C:\enable-mailboxes-log.txt"
$targetUPN   = "@sirket.com"
$mailboxDB   = "Mailbox Database 0123456789"  # Get-MailboxDatabase ile öğrenin

$etkinlestirilen = 0
$atlanan         = 0
$hatali          = 0

"Başlangıç: $(Get-Date)" | Out-File $logPath

# Posta kutusu olmayan, @sirket.com UPN'li AD kullanıcılarını al
$adUsers = Get-User -RecipientTypeDetails User -Filter { UserPrincipalName -like "*@sirket.com" }

foreach ($adUser in $adUsers) {
    $upn = $adUser.UserPrincipalName

    # Zaten posta kutusu varsa atla
    if (Get-Mailbox -Identity $upn -ErrorAction SilentlyContinue) {
        "ATLANDI (posta kutusu zaten var): $upn" | Out-File $logPath -Append
        $atlanan++
        continue
    }

    try {
        Enable-Mailbox -Identity $upn -Database $mailboxDB | Out-Null
        "ETKİNLEŞTİRİLDİ: $upn" | Out-File $logPath -Append
        $etkinlestirilen++
    }
    catch {
        "HATA: $upn — $($_.Exception.Message)" | Out-File $logPath -Append
        $hatali++
    }
}

$ozet = "Tamamlandı: $(Get-Date) | Etkinleştirilen: $etkinlestirilen | Atlanan: $atlanan | Hata: $hatali"
$ozet | Out-File $logPath -Append
Write-Host $ozet -ForegroundColor Cyan
Adım 5.2 — Veritabanı Adını Öğren

Scriptteki $mailboxDB değişkenine atanacak gerçek veritabanı adını öğrenmek için:

Get-MailboxDatabase | Select-Object Name, Server
Name Server ---- ------ Mailbox Database 0123456789 MAIL01

Çıktıdaki Name değerini scriptteki $mailboxDB satırına yazın.

Adım 5.3 — Scripti Çalıştır

MAIL01 üzerinde Exchange Management Shell'i açıp çalıştırın:

powershell.exe -ExecutionPolicy Bypass -File "C:\enable-mailboxes.ps1"

Tamamlanınca özet:

Tamamlandı: 05/15/2026 15:10:33 | Etkinleştirilen: 285 | Atlanan: 0 | Hata: 0

6. Zamanlanmış Görev ile Otomatik Çalıştırma

Script'i uzaktan çalıştırmak gerektiğinde — ya da interaktif oturum açmadan zamanlı çalıştırmak istendiğinde — Windows Zamanlanmış Görevler kullanılabilir. Bu yöntem özellikle WinRM double-hop kısıtını aşmak için de kullanışlıdır: script sunucuda yerel olarak çalışacağından kimlik delegasyonu sorunu olmaz.

Adım 6.1 — Batch Dosyası Oluştur

MAIL01 üzerinde C:\run-mailbox.bat oluşturun:

@echo off
powershell.exe -ExecutionPolicy Bypass -File "C:\enable-mailboxes.ps1"
⚠️ -NonInteractive Kullanmayın: Exchange snap-in bazı ortamlarda -NonInteractive bayrağıyla yüklenemiyor. Batch dosyasında bu bayrağı kullanmaktan kaçının.
Adım 6.2 — Zamanlanmış Görevi Kayıt Et ve Çalıştır

MAIL01 üzerinde ya da uzaktan schtasks.exe ile görev oluşturun. PowerShell'in Register-ScheduledTask cmdlet'i özel karakterler içeren parolalarda sorun çıkarabilir; schtasks.exe CLI daha güvenilirdir:

# Görevi kayıt et
schtasks /create /tn "ExchangeMailboxEnable" `
         /tr "C:\run-mailbox.bat" `
         /sc ONCE /st 00:00 `
         /ru "SIRKET\administrator" /rp "Parola123!" `
         /rl HIGHEST /f

# Hemen çalıştır
schtasks /run /tn "ExchangeMailboxEnable"

# 30 saniye sonra sonucu kontrol et
Start-Sleep -Seconds 30
Get-Content C:\enable-mailboxes-log.txt | Select-Object -Last 5
ℹ️ Görev Tamamlandı mı? Log dosyasının son satırında "Tamamlandı:" ifadesi görünüyorsa script başarıyla çalışmış demektir. Görevi çalıştırdıktan sonra log dosyasını birkaç dakika bekleyerek kontrol edin; işlem kullanıcı sayısına göre zaman alabilir.

7. Sonuçların Doğrulanması

Adım 7.1 — Exchange Posta Kutusu Sayısını Kontrol Et

MAIL01 üzerinde Exchange Management Shell'de çalıştırın:

# Toplam posta kutusu sayısı
(Get-Mailbox -ResultSize Unlimited).Count

# Veritabanındaki posta kutularını listele
Get-Mailbox -Database "Mailbox Database 0123456789" -ResultSize Unlimited |
    Select-Object DisplayName, PrimarySmtpAddress, Database |
    Sort-Object DisplayName |
    Select-Object -First 10 |
    Format-Table -AutoSize
DisplayName PrimarySmtpAddress Database ----------- ------------------ -------- Ahmet Demir ahmet.demir@sirket.com Mailbox Database 0123456789 Ali Yılmaz ali.yilmaz@sirket.com Mailbox Database 0123456789 Ayşe Kaya ayse.kaya@sirket.com Mailbox Database 0123456789
Adım 7.2 — Belirli Bir Kullanıcıyı Doğrula
Get-Mailbox -Identity "ali.yilmaz@sirket.com" |
    Select-Object DisplayName, PrimarySmtpAddress, EmailAddresses, Database
DisplayName : Ali Yılmaz PrimarySmtpAddress : ali.yilmaz@sirket.com EmailAddresses : {smtp:ali_yilmaz@sirket.local, SMTP:ali.yilmaz@sirket.com} Database : Mailbox Database 0123456789
Adım 7.3 — OWA ile Test Girişi

Bir test kullanıcısıyla OWA'ya giriş yaparak posta kutusunun çalıştığını doğrulayın:

  1. Tarayıcıda https://mail.sirket.com/owa adresini açın
  2. Kullanıcı adı: ali.yilmaz@sirket.com
  3. Parola: Geçici şifre (ilk girişte değiştirme zorunlu olacak)
  4. Başarılı giriş sonrası boş gelen kutusu görünmelidir
✅ OWA girişi başarılıysa kullanıcı ve posta kutusu düzgün çalışıyor demektir.

8. Sık Karşılaşılan Sorunlar

Sorun 1: SamAccountName Çakışması
? Hata: "The operation failed because UPN value provided for addition/modification is not unique forest-wide."

Çözüm: İki farklı kullanıcının UPN'i aynıya dönüşüyor olabilir (örn. ali.yilmaz ve a.l.i.yilmaz ikisi de aliyilmaz'a dönüşür). Script $sam değişkeninin benzersiz olup olmadığını kontrol ederek çakışan kullanıcıyı atlar ve log'a yazar. Log'u inceleyerek bu kullanıcılara manuel SamAccountName atayın.

# Manuel düzeltme
Set-ADUser -Identity "aliyilmaz" -SamAccountName "aliyilmaz2"
Sorun 2: Exchange Snap-in Yüklenemiyor
? Hata: "Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 5."

Çözüm: Bu hata genellikle Exchange Management Shell yerine sıradan PowerShell'de çalıştırıldığında görülür. Exchange'in yüklü olduğu MAIL01 üzerinde Exchange Management Shell'i başlat menüsünden açın. Sıradan PowerShell'de snap-in'i yüklemek için Exchange kurulum dizinini PATH'e ekleyin:

$env:Path += ";C:\Program Files\Microsoft\Exchange Server\V15\bin"
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn
Sorun 3: Enable-Mailbox "User Not Found" Hatası
? Hata: "The operation couldn't be performed because object 'ali.yilmaz@sirket.com' couldn't be found on 'DC01.sirket.local'."

Çözüm: AD replikasyon gecikmesi yaşanıyor olabilir. DC01'de yeni oluşturulan kullanıcı henüz MAIL01'in Global Catalog'una yansımamıştır. Birkaç dakika bekleyip tekrar deneyin:

# Replikasyonu zorla (DC01 üzerinde)
repadmin /syncall /AdeP

9. Tamamlanan Kurulum — Genel Özet

Bu seri boyunca sıfırdan tam bir on-premises Exchange 2019 ortamı kurduk. Aşağıdaki tablo tüm serinin özetini sunar:

Bölüm Konu Temel Adımlar
1 Ortam Hazırlığı Makine adı, saat dilimi, güvenlik duvarı, WinRM
2 Active Directory AD DS rolü, forest kurulumu, UPN suffix, domain join
3 Exchange Ön Gereksinimleri Windows Features, VC++ 2013, URL Rewrite, UCMA, PrepareSchema/AD/Domain
4 Exchange Kurulumu setup.exe unattended kurulum, servis ve EAC doğrulaması
5 Exchange Konfigürasyonu Accepted Domain, Email Policy, Send Connector, Virtual Directory URL'leri
6 Toplu Kullanıcı Excel → AD kullanıcıları (New-ADUser), Exchange posta kutuları (Enable-Mailbox)
  • DC01 üzerinde AD forest kuruldu, sirket.local ve sirket.com UPN tanımlı
  • MAIL01 domain'e alındı, Exchange 2019 CU15 kuruldu
  • Accepted Domain, Email Policy, Send Connector yapılandırıldı
  • Virtual Directory URL'leri dış erişime uygun güncellendi
  • Excel kaynak dosyasından tüm kullanıcılar AD'ye aktarıldı
  • Tüm kullanıcılar için Exchange posta kutuları etkinleştirildi
  • OWA ve EAC ile test girişleri başarıyla tamamlandı

Bölüm 6 Özeti

  • ImportExcel modülü ile Excel dosyası PowerShell'den okundu
  • New-ADUser ile domain filtrelemesi ve hata yönetimi yapılarak toplu AD kullanıcısı oluşturuldu
  • Enable-Mailbox ile tüm kullanıcılara Exchange posta kutusu atandı
  • Double-hop kısıtı aşmak için zamanlanmış görev yöntemi kullanıldı
  • Tüm işlemler log dosyasına kaydedilerek izlenebilir hale getirildi
? Seri Tamamlandı!
Exchange Server 2019 kurulum serisinin tüm bölümleri tamamlanmıştır. Bu seri sayesinde Windows Server 2022 üzerinde sıfırdan tam bir Active Directory + Exchange 2019 ortamı kurabilir, yüzlerce kullanıcıyı otomatik olarak sisteme dahil edebilirsiniz.