2024 Sonrası Tek Doğru: Microsoft Graph PowerShell

Microsoft Mart 2024'te MSOnline ve AzureAD/AzureADPreview modüllerinin authentication endpoint'lerini kapattı. Bu modüller artık çalışmıyor. Tek alternatif: Microsoft.Graph PowerShell SDK.

EskiYeni
Get-MsolUserGet-MgUser
Get-AzureADUserGet-MgUser
Set-MsolUserLicenseSet-MgUserLicense
Get-MsolGroupGet-MgGroup
Get-MsolDirectoryRoleGet-MgDirectoryRole

1) Modülü Kur

Install-Module Microsoft.Graph -Scope CurrentUser -Force
Update-Module Microsoft.Graph

# Sadece sık kullanılan alt modülleri yüklemek istersen (1 GB değil 200 MB):
Install-Module Microsoft.Graph.Authentication
Install-Module Microsoft.Graph.Users
Install-Module Microsoft.Graph.Groups
Install-Module Microsoft.Graph.Identity.SignIns

2) İlk Bağlantı (Modern Auth + MFA)

Connect-MgGraph -Scopes "User.Read.All", "Group.Read.All"

Tarayıcı popup → admin hesabı + MFA → onay. İlk seferde tenant admin'in "consent on behalf of organization" işaretlemesi gerekir.

3) Scope (Permission) Cheatsheet

ScopeNe Yapar?
User.Read.AllTüm kullanıcıları oku
User.ReadWrite.AllTüm kullanıcıları oku + yaz
Group.ReadWrite.AllGrup oluştur, sil, üye ekle
Directory.ReadWrite.AllTüm directory (lisans, role, tenant ayarı)
AuditLog.Read.AllSign-in log + audit log
RoleManagement.ReadWrite.DirectoryRole atama
Policy.ReadWrite.ConditionalAccessCA politikası yönetimi
Mail.SendApplication olarak mail gönder
Sites.ReadWrite.AllSharePoint site yönetimi
Files.ReadWrite.AllOneDrive/SharePoint dosya yönetimi

4) Bağlantıyı Kontrol Et

Get-MgContext
# AppName, Account, Scopes, TenantId döner

5) Bağlantıyı Kapat

Disconnect-MgGraph

10 Hazır Komut

1. Tüm aktif kullanıcıları listele

Get-MgUser -All -Filter "accountEnabled eq true" `
  -Property Id, DisplayName, UserPrincipalName, JobTitle, Department |
  Select DisplayName, UserPrincipalName, Department |
  Export-Csv .\active_users.csv -NoTypeInformation -Encoding UTF8

2. Lisans atanmış kullanıcılar

Get-MgUser -All -Property AssignedLicenses, DisplayName |
  Where-Object { $_.AssignedLicenses.Count -gt 0 } |
  Select DisplayName, @{n="LicCount";e={$_.AssignedLicenses.Count}}

3. Belirli kullanıcının grupları

Get-MgUserMemberOf -UserId ahmet@firmaniz.com |
  ForEach-Object { $_.AdditionalProperties["displayName"] }

4. Yeni grup oluştur

$params = @{
  DisplayName = "Pazarlama Ekibi"
  MailNickname = "pazarlama"
  MailEnabled = $false
  SecurityEnabled = $true
  Description = "Pazarlama departmanı kullanıcıları"
}
New-MgGroup -BodyParameter $params

5. Gruba kullanıcı ekle

$grp = Get-MgGroup -Filter "displayName eq \u0027Pazarlama Ekibi\u0027"
$user = Get-MgUser -UserId ahmet@firmaniz.com

New-MgGroupMember -GroupId $grp.Id -DirectoryObjectId $user.Id

6. Son 7 gün giriş başarısız sign-in'leri

$cutoff = (Get-Date).AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ssZ")

Get-MgAuditLogSignIn -Filter "createdDateTime ge $cutoff and status/errorCode ne 0" -Top 100 |
  Select CreatedDateTime, UserPrincipalName, AppDisplayName,
    @{n="Error";e={$_.Status.ErrorCode}},
    @{n="Reason";e={$_.Status.FailureReason}},
    @{n="IP";e={$_.IpAddress}} |
  Export-Csv .\failed_signins.csv -NoTypeInformation

7. MFA durumu raporu

Get-MgUser -All -Property Id, UserPrincipalName | ForEach-Object {
  $methods = Get-MgUserAuthenticationMethod -UserId $_.Id
  $hasMFA = $methods.AdditionalProperties.\u0027@odata.type\u0027 -match "microsoftAuthenticator|fido2|sms|softwareOath"

  [PSCustomObject]@{
    User = $_.UserPrincipalName
    MFAEnabled = $hasMFA -ne $null
    MethodCount = $methods.Count
  }
} | Export-Csv .\mfa_status.csv -NoTypeInformation

8. Yeni kullanıcı oluştur

$tempPass = -join ((33..126) | Get-Random -Count 16 | %{[char]$_})

$params = @{
  AccountEnabled = $true
  DisplayName = "Mehmet Demir"
  MailNickname = "mehmet"
  UserPrincipalName = "mehmet@firmaniz.com"
  PasswordProfile = @{
    Password = $tempPass
    ForceChangePasswordNextSignIn = $true
  }
  UsageLocation = "TR"
  JobTitle = "Yazılım Geliştirici"
  Department = "Bilgi İşlem"
}

New-MgUser -BodyParameter $params
Write-Host "Geçici parola: $tempPass"

9. Kullanıcıya lisans ata

# Önce SKU ID'sini bul
$sku = Get-MgSubscribedSku -All |
  Where-Object SkuPartNumber -eq "O365_BUSINESS_ESSENTIALS"

Set-MgUserLicense -UserId mehmet@firmaniz.com `
  -AddLicenses @(@{SkuId = $sku.SkuId}) `
  -RemoveLicenses @()

10. Conditional Access politikalarını listele

Get-MgIdentityConditionalAccessPolicy |
  Select DisplayName, State, CreatedDateTime, ModifiedDateTime |
  Sort ModifiedDateTime -Descending

App-Only (Sertifika) Authentication

Cron / scheduled task için MFA popup'ı çıkmaması için:

  1. Entra Admin → App registrations → New registration
  2. Adı: PS-Automation
  3. API permissions → Microsoft Graph → Application permissions → gerekli scope'ları ekle (örn. User.Read.All)
  4. "Grant admin consent"
  5. Certificates & secrets → Upload sertifika (PFX)
Connect-MgGraph -ClientId "00000000-0000-0000-0000-000000000000" `
  -TenantId "11111111-1111-1111-1111-111111111111" `
  -CertificateThumbprint "ABCDEF..."

Sık Karşılaşılan Hatalar

"Insufficient privileges to complete the operation"

Scope eksik. Connect-MgGraph'ı doğru scope ile yeniden çalıştır.

"Forbidden — admin consent required"

App permission tenant'ta consent almamış. Entra Admin → App registrations → API permissions → Grant admin consent.

"Throttling — Too many requests"

Graph saatte 10K istek limiti. Try/catch + sleep ile retry mantığı:

try {
  Get-MgUser -All
} catch {
  if ($_.Exception.Response.StatusCode -eq 429) {
    Start-Sleep -Seconds 30
    # retry
  }
}

SSS

MSOnline modülü hâlâ kurulabiliyor — neden çalışmıyor?

Modül kurulur ama Microsoft authentication endpoint'i kapattı. Connect-MsolService hata verir.

Tüm Graph SDK 1 GB — gereksiz mi?

Evet — sadece kullandığın alt modülleri kur (Authentication + Users + Groups yeterli). Toplam ~200 MB.

App-only ile MFA popup çıkmıyor mu?

Hayır — sertifika tabanlı, headless. Cron için ideal.

Graph Explorer (web) ile PowerShell aynı mı?

Evet — ikisi de aynı API endpoint'lerini çağırır. PowerShell otomasyon için, Explorer test için.

Get-MgUser yavaş — paging?

Default 100 kayıt. -All tüm kayıtları getirir ama yavaş. Filtrele: -Filter "department eq \u0027IT\u0027".

Microsoft Graph PowerShell otomasyon paketleri için bize ulaşın → Hazır script kütüphanesi + uzaktan kurulum.