Hemen Ara WhatsApp
KOBİ Siber Güvenlik

AD Toplu User Import — İK CSV'sinden 50 Çalışan Tek Komutta

AD'ye 50+ kullanıcı toplu ekleme — İK CSV'sinden PowerShell ile. OU placement, password policy uyumu, group membership, email attribute.

“İlk Hafta 50 Stajyer Başlıyor”

İK müdürü bir Excel gönderdi: 50 üniversite stajyeri, her biri için:

  • Ad, Soyad
  • Departman (Mühendislik, İK, Finans, Pazarlama)
  • Başlangıç tarihi
  • Yönetici adı
  • Iletişim bilgileri

BT uzmanı Zeynep: “Tek tek ADUC ile açsam 3 gün sürer. PowerShell ile 5 dakika.”

Bu yazı pratik bulk import örneği — İK formatından AD user’a.

CSV Şablonu

İK’nın paylaştığı Excel’i CSV’ye export et (Save As > CSV UTF-8):

FirstName,LastName,Department,JobTitle,Manager,StartDate,Email
Ahmet,Çelik,Mühendislik,Junior Developer,ayse.demir,2024-06-01,ahmet.celik@firma.com.tr
Ayşe,Yılmaz,Pazarlama,Marketing Intern,mehmet.kara,2024-06-01,ayse.yilmaz@firma.com.tr
Mehmet,Kara,Finans,Finance Intern,can.aydin,2024-06-01,mehmet.kara@firma.com.tr
...

Hızlı Çözüm (TL;DR)

Import-Csv .\stajyerler.csv -Encoding UTF8 | ForEach-Object {
    $password = "Stajyer!2024$(Get-Random -Max 999)"
    $sam = "$($_.FirstName.ToLower()).$($_.LastName.ToLower())" -replace "[ğĞ]","g" -replace "[üÜ]","u" -replace "[şŞ]","s" -replace "[ıİ]","i" -replace "[öÖ]","o" -replace "[çÇ]","c"
    
    New-ADUser `
        -Name "$($_.FirstName) $($_.LastName)" `
        -GivenName $_.FirstName `
        -Surname $_.LastName `
        -SamAccountName $sam `
        -UserPrincipalName "$sam@corp.firma.com.tr" `
        -EmailAddress $_.Email `
        -Department $_.Department `
        -Title $_.JobTitle `
        -Manager (Get-ADUser -Filter "SamAccountName -eq '$($_.Manager)'").DistinguishedName `
        -Path "OU=Interns,OU=Users,DC=corp,DC=firma,DC=com,DC=tr" `
        -AccountPassword (ConvertTo-SecureString $password -AsPlainText -Force) `
        -ChangePasswordAtLogon $true `
        -Enabled $true
    
    Write-Host "Created: $sam — Password: $password"
}

Adım 1: Türkçe Karakter Sorunu

AD SamAccountName’de Türkçe karakter sorun yaratır:

  • mehmet.yılmaz → login problem
  • çağatay → path, search bozulur

Çözüm: ASCII translit:

function ConvertTo-ASCII {
    param([string]$Input)
    $Input -replace "[ğĞ]","g" -replace "[üÜ]","u" -replace "[şŞ]","s" -replace "[ıİ]","i" -replace "[öÖ]","o" -replace "[çÇ]","c"
}

# Test
ConvertTo-ASCII "mehmet.yılmaz"  # → mehmet.yilmaz
ConvertTo-ASCII "çağatay"        # → cagatay

Adım 2: Username Naming Convention

Standart format seç:

  • Format A: ad.soyad (örn. mehmet.yilmaz) — en yaygın
  • Format B: asoyad (örn. myilmaz) — kısa ama çakışma riski
  • Format C: adsoyad (ör. mehmetyilmaz) — uzun ama net

Zeynep Format A’yı seçti.

Çakışma kontrolü:

$desired = "mehmet.yilmaz"
if (Get-ADUser -Filter "SamAccountName -eq '$desired'") {
    # Çakışma — ekle suffix
    $desired = "$desired.2"
}

Adım 3: Güvenli Geçici Şifre Üret

Default şifre tüm stajyerlerde aynı → güvenlik riski. Random:

function New-TempPassword {
    $chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%"
    -join (1..12 | ForEach-Object { $chars[(Get-Random -Max $chars.Length)] })
}

Her kullanıcı için unique + karmaşık şifre. İlk girişte zorla değiştirme.

Adım 4: OU Placement

Tüm stajyerler tek OU’da:

OU=Interns,OU=Users,DC=corp,DC=firma,DC=com,DC=tr

Bu OU’da özel GPO’lar olabilir:

  • İnternet kısıtlı
  • Departman spesifik klasörlere read-only
  • Stajyer grubuna ek yetki verilemez

Yaşam döngüsü OU’sı avantajı — stajyer ayrılınca tek komutla tamamını ayarla.

Adım 5: Kapsamlı Script

#Requires -Module ActiveDirectory

# Config
$OUPath = "OU=Interns,OU=Users,DC=corp,DC=firma,DC=com,DC=tr"
$Domain = "corp.firma.com.tr"
$DefaultGroup = "Interns-Group"
$OutputCSV = "C:\Temp\yeni-stajyerler-credentials.csv"

$results = @()

# Türkçe ASCII dönüşüm
function ConvertTo-ASCII {
    param([string]$input)
    $input -replace "[ğĞ]","g" -replace "[üÜ]","u" -replace "[şŞ]","s" `
           -replace "[ıİ]","i" -replace "[öÖ]","o" -replace "[çÇ]","c"
}

