Neden Önemli? — "Hayalet Lisans" Sorunu
Türkiye'deki şirketlerin %40'ı, ortalama olarak kullanıcı sayısının %15-25'i kadar boşta lisans bulundurur. Sebep:
- Çalışan ayrılır, IT lisansı kaldırmayı unutur
- Kısa vadeli proje çalışanları kalıcı olarak duruyor sanılır
- Test hesapları silinmiyor
- Yıl sonu lisans audit'i yapılmıyor
Örnek: 100 kullanıcılı şirket, 20 boş lisans (Business Standard $12.50). Yıllık $3.000 (~120.000 TL) çöpe atılan para.
1) Microsoft 365 Admin Center'dan "Inactive Users" Raporu
Hızlı manuel yöntem:
admin.microsoft.com → Reports → Usage
- "Active users" raporu seç
- "180 days" zaman aralığı
- "Last activity date" sütununu sıralayın
- Boş veya çok eski olanlar = candidate
Limit: Sadece son 180 gün. Daha eski için PowerShell şart.
2) Microsoft Graph PowerShell ile Detaylı Rapor
Modül kurulumu
Install-Module Microsoft.Graph -Scope CurrentUser
Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All","Directory.ReadWrite.All"
90 günden fazla giriş yapmamış kullanıcılar
$cutoff = (Get-Date).AddDays(-90)
$inactive = Get-MgUser -All -Property `
Id, DisplayName, UserPrincipalName, AccountEnabled, `
SignInActivity, AssignedLicenses |
Where-Object {
$_.AccountEnabled -eq $true -and
$_.AssignedLicenses.Count -gt 0 -and
(
($_.SignInActivity.LastSignInDateTime -lt $cutoff) -or
($null -eq $_.SignInActivity.LastSignInDateTime)
)
}
$inactive |
Select DisplayName, UserPrincipalName,
@{n="LastSignIn";e={$_.SignInActivity.LastSignInDateTime}},
@{n="LicenseCount";e={$_.AssignedLicenses.Count}} |
Export-Csv .\inactive_users.csv -NoTypeInformation -Encoding UTF8
Write-Host "$($inactive.Count) inactive kullanıcı bulundu."
3) Lisans Detaylarını Almak (Hangi SKU?)
$skuMap = @{}
Get-MgSubscribedSku | ForEach-Object {
$skuMap[$_.SkuId] = $_.SkuPartNumber
}
$inactive | ForEach-Object {
$names = $_.AssignedLicenses.SkuId | ForEach-Object { $skuMap[$_] }
[PSCustomObject]@{
User = $_.UserPrincipalName
LastSignIn = $_.SignInActivity.LastSignInDateTime
Licenses = $names -join ", "
}
} | Export-Csv .\inactive_with_skus.csv -NoTypeInformation
Yaygın SKU adları
| SkuPartNumber | Plan adı |
| O365_BUSINESS_ESSENTIALS | Microsoft 365 Business Basic |
| O365_BUSINESS_PREMIUM | Microsoft 365 Business Standard |
| SPB | Microsoft 365 Business Premium |
| EXCHANGESTANDARD | Exchange Online Plan 1 |
| EXCHANGEENTERPRISE | Exchange Online Plan 2 |
| ENTERPRISEPACK | Office 365 E3 |
4) Toplu Lisans Kaldırma Scripti
DİKKAT: Lisans kaldırılınca posta kutusu 30 gün soft-deleted olur. Önce mailbox'ı PST export etmeniz veya Shared Mailbox'a çevirmeniz önerilir.
# CSV'den oku, manuel onay sonrası kaldır
$users = Import-Csv .\inactive_with_skus.csv
foreach ($u in $users) {
$mgUser = Get-MgUser -UserId $u.User -Property AssignedLicenses
$skusToRemove = $mgUser.AssignedLicenses | Select -ExpandProperty SkuId
Write-Host "Kaldırılacak: $($u.User) — $($skusToRemove -join ', ')"
$confirm = Read-Host "Devam? (y/n)"
if ($confirm -eq 'y') {
Set-MgUserLicense -UserId $u.User -AddLicenses @() -RemoveLicenses $skusToRemove
Write-Host " ✓ Kaldırıldı."
}
}
5) Çıkış Yapan Çalışan İçin Doğru Süreç
Sadece lisans kaldırmak yetmez. Tam süreç:
- Block sign-in: Entra Admin → kullanıcı → Block sign-in: Yes
- Tüm cihaz oturumlarını sonlandır: Authentication methods → Revoke MFA sessions
- Mail forward: Eski → yeni sorumlu (30-60 gün)
- OneDrive ownership transfer: SharePoint Admin → User'ın OneDrive'ına kendine erişim ver, dosyaları taşı
- Litigation Hold (KVKK için): mailbox 7 yıl sakla
- Mailbox → Shared Mailbox: Lisans iade ama mail erişilebilir kalır
- Lisans kaldır
- 30 gün sonra: User'ı sil (soft delete, 30 gün daha geri alınabilir)
6) Mailbox'ı Shared Mailbox'a Çevirme (Lisans Tasarrufu)
Connect-ExchangeOnline
Set-Mailbox -Identity eski@firmaniz.com -Type Shared
# Erişim izni veriyoruz: yeni sorumlu okusun
Add-MailboxPermission -Identity eski@firmaniz.com `
-User yenisorumlu@firmaniz.com -AccessRights FullAccess
Shared Mailbox 50 GB'a kadar ücretsiz. Eski çalışanın gelen maillerini görmek için ideal.
Aylık Otomatik İzleme
# cron: aylık 1'inde inactive raporu mail at
$inactive = ... # yukarıdaki sorgu
if ($inactive.Count -gt 0) {
$body = "Kullanılmayan lisans tespit edildi: $($inactive.Count) kullanıcı.`n`n"
$body += ($inactive | Format-Table -AutoSize | Out-String)
Send-MgUserMail -UserId admin@firmaniz.com -BodyParameter @{
Message = @{
Subject = "[$(Get-Date -F yyyy-MM)] Inactive User Raporu"
Body = @{ ContentType = "Text"; Content = $body }
ToRecipients = @(@{ EmailAddress = @{ Address = "it@firmaniz.com" } })
}
}
}
SSS
SignInActivity neden bazı kullanıcılarda boş?
SignInActivity için Entra ID P1 lisansı (en az 1 admin'de) gerekir. Free tenant'larda alan boş döner.
30 günde geri alınabilir mi?
Evet — kullanıcı silindikten sonra 30 gün içinde Restore-MgUser ile geri alınabilir. Lisanslar otomatik geri atanmaz, manuel ekle.
Mailbox Shared'a çevirildikten sonra lisans hemen kaldırılabilir mi?
Hayır — 30 gün bekleyin. Yoksa shared mailbox'ta gecikme ile sıkıntı olur.
Office uygulamaları lisans kalkınca kapatılır mı?
Evet — 30 gün grace period sonra Word/Excel'de "Aktivasyon gerekli" çıkar.
Kullanılmayan lisansı sözleşme sonu beklemeden iade edebilir miyim?
CSP partneriyseniz aylık iade var (5 gün cancel window). Yıllık taahhütte sözleşme sonu beklenir, sayı azaltılır.
Lisans audit + maliyet optimizasyonu için bize ulaşın → Yıllık ücretsiz lisans temizliği yapıyoruz.