# Microsoft 365

> Microsoft 365 عبر Microsoft Graph: النطاقات وDNS وصناديق البريد المرخّصة والحدود.

يدير بريد Microsoft 365 لنطاق ما عبر Microsoft Graph: تسجيل النطاق والتحقق منه، ونشر سجلات DNS التي تتطلبها الخدمة، وإنشاء صناديق البريد كمستخدمين مرخّصين.

هذه الصفحة صريحة على غير العادة بشأن الحدود، لأن ثلاثة أشياء يتوقعها الناس لا يمكن الوصول إليها عبر Graph أصلًا. يرفضها mailctl بدل قبولها وعدم فعل شيء.

## ما يستطيع Graph فعله وما لا يستطيع

**جدول 1. مدعوم**

  
| القدرة | نقطة النهاية |
| --- | --- |
| 

إضافة نطاق إلى المستأجر

 | 

`POST /domains`

 |
| 

قراءة سجل الملكية

 | 

`GET /domains/{id}/verificationDnsRecords`

 |
| 

التحقق من الملكية

 | 

`POST /domains/{id}/verify`

 |
| 

التصريح بخدمات النطاق

 | 

`PATCH /domains/{id}`

 |
| 

قراءة سجلات DNS المطلوبة

 | 

`GET /domains/{id}/serviceConfigurationRecords`

 |
| 

سرد مستخدمي النطاق

 | 

`GET /domains/{id}/domainNameReferences/microsoft.graph.user`

 |
| 

إنشاء مستخدم

 | 

`POST /users`

 |
| 

تعيين ترخيص

 | 

`POST /users/{id}/assignLicense`

 |
| 

قراءة مخزون التراخيص

 | 

`GET /subscribedSkus`

 |

<table class="tableblock frame-all grid-all stretch"><caption class="title">جدول 2. غير مدعوم، ولماذا</caption> <colgroup><col style="width: 25%;"> <col style="width: 75%;"></colgroup><tbody><tr><td class="tableblock halign-left valign-top"><p class="tableblock">الأسماء البديلة</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">يوثّق Graph الحقل <code>proxyAddresses</code> على أنه للقراءة فقط، ولا يُحدَّث إلا عبر مركز إدارة Microsoft 365. العنوان الأساسي وحده قابل للكتابة. وجود كتلة <code>aliases</code> على نطاق <code>ms365</code> خطأ تحقق.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock">الالتقاط الشامل</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">يتطلب قاعدة نقل في Exchange، ولا واجهة لها في Graph. وجود كتلة <code>catchAll</code> خطأ تحقق.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock">تفعيل DKIM</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">لا يمكن استنتاج أهداف CNAME، فالصيغة الحالية تتضمن حرف تقسيم خاصًا بكل مستأجر. وتقول وثائق Microsoft نفسها إن القيم المنشورة للتوضيح فقط، ويجب قراءتها من بوابة Defender أو من Exchange Online PowerShell.</p></td></tr></tbody></table>

كان بإمكان mailctl استدعاء PowerShell من أجل DKIM. لكنه لا يفعل، لأن ذلك سيجعل `pwsh` ووحدة Exchange متطلبات تشغيل إلزامية لملف تنفيذي له اعتمادية واحدة فقط فيما عدا ذلك.

## الإعداد

### 1\. سجّل تطبيقًا

في Microsoft Entra، سجّل تطبيقًا وامنحه صلاحيات **تطبيق** بموافقة المسؤول:

-   `Domain.ReadWrite.All`
    
-   `User.ReadWrite.All`
    
-   `Organization.Read.All`
    

ثم صدّر القيم الثلاث:

```properties
MS365_TENANT_ID=...
MS365_CLIENT_ID=...
MS365_CLIENT_SECRET=...
```

### 2\. اضبط النطاق

```yaml
domains:
  - name: example.com
    mail:
      provider: ms365
      ms365:
        license: BUSINESS_BASIC
        usageLocation: DE
        dkimCnames:
          - selector1-example-com._domainkey.contoso.n-v1.dkim.mail.microsoft
          - selector2-example-com._domainkey.contoso.n-v1.dkim.mail.microsoft
    mailboxes:
      - address: a.person@example.com
        displayName: A Person
```

<table class="tableblock frame-all grid-all stretch"><colgroup><col style="width: 25%;"> <col style="width: 75%;"></colgroup><tbody><tr><td class="tableblock halign-left valign-top"><p class="tableblock"><code>license</code></p></td><td class="tableblock halign-left valign-top"><p class="tableblock">قيمة <code>skuPartNumber</code> مثل <code>BUSINESS_BASIC</code>، لا معرّف <code>skuId</code> بصيغة GUID. رقم الجزء ثابت وظاهر في مركز الإدارة؛ أما GUID فليس كذلك. يُحلَّل مقابل <code>/subscribedSkus</code>.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock"><code>usageLocation</code></p></td><td class="tableblock halign-left valign-top"><p class="tableblock">رمز من حرفين وفق ISO 3166-1 alpha-2. لا يعيّن Graph ترخيصًا دونه، لذا يطلبه mailctl مقدّمًا بدل أن يفشل وقت التطبيق.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock"><code>dkimCnames</code></p></td><td class="tableblock halign-left valign-top"><p class="tableblock">اختياري. الهدفان المنسوخان مرة واحدة من بوابة Defender، لـ <code>selector1</code> و<code>selector2</code> بهذا الترتيب. إن أُعطيهما، ينشر mailctl سجلَّي CNAME ويدقّقهما كأي سجل آخر. احذفهما فيبقى DKIM خارج mailctl.</p></td></tr></tbody></table>

### 3\. طبّق مرتين

يُتوقَّع أن يفعل التطبيق الأول أقل مما قد تظن، وهذا مقصود في التصميم وليس خللًا.

لا توجد `verificationDnsRecords` و`serviceConfigurationRecords` حتى يُضاف النطاق إلى المستأجر، وقراءة الحالة يجب ألا تغيّر شيئًا أبدًا. فيكون التسلسل:

1.  التطبيق الأول: يضيف النطاق إلى المستأجر. لا يُعرف في هذه المرحلة إلا سجلات DKIM، إن كانت مُعَدّة.
    
2.  التطبيق الثاني: صارت سجلات الملكية والخدمة قابلة للقراءة، فيُنشر DNS ويُتحقق من النطاق.
    
3.  التطبيق الثالث: تُنشأ صناديق البريد، بعد التحقق من النطاق.
    

يقول `mailctl plan` ذلك صراحة في كل مرحلة، بدل أن يتركك تخمّن سبب غياب DNS.

## صناديق البريد مستخدمون مرخّصون

في Microsoft 365 لا يكون صندوق البريد كائنًا مستقلًا: إنه مستخدم له ترخيص. وإنشاء واحد يستهلك مقعدًا مدفوعًا.

لذلك يفحص mailctl المقاعد وقت **التخطيط**، فيقرأ `/subscribedSkus` ويرفض مقدّمًا إن كانت عمليات الإنشاء ستتجاوز المتاح:

```console
creating mailboxes needs 3 BUSINESS_BASIC seat(s) but only 2 are free;
buy more seats or free some, then rerun
```

اكتشاف ذلك في منتصف التطبيق سيترك بعض الصناديق منشأة وبعضها لا.

### ثلاث حالات لا حالتان

يمكن أن يكون الصندوق غائبًا، أو موجودًا دون ترخيص، أو موجودًا ومرخّصًا. توجد الحالة الوسطى لأن إنشاء صندوق يتطلب استدعاءين: إنشاء المستخدم، ثم تعيين الترخيص، وقد يفشل الثاني وحده.

يتعامل mailctl معها صراحة:

<table class="tableblock frame-all grid-all stretch"><colgroup><col style="width: 33.3333%;"> <col style="width: 66.6667%;"></colgroup><tbody><tr><td class="tableblock halign-left valign-top"><p class="tableblock">غائب</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">أنشئ المستخدم وعيّن الترخيص.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock">موجود دون ترخيص مطابق</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">عيّن الترخيص فقط. يُترك المستخدم كما هو.</p></td></tr><tr><td class="tableblock halign-left valign-top"><p class="tableblock">موجود ومرخّص</p></td><td class="tableblock halign-left valign-top"><p class="tableblock">لا شيء لفعله.</p></td></tr></tbody></table>

دون تلك الحالة الوسطى، سيترك فشل الترخيص حسابًا موجودًا يحمل كلمة سر مولّدة ولا صندوق بريد له، بينما تبلّغ كل خطة لاحقة بأنه لا شيء لفعله.

### كلمات سر لمرة واحدة

يحصل المستخدم المنشأ على `forceChangePasswordNextSignIn`، فتكون بيانات الاعتماد التي يولّدها mailctl لاستخدام واحد فعلًا: تسلّمها، فيستبدلها المستلم عند أول تسجيل دخول.

## الحذف صعب عمدًا

حذف مستخدم في Microsoft 365 يتلف بريد ذلك الشخص، ويمكن استرداده خلال 30 يومًا. لذا يتطلب الحذف `-prune` **و**`-prune-mailboxes`، ثم يطلب منك سؤال التأكيد كتابة اسم النطاق.

صناديق البريد غير المُدارة، أي الموجودة في المستأجر والغائبة عن إعدادك، يُبلَّغ عنها في كل `plan` سواء مرّرت تلك الخيارات أم لا، فتعرف بالانحراف دون اللجوء إلى الخيار المُتلِف.

يحدد الحذف المستخدمين بمعرّف كائن Graph، لا بعنوان البريد أبدًا. فـ Graph يحلّ `/users/{...}` بالمعرّف أو بـ `userPrincipalName` فقط، والحذف بالعنوان قد يخطئ الهدف، أو يطابق مستخدمًا آخر صادف أن UPN الخاص به يساويه.

## النطاقات الموحّدة

يدير mailctl النطاقات المُدارة. إن كان `authenticationType` لنطاق ما هو `Federated`، يبلّغ `plan` بملاحظة: مستخدموه يصادقون في مكان آخر، فإدارة المستخدمين هنا ليست الصورة كاملة.