# Random password
function New-TempPassword {
    $chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789!@#$%"
    -join (1..12 | ForEach-Object { $chars[(Get-Random -Max $chars.Length)] })
}

Import-Csv .\stajyerler.csv -Encoding UTF8 | ForEach-Object {
    try {
        # Username üret
        $first = ConvertTo-ASCII $_.FirstName
        $last = ConvertTo-ASCII $_.LastName
        $sam = "$first.$last".ToLower()
        
        # Çakışma varsa suffix ekle
        $originalSam = $sam
        $counter = 2
        while (Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue) {
            $sam = "$originalSam.$counter"
            $counter++
        }
        
        # Şifre
        $tempPassword = New-TempPassword
        
        # Manager DN (varsa)
        $managerDN = $null
        if ($_.Manager) {
            $mgrUser = Get-ADUser -Filter "SamAccountName -eq '$($_.Manager)'" -ErrorAction SilentlyContinue
            if ($mgrUser) { $managerDN = $mgrUser.DistinguishedName }
        }
        
        # User oluştur
        $userParams = @{
            Name                  = "$($_.FirstName) $($_.LastName)"
            GivenName             = $_.FirstName
            Surname               = $_.LastName
            SamAccountName        = $sam
            UserPrincipalName     = "$sam@$Domain"
            EmailAddress          = $_.Email
            Department            = $_.Department
            Title                 = $_.JobTitle
            Path                  = $OUPath
            AccountPassword       = (ConvertTo-SecureString $tempPassword -AsPlainText -Force)
            ChangePasswordAtLogon = $true
            Enabled               = $true
            AccountExpirationDate = (Get-Date $_.StartDate).AddMonths(6) # 6 aylık stajyer
        }
        if ($managerDN) { $userParams.Manager = $managerDN }
        
        New-ADUser @userParams
        
        # Default gruba ekle
        Add-ADGroupMember -Identity $DefaultGroup -Members $sam
        
        # Departman grubu
        $deptGroup = "Dept-$($_.Department)"
        if (Get-ADGroup -Filter "Name -eq '$deptGroup'" -ErrorAction SilentlyContinue) {
            Add-ADGroupMember -Identity $deptGroup -Members $sam
        }
        
        # Sonuç kaydet
        $results += [PSCustomObject]@{
            Username    = $sam
            Password    = $tempPassword
            Email       = $_.Email
            Department  = $_.Department
            Status      = "Created"
        }
        
        Write-Host "✓ Created: $sam" -ForegroundColor Green
    }
    catch {
        $results += [PSCustomObject]@{
            Username    = $sam
            Password    = "-"
            Email       = $_.Email
            Department  = $_.Department
            Status      = "Failed: $($_.Exception.Message)"
        }
        Write-Host "✗ Failed: $sam$($_.Exception.Message)" -ForegroundColor Red
    }
}

# Credentials'ı secure CSV'ye yaz
$results | Export-Csv $OutputCSV -Encoding UTF8 -NoTypeInformation

