شاهد الفيديو (دقيقة واحدة):
كل حساب لم يعد أحد يستخدمه ما زال يكلّفك ترخيصاً. وهو أيضاً خطر أمني، فلن ينتبه أحد إذا سجّل مهاجم الدخول إلى حساب تركه صاحبه منذ أشهر. والوضع في المدارس أسوأ، لأن كل فصل دراسي يأتي بدفعة جديدة من الطلاب، ولا ينظّف أحد حسابات الدفعة السابقة.
في فيديو إنشاء حسابات الطلاب دفعة واحدة في AD أنشأنا حسابات فصل دراسي كامل خلال دقائق. وهذا المقال عن النصف الآخر من دورة حياة الحساب: العثور على الحسابات التي لا يستخدمها أحد، وتنظيفها بأمان.
خطة آمنة من 3 مراحل
لا تحذف المستخدمين غير النشطين مباشرة، بل اعمل على مراحل:
- التقرير: اعرض قائمة بالمستخدمين الحاصلين على تراخيص ولم يسجّلوا دخولاً ناجحاً منذ 90 يوماً. لا تغيّر شيئاً في هذه المرحلة.
- الحظر وإزالة الترخيص: امنع تسجيل الدخول، وأخرِج المستخدمين من جميع الجلسات، وأزل تراخيصهم.
- الحذف بعد 30 يوماً: إذا لم يطلب أحد استعادة الحساب، فاحذفه.
وإرشادات Microsoft نفسها تقول الشيء ذاته. فلا يوجد تقرير جاهز باسم "المستخدم غير النشط"، لذلك تتخذ القرار بناءً على تاريخ آخر تسجيل دخول. ويجب أن تراعي حالات الغياب المشروعة، مثل الإجازات الطويلة أو إجازة الأمومة والأبوة. وتعتمد مؤسسات كثيرة مدة تتراوح بين 90 و180 يوماً.
ما تحتاج إليه
- PowerShell 7 وMicrosoft Graph PowerShell SDK (مجموعة أدوات التطوير الخاصة بـ Microsoft Graph)، وتثبّتها بالأمر:
Install-Module Microsoft.Graph -Scope CurrentUser. أما الوحدتان (Modules) القديمتان MSOnline وAzureAD فقد أوقفتهما Microsoft، لذلك لم تعد السكربتات التي تستخدمGet-MsolUserتعمل. - ترخيص Microsoft Entra ID P1 (أو P2) في المستأجر (Tenant)، أي بيئة Microsoft 365 الخاصة بمؤسستك. فبيانات نشاط تسجيل الدخول تحتاج إليه. ويأتي P1 مع Microsoft 365 Business Premium وE3 وE5 وA3 وA5. أما Business Basic وBusiness Standard وA1 فلا تتضمنه (ويمكنك شراء Entra ID P1 وإضافته بشكل مستقل).
- مسؤول (Admin) يملك صلاحية قراءة تقارير تسجيل الدخول وإدارة المستخدمين والتراخيص (مثلاً User Administrator + Reports Reader).
- للمستأجرين الهجينين (Hybrid) فقط: شغّل السكربت على خادم مثبّتة عليه وحدة ActiveDirectory (ضمن أدوات RSAT)، مثل خادم Entra Connect لديك.
الخطوة 1: الاتصال بـ Microsoft Graph
Connect-MgGraph -Scopes "User.ReadWrite.All","AuditLog.Read.All","GroupMember.ReadWrite.All"
الإذن AuditLog.Read.All هو الذي يسمح لك بقراءة نشاط تسجيل الدخول. أما الإذنان الآخران فيسمحان للسكربت بحظر المستخدمين وتعديل عضوية المجموعات.
الخطوة 2: العثور على المستخدمين غير النشطين وتصدير تقرير
$cutoff = (Get-Date).ToUniversalTime().AddDays(-90)
$users = Get-MgUser -All -Filter "accountEnabled eq true and userType eq 'Member'" `
-Property Id,DisplayName,UserPrincipalName,CreatedDateTime,SignInActivity,AssignedLicenses,LicenseAssignmentStates,OnPremisesSyncEnabled
$inactive = $users | Where-Object {
$last = $_.SignInActivity.LastSuccessfulSignInDateTime
$_.AssignedLicenses.Count -gt 0 -and
( ($last -and $last -lt $cutoff) -or (-not $last -and $_.CreatedDateTime -lt $cutoff) )
}
انتبه إلى هذه التفاصيل المهمة:
- استخدم
LastSuccessfulSignInDateTime. فالقيمةLastSignInDateTimeتحتسب المحاولات الفاشلة أيضاً. لذلك سيبدو الحساب "نشطاً" إذا كان المهاجمون يحاولون اختراقه باستمرار. وقيمة آخر تسجيل دخول ناجح متوفرة منذ ديسمبر 2023. - الحساب الذي لم يسجّل الدخول قط (أي القيمة فارغة) لا يُعدّ غير نشط إلا إذا أُنشئ قبل تاريخ الحد (Cutoff). وإلا فستحظر حسابات الموظفين الجدد التي أنشأتها بالأمس.
- يشمل التقرير المستخدمين الحاصلين على تراخيص فقط، لأن هذه الحسابات هي التي تكلّفك المال. أما حسابات الضيوف (Guests) فلها عملية تنظيف خاصة بها.
هذا هو شكل التقرير:
| DisplayName | UserPrincipalName | LastSuccessfulSignIn | SyncedFromAD |
|---|---|---|---|
| Abd Shamout (Spring 2026) | s2026014@mouhimen.dev | 2026-05-28 | True |
| Abd A. Shamout | abd.temp@mouhimen.dev | 2026-06-30 | False |
| Mouhimen Dev Intern | intern.mouhimen@mouhimen.dev | (never) | False |
راجع التقرير قبل أن تنتقل إلى الخطوة التالية. ثم أضف حسابات المسؤولين المخصصة للطوارئ ("break-glass") وحسابات الخدمة (Service Accounts) إلى الملف exclude.txt، واكتب اسم مستخدم واحداً (UPN) في كل سطر. فهذه الحسابات يُفترض أن تبقى دون استخدام، وآخر ما تريده هو أن تُقفلها.
الخطوة 3: حظر تسجيل الدخول وتحرير التراخيص
شغّل السكربت مرة أخرى مع المعامل -Apply:
.\Invoke-InactiveCleanup.ps1 -Apply
ينفّذ السكربت ما يلي مع كل مستخدم غير نشط:
- يحظر تسجيل الدخول (
Update-MgUser -AccountEnabled:$false) - يُخرج المستخدم من جميع الجلسات (
Revoke-MgUserSignInSession) - يزيل التراخيص
والتراخيص هي الجزء الصعب الثاني. إذا كنت تعيّن التراخيص عبر المجموعات، أي الترخيص المعتمد على المجموعات (Group-based licensing) كما فعلنا مع الطلاب، فلا يمكنك إزالتها من المستخدم مباشرة. فالأمر Set-MgUserLicense لا يزيل إلا التراخيص المعيّنة للمستخدم مباشرة. لذلك يُخرج السكربت المستخدم من مجموعة الترخيص بدلاً من ذلك (Remove-MgGroupMemberByRef).
احفظ البيانات التي تحتاج إليها قبل إزالة أي ترخيص. عند إزالة الترخيص، يبقى صندوق البريد وOneDrive محفوظَين خلال فترة سماح، ثم يُحذفان. لذلك حوّل صناديق البريد المهمة إلى صندوق بريد مشترك (Shared Mailbox)، أو امنح أحد المديرين صلاحية الوصول إلى OneDrive، أو طبّق على الحساب سياسة احتفاظ (Retention Policy) أولاً.
الجزء الصعب: المستخدمون الهجينون المُزامَنون من AD المحلي
إذا كنت تستخدم Entra Connect (أو Cloud Sync)، فإن الحساب "الحقيقي" للمستخدم موجود في Active Directory المحلي (On-premises) لديك. أما النسخة السحابية فمعظم خصائصها للقراءة فقط. لذلك إذا نفّذت Update-MgUser -AccountEnabled:$false على مستخدم مُزامَن فسيفشل الأمر. وحتى لو نجح، فستلغي المزامنة التالية هذا التغيير.
لهذا يتعامل السكربت مع المستخدمين المُزامَنين على الخادم المحلي:
Get-ADUser -Filter "UserPrincipalName -eq '$upn'" | Disable-ADAccount
Remove-ADGroupMember -Identity "Students-Spring2026" -Members $adUser -Confirm:$false
بعد دورة المزامنة التالية يُحظر الحساب السحابي ويختفي الترخيص المعتمد على المجموعة. وتعمل المزامنة كل 30 دقيقة افتراضياً، ويمكنك تشغيلها فوراً بالأمر Start-ADSyncSyncCycle -PolicyType Delta على خادم Entra Connect.
الحذف بعد 30 يوماً
انتظر 30 يوماً. إذا لم يحتج أحد إلى الحساب، فاحذفه:
- الحسابات السحابية فقط (Cloud-only): نفّذ
Remove-MgUser -UserId <id>. سينتقل الحساب إلى قائمة المستخدمين المحذوفين (Deleted users) ويبقى فيها 30 يوماً إضافية، لذلك ما زال بإمكانك استعادته. - الحسابات المُزامَنة: احذفها في AD (
Remove-ADUser)، أو انقلها إلى وحدة تنظيمية (OU) لا تُزامنها.
شغّله كل شهر
جدوِل التقرير ليعمل في اليوم الأول من كل شهر باستخدام Task Scheduler أو Azure Automation. وإذا أردت أن يعمل دون تدخّل منك، فاستخدم تسجيل تطبيق (App Registration) مع شهادة (Certificate) بدلاً من تسجيل دخولك الشخصي:
Connect-MgGraph -ClientId "<app-id>" -TenantId "<tenant-id>" -CertificateThumbprint "<thumbprint>"
امنح التطبيق أذونات التطبيق (Application permissions) التالية: User.ReadWrite.All وAuditLog.Read.All وGroupMember.ReadWrite.All. وأنصحك بتشغيل التقرير تلقائياً، مع إبقاء -Apply خطوة تشغّلها بنفسك بعد أن تراجع ملف CSV.
السكربت الكامل
نزّل الملفين Invoke-InactiveCleanup.ps1 وexclude.txt: [attach the files when you publish]
.\Invoke-InactiveCleanup.ps1 # report only (safe, changes nothing)
.\Invoke-InactiveCleanup.ps1 -Days 120 # different threshold
.\Invoke-InactiveCleanup.ps1 -Apply # block sign-in + remove licenses
قائمة التحقق
- تثبيت Microsoft Graph PowerShell (وليس MSOnline/AzureAD)
- وجود Entra ID P1 في المستأجر
- إضافة حسابات مسؤولي الطوارئ (Break-glass) وحسابات الخدمة إلى
exclude.txt - مراجعة التقرير قبل تشغيل
-Apply - حفظ صناديق البريد المهمة وبيانات OneDrive
- معالجة المستخدمين المُزامَنين في AD المحلي
- جدولة الحذف بعد 30 يوماً
- جدولة التقرير الشهري
المصادر
- Microsoft Learn: كيفية إدارة حسابات المستخدمين غير النشطة في Microsoft Entra ID
- Microsoft Graph: نوع المورد signInActivity
- Microsoft Graph PowerShell: Remove-MgGroupMemberByRef
- Office 365 for IT Pros: Entra ID يسجّل آخر تسجيل دخول ناجح
شاهد الفيديو:
Abd Almouhimen Shamout، Take away support: حلول لمشكلات تقنية المعلومات تصلك في أقل من دقيقتين. المزيد على mouhimen.dev.
هذا المقال ترجمة عربية للمقال الأصلي باللغة الإنجليزية للكاتب عبد المهيمن شموط على mouhimen.dev.