Write-Host ""
Write-Host "=== Özet ===" -ForegroundColor Cyan
Write-Host "Toplam:       $($results.Count)"
Write-Host "Başarılı:     $(($results | Where Status -eq 'Created').Count)"
Write-Host "Başarısız:    $(($results | Where Status -ne 'Created').Count)"
Write-Host "Credentials CSV: $OutputCSV"

Çalıştırma

Run:

.\Bulk-Import-Interns.ps1

Output:

✓ Created: ahmet.celik
✓ Created: ayse.yilmaz
✓ Created: mehmet.kara
...

=== Özet ===
Toplam:       50
Başarılı:     48
Başarısız:    2 (Ahmet Çelik - password policy fail, Ali Demir - duplicate sam)

Credentials CSV’yi güvenli paylaşım:

  • Bitwarden’a import
  • Her çalışana kendi şifresini kişisel yolla (manager email, güvenli SMS)
  • CSV dosyasını sil veya encrypted folder’a taşı

Rollback

Yanlışlıkla import yapıldıysa hızla geri al:

Import-Csv .\stajyerler.csv | ForEach-Object {
    $sam = ConvertTo-ASCII "$($_.FirstName).$($_.LastName)".ToLower()
    
    if (Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue) {
        Remove-ADUser -Identity $sam -Confirm:$false
        Write-Host "Removed: $sam"
    }
}

Eğer AD Recycle Bin aktif ise restore mümkün.

İleri Seviye — Idempotent Import

Script tekrar çalıştırılabilir olsun (çakışma olmadan):

# Önce var mı kontrol
$existing = Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue

if ($existing) {
    # Update mevcut user
    Set-ADUser -Identity $sam -Department $_.Department -Title $_.JobTitle -EmailAddress $_.Email
    Write-Host "Updated: $sam"
} else {
    # Yeni oluştur
    New-ADUser ...
    Write-Host "Created: $sam"
}

Bu pattern “upsert” — var olanı güncelle, yoksa oluştur.

HR Integration — Otomasyon

Manuel CSV yerine canlı İK integration:

  • Workday API / SAP SuccessFactors API / BambooHR API
  • Scheduled task: her gün yeni çalışanları çek, AD’ye push
  • Azure AD Connect veya MIM (Microsoft Identity Manager) enterprise için

Küçük-orta firma için haftalık CSV yeterli.

Dikkat Edilecek Noktalar

1. Password Policy Uyumu

Random password üretirsen domain password policy’sine uyumlu olmalı:

  • Min length (örn. 12 karakter)
  • Complexity (büyük/küçük/rakam/özel)

Script’imdeki $chars kombinasyonu çoğu policy’yi karşılar.

2. Email Kontrolü

CSV’deki email doğru formatta mı? Yanlış e-mail → GAL’de yanlış görünür, mail routing bozuk.

$emailPattern = "^[\w\.-]+@[\w\.-]+\.\w+$"
if ($_.Email -notmatch $emailPattern) {
    throw "Invalid email: $($_.Email)"
}

3. License Assignment (M365)

M365 lisansı ayrı — Azure AD Connect sync sonrası veya direct M365 Admin API ile:

# Azure AD PowerShell
Connect-MsolService
Set-MsolUserLicense -UserPrincipalName "ahmet.celik@firma.com.tr" -AddLicenses "contoso:ENTERPRISEPACK"

4. Manager-Direct Report Zinciri

Her stajyerin yöneticisi CSV’de var olan bir kullanıcı. Manager atlanıp sonra eklenebilir (2. pass):

# 1. Pass: Tüm user oluştur (manager null)
# 2. Pass: Her user için manager attribute ekle

İlgili Rehberler


AD automation, HR-AD integration ve PowerShell scripting uzman desteği için? Kozyatağı Bilişim AD management paketimiz. Teknik görüşme.

Bu konuda destek mi arıyorsunuz?

Ücretsiz keşif görüşmesi ile mevcut altyapınızı analiz edelim ve size özel bir yol haritası çıkaralım.

Ücretsiz Keşif Planla →

İlgili Hizmetlerimiz

Bu konuyla ilgili sunduğumuz kurumsal IT hizmetleri:

İstanbul Hizmet Bölgelerimiz

İlgili Rehberler