Microsoft 365 Administration via Microsoft Graph API
This skill provides comprehensive knowledge for administering a Microsoft 365 tenant through the Microsoft Graph API. It covers user lifecycle management, license assignment, group administration, Exchange Online mailbox operations, SharePoint site management, and bulk processing patterns. All operations use delegated authentication with least-privilege scopes and produce structured reports.
Integration Context Contract
| Workflow |
tenantId |
subscriptionId |
environmentCloud |
principalType |
scopesOrRoles |
| User, group, license, audit workflows |
required |
optional (for Azure chain handoff) |
AzureCloud* |
delegated-user |
User.ReadWrite.All, Group.ReadWrite.All, Directory.ReadWrite.All, AuditLog.Read.All |
| Exchange and SharePoint admin workflows |
required |
optional |
AzureCloud* |
delegated-user |
MailboxSettings.ReadWrite, Mail.ReadWrite, Sites.FullControl.All |
| Teams admin workflows |
required |
optional |
AzureCloud* |
delegated-user |
Team.ReadWrite.All, TeamMember.ReadWrite.All, TeamsAppInstallation.ReadWriteForTeam.All |
| Intune / device management workflows |
required |
optional |
AzureCloud* |
delegated-user |
DeviceManagementManagedDevices.ReadWrite.All, DeviceManagementConfiguration.ReadWrite.All |
| PIM and access review workflows |
required |
optional |
AzureCloud* |
delegated-user |
RoleManagement.ReadWrite.Directory, AccessReview.ReadWrite.All, EntitlementManagement.ReadWrite.All |
| Usage report workflows |
required |
optional |
AzureCloud* |
delegated-user |
Reports.Read.All |
| Guest / external identity workflows |
required |
optional |
AzureCloud* |
delegated-user |
User.Invite.All, Policy.ReadWrite.CrossTenantAccess, User.ReadWrite.All |
| Administrative unit workflows |
required |
optional |
AzureCloud* |
delegated-user |
AdministrativeUnit.ReadWrite.All, RoleManagement.ReadWrite.Directory |
| Microsoft Search admin workflows |
required |
optional |
AzureCloud* |
delegated-user |
SearchConfiguration.ReadWrite.All |
| Domain management workflows |
required |
optional |
AzureCloud* |
delegated-user |
Domain.ReadWrite.All |
* Use sovereign cloud values from the canonical contract when applicable.
Fail fast before Graph/PowerShell execution when required context is missing or invalid. Redact tenant and object identifiers in outputs.
Microsoft Graph Admin API Overview
The Microsoft Graph API is the unified gateway to data and intelligence in Microsoft 365. All admin operations target the base URL:
https://graph.microsoft.com/v1.0/
Use the beta endpoint only when a feature is not yet available in v1.0 (e.g., certain Entra ID Governance features). Production admin scripts should target v1.0 for stability.
Key Admin Endpoints
| Endpoint |
Purpose |
/users |
Create, read, update, delete users |
/groups |
Security groups, M365 groups, membership |
/subscribedSkus |
Tenant license inventory (SKU list) |
/users/{id}/assignLicense |
License assignment per user |
/auditLogs/signIns |
Sign-in activity logs |
/auditLogs/directoryAudits |
Directory change audit trail |
/users/{id}/mailboxSettings |
Exchange mailbox settings via Graph |
/users/{id}/mailFolders |
Mail folder listing |
/sites |
SharePoint site collections |
/sites/{id}/permissions |
Site-level permissions |
/sites/{id}/drives |
Document libraries on a site |
/$batch |
Batch up to 20 requests in a single call |
Authentication and Authorization
All operations use delegated authentication with interactive user login. The signed-in user must have the appropriate admin roles (Global Administrator, User Administrator, Exchange Administrator, SharePoint Administrator, etc.).
Required Scopes by Operation Area
Request scopes dynamically based on the operation to follow the principle of least privilege:
| Operation Area |
Scopes |
| User CRUD |
User.ReadWrite.All |
| Directory and roles |
Directory.ReadWrite.All |
| Group management |
Group.ReadWrite.All |
| License management |
User.ReadWrite.All, Directory.Read.All |
| Mail / Mailbox |
Mail.ReadWrite, MailboxSettings.ReadWrite |
| SharePoint |
Sites.FullControl.All |
| Audit logs |
AuditLog.Read.All |
| Calendar |
Calendars.ReadWrite |
Auth Pattern (MSAL with Interactive Login)
import { PublicClientApplication, InteractiveBrowserCredential } from "@azure/identity";
import { Client } from "@microsoft/microsoft-graph-client";
import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";
const credential = new InteractiveBrowserCredential({
clientId: process.env.AZURE_CLIENT_ID!,
tenantId: process.env.AZURE_TENANT_ID!,
});
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
scopes: ["https://graph.microsoft.com/User.ReadWrite.All"],
});
const graphClient = Client.initWithMiddleware({ authProvider });
Never hardcode client secrets or tokens. Use environment variables or Azure Key Vault. For delegated flows, the interactive browser credential prompts the user and caches tokens. Token caching persists across sessions to avoid repeated login prompts.
App Registration Prerequisites
Before using the Graph API, register an application in Entra ID:
- Navigate to Azure Portal > Entra ID > App registrations > New registration
- Set the redirect URI to
http://localhost for local development
- Under API permissions, add Microsoft Graph delegated permissions for the required scopes
- Grant admin consent for the tenant (required for
User.ReadWrite.All, Directory.ReadWrite.All, etc.)
- Note the Application (client) ID and Directory (tenant) ID for use in the auth provider
For multi-tenant scenarios, use common as the tenant ID. For single-tenant admin tools, use the specific tenant GUID.
Error Response Format
Graph API errors follow a consistent format that all operations should handle:
interface GraphErrorResponse {
error: {
code: string; // e.g., "Request_ResourceNotFound", "Authorization_RequestDenied"
message: string; // Human-readable error description
innerError: {
"request-id": string;
date: string;
"client-request-id": string;
};
};
}
Common error codes: Request_ResourceNotFound (404), Authorization_RequestDenied (403), Request_BadRequest (400), TooManyRequests (429), ServiceNotAvailable (503).
User Lifecycle
The standard user lifecycle in M365 administration follows a predictable sequence:
- Create -- POST to
/users with required properties (displayName, mailNickname, userPrincipalName, passwordProfile)
- Set usageLocation -- Required before license assignment (ISO 3166-1 alpha-2 country code)
- Assign license -- POST to
/users/{id}/assignLicense with skuId
- Add to groups -- POST to
/groups/{id}/members/$ref for security groups, M365 groups
- Configure mailbox -- Set auto-reply, calendar permissions, delegates via Graph or PowerShell
- Ongoing management -- Update properties, reassign licenses, change group memberships
- Offboard -- Disable account, revoke licenses, remove from groups, set OOF, convert mailbox to shared, transfer OneDrive ownership
- Delete -- Soft delete (30-day recycle bin), then permanent purge
Critical Ordering Rules
usageLocation must be set before any license can be assigned. If you attempt to assign a license to a user without usageLocation, Graph returns a 400 error with code Request_BadRequest.
- Account must be disabled before revoking sign-in sessions during offboarding. Disabling the account prevents new sign-ins, while
revokeSignInSessions invalidates existing tokens.
- Licenses should be revoked before deleting a user to free up license capacity immediately.
- Group membership removal should happen before account deletion, as some group types may block removal of deleted members.
- Mailbox conversion to shared (via Exchange Online PowerShell) should happen before license removal, as the conversion process may fail if the mailbox is already deprovisioned.
Pagination for User Queries
When listing users or group members, Graph returns paginated results. Always follow @odata.nextLink to retrieve all pages:
interface PagedResponse<T> {
value: T[];
"@odata.nextLink"?: string;
"@odata.count"?: number;
}
async function getAllPages<T>(graphClient: Client, initialUrl: string): Promise<T[]> {
let all: T[] = [];
let nextLink: string | null = initialUrl;
while (nextLink) {
const response: PagedResponse<T> = await graphClient.api(nextLink).get();
all = all.concat(response.value);
nextLink = response["@odata.nextLink"] ?? null;
}
return all;
}
Default page size is 100 for most endpoints. Use $top to control page size (max 999 for /users).
Bulk Operations Pattern
All bulk operations follow a consistent pipeline:
CSV Input --> Validate All Rows --> Dry-Run Preview --> Execute with Rate Limiting --> Generate Report
- CSV format: UTF-8 with headers, required columns documented per operation
- Validation: Check every row before executing any (email format, UPN uniqueness, SKU availability, group existence)
- Dry-run: Output a markdown table showing what would happen, with no API calls
- Execution: Batch using Graph
$batch (up to 20 per request) or sequential with concurrency control
- Rate limiting: Handle HTTP 429 with
Retry-After header, exponential backoff starting at 1 second
- Reporting: Markdown table with per-row status (success/failure/skipped), error messages, and summary counts
Graph $batch Requests
The $batch endpoint accepts up to 20 individual requests in a single HTTP POST:
POST https://graph.microsoft.com/v1.0/$batch
Content-Type: application/json
{
"requests": [
{ "id": "1", "method": "POST", "url": "/users", "body": {...}, "headers": {"Content-Type": "application/json"} },
{ "id": "2", "method": "PATCH", "url": "/users/{id}", "body": {...}, "headers": {"Content-Type": "application/json"} }
]
}
Each response in the batch includes its own status code. Process each individually and capture per-request errors.
Rate Limiting
Microsoft Graph enforces throttling at multiple levels:
- Per-app, per-tenant: varies by endpoint (typically 10,000 requests per 10 minutes for most endpoints)
- Per-mailbox: 10,000 requests per 10 minutes for mail/calendar operations
- Response: HTTP 429 with
Retry-After header (value in seconds)
Handling pattern:
async function graphRequestWithRetry<T>(fn: () => Promise<T>, maxRetries = 5): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error: unknown) {
if (error instanceof GraphError && error.statusCode === 429 && attempt < maxRetries) {
const retryAfter = parseInt(error.headers?.get("Retry-After") ?? "1", 10);
const delay = retryAfter * 1000 * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
throw new Error("Max retries exceeded");
}
Exchange Online via Graph
Graph covers a subset of Exchange administration:
- Mailbox settings: GET/PATCH
/users/{id}/mailboxSettings (auto-replies, time zone, language)
- Mail folders: GET
/users/{id}/mailFolders
- Calendar permissions: GET/POST
/users/{id}/calendar/calendarPermissions
- Send mail: POST
/users/{id}/sendMail (with application or delegated permissions)
Operations not available via Graph (require Exchange Online PowerShell):
- Shared mailbox creation (
New-Mailbox -Shared)
- Distribution list management (
New-DistributionGroup, Add-DistributionGroupMember)
- Mail flow / transport rules (
New-TransportRule)
- Full mailbox delegation: Full Access, Send-As, Send-on-Behalf (
Add-MailboxPermission, Add-RecipientPermission)
- Mailbox type conversion (
Set-Mailbox -Type Shared)
- Message trace (
Get-MessageTrace)
For PowerShell operations, use the Exchange Online Management module:
Install-Module -Name ExchangeOnlineManagement -Force
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
SharePoint Administration via Graph
Graph provides site and drive access:
- Search sites: GET
/sites?search={query}
- Get site by path: GET
/sites/{hostname}:{serverRelativePath}
- Site permissions: GET/POST
/sites/{id}/permissions
- Document libraries: GET
/sites/{id}/drives
- Drive items: GET
/sites/{id}/drives/{driveId}/root/children
Operations requiring SharePoint Admin REST or PnP PowerShell:
- Site collection creation (SharePoint Admin REST
/_api/SPSiteManager/create)
- Storage quota management
- Hub site registration and association
- Site designs and templates
- Sharing policy configuration at the site level
PnP PowerShell is recommended for SharePoint-specific admin:
Install-Module -Name PnP.PowerShell -Force
Connect-PnPOnline -Url https://contoso-admin.sharepoint.com -Interactive
SharePoint URL Patterns
Understanding SharePoint URL structure is essential for site operations:
- Root site:
https://{tenant}.sharepoint.com
- Admin center:
https://{tenant}-admin.sharepoint.com
- Site collection:
https://{tenant}.sharepoint.com/sites/{sitename}
- OneDrive for Business:
https://{tenant}-my.sharepoint.com/personal/{username_domain_com}
- Graph site ID format:
{hostname},{siteCollectionId},{siteId} -- three comma-separated values
When using Graph to access sites by path, the colon syntax is required: /sites/{hostname}:{path}. For the root site, use /sites/{hostname}: with a trailing colon.
Audit and Compliance
Graph provides access to audit data:
- Sign-in logs: GET
/auditLogs/signIns -- filter by user, app, status, date, IP
- Directory audit logs: GET
/auditLogs/directoryAudits -- all directory changes (user creation, role assignment, group changes)
Both support OData $filter, $select, $top, and $orderby. The AuditLog.Read.All scope is required and the signed-in user needs at minimum the Reports Reader role.
Filtering Examples
GET /auditLogs/signIns?$filter=userPrincipalName eq 'user@contoso.com' and createdDateTime ge 2025-01-01T00:00:00Z
GET /auditLogs/directoryAudits?$filter=activityDisplayName eq 'Add member to group' and activityDateTime ge 2025-01-01T00:00:00Z
Data Retention
Audit log retention depends on the tenant license:
| License Tier |
Sign-In Logs |
Directory Audits |
| Azure AD Free |
7 days |
7 days |
| Azure AD Premium P1 |
30 days |
30 days |
| Azure AD Premium P2 |
30 days |
30 days |
| With Log Analytics export |
Custom (years) |
Custom (years) |
For long-term retention, export audit data to Azure Log Analytics workspace or Azure Storage using diagnostic settings. This allows queries beyond the default retention period.
Compliance Considerations
When building admin scripts, ensure compliance with organizational policy:
- Audit trail: Log every administrative action with who, what, when, and from where
- Approval workflows: High-impact operations (bulk license changes, mass offboarding) should require approval
- Change management: Document changes in a change management system before execution
- Data residency: Be aware of data residency requirements when accessing audit logs and user data
- GDPR: User deletion must be handled in compliance with data protection regulations; use the 30-day soft delete period to ensure recoverability before permanent deletion
Output Convention
Every operation produces a structured markdown report containing:
- Header: operation name, timestamp, executed by
- Summary: total processed, succeeded, failed, skipped
- Details table: per-item status with relevant identifiers
- Errors section: detailed error messages for failed items
- Recommendations: next steps or warnings
Reference Files
| Reference |
Path |
Topics |
| Entra ID |
references/entra-id.md |
User CRUD, licenses, groups, roles, named locations, auth strength, SSPR, MFA, security defaults, sign-in audit |
| Exchange Online |
references/exchange-online.md |
Mailboxes, DLs, mail flow/transport rules, shared mailboxes, connectors, DKIM, anti-spam, resource mailboxes, message trace |
| SharePoint Admin |
references/sharepoint-admin.md |
Site collections, storage, sharing, hub sites, permissions |
| Bulk Operations |
references/bulk-operations.md |
CSV processing, dry-run, retry, rate limits, reports |
| Teams Administration |
references/teams-admin.md |
Team CRUD, channels, membership, app installation, messaging/meeting policies, Teams PowerShell |
| Intune / Device Management |
references/intune-admin.md |
Managed devices, device actions, compliance policies, configuration profiles, apps, Autopilot |
| PIM and Access Reviews |
references/pim-access.md |
Role eligibility schedules, JIT activation, access reviews, entitlement management, PIM for Groups |
| Usage Reports and Analytics |
references/reports-analytics.md |
Email/Teams/OneDrive/SharePoint/mailbox usage reports, active user counts, adoption analytics |
| External Identities |
references/external-identities.md |
Guest invitations, stale guest cleanup, cross-tenant access policy, authorization policy, B2B settings |
| Administrative Units |
references/admin-units.md |
AU CRUD, static/dynamic membership, scoped role assignments, delegated administration |
| Microsoft Search Admin |
references/search-admin.md |
Bookmarks, Q&As, acronyms, audience targeting, bulk import |
| Domain Management |
references/domain-management.md |
Custom domain add/verify/delete, DNS records, default domain, SAML/WS-Fed federation |
Example Files
| Examples |
Path |
Scenarios |
| User Management |
examples/user-management.md |
Create, update, disable, offboard users |
| License Management |
examples/license-management.md |
Assign, revoke, reassign with SKU handling |
| Exchange Operations |
examples/exchange-operations.md |
Mailbox management, DLs, rules, calendar |
| SharePoint Operations |
examples/sharepoint-operations.md |
Site CRUD, permissions, sharing, hubs |
Knowledge references
references/operational-knowledge.md — compact API surface map, prerequisite matrix, deterministic failure remediation, limits/quotas and pagination/throttling guidance, and safe-default read-first/apply-second pattern.
Progressive Disclosure — Reference Files
| Topic |
File |
| Users, groups, licenses, roles, named locations, MFA, sign-in audit |
references/entra-id.md |
| Mailboxes, distribution lists, mail flow rules, DKIM, anti-spam, message trace |
references/exchange-online.md |
| SharePoint site collections, storage, sharing policies, hub sites, permissions |
references/sharepoint-admin.md |
| CSV bulk processing, dry-run, retry logic, rate limiting, audit reports |
references/bulk-operations.md |
| Teams CRUD, channels, membership, app installation, meeting and messaging policies |
references/teams-admin.md |
| Managed devices, device actions, compliance policies, configuration profiles, Autopilot |
references/intune-admin.md |
| PIM role eligibility, JIT activation, approval workflows, access reviews, PIM for Groups |
references/pim-access.md |
| Usage reports — Teams, email, OneDrive, SharePoint, mailbox activity, adoption analytics |
references/reports-analytics.md |
| Guest invitations, stale guest cleanup, cross-tenant access policy, B2B settings |
references/external-identities.md |
| Administrative unit CRUD, dynamic membership, scoped role assignments, delegation |
references/admin-units.md |
| Bookmarks, Q&As, acronyms, audience targeting, search vertical configuration |
references/search-admin.md |
| Custom domain add/verify/delete, DNS records, default domain, SAML/WS-Fed federation |
references/domain-management.md |
| Onboarding wizard — provisioning checklist, welcome email, group membership |
references/onboarding-concierge.md |
| Offboarding cleanup — disable, revoke, convert mailbox, transfer OneDrive |
references/offboarding-cleanup.md |
| Compact API surface map, prerequisite matrix, failure remediation, throttling |
references/operational-knowledge.md |
1---2name: m365-admin3description: Deep expertise in Microsoft 365 tenant administration via Microsoft Graph API — managing users, groups, licenses, Exchange Online, SharePoint, Teams, Intune, PIM, access reviews, usage reports, guest users, administrative units, Microsoft Search, and domain/federation management with proper auth, rate limiting, and audit trails.4---56# Microsoft 365 Administration via Microsoft Graph API78This skill provides comprehensive knowledge for administering a Microsoft 365 tenant through the Microsoft Graph API. It covers user lifecycle management, license assignment, group administration, Exchange Online mailbox operations, SharePoint site management, and bulk processing patterns. All operations use delegated authentication with least-privilege scopes and produce structured reports.910## Integration Context Contract11- Canonical contract: [`docs/integration-context.md`](../../../docs/integration-context.md)1213| Workflow | tenantId | subscriptionId | environmentCloud | principalType | scopesOrRoles |14|---|---|---|---|---|---|15| User, group, license, audit workflows | required | optional (for Azure chain handoff) | `AzureCloud`\* | `delegated-user` | `User.ReadWrite.All`, `Group.ReadWrite.All`, `Directory.ReadWrite.All`, `AuditLog.Read.All` |16| Exchange and SharePoint admin workflows | required | optional | `AzureCloud`\* | `delegated-user` | `MailboxSettings.ReadWrite`, `Mail.ReadWrite`, `Sites.FullControl.All` |17| Teams admin workflows | required | optional | `AzureCloud`\* | `delegated-user` | `Team.ReadWrite.All`, `TeamMember.ReadWrite.All`, `TeamsAppInstallation.ReadWriteForTeam.All` |18| Intune / device management workflows | required | optional | `AzureCloud`\* | `delegated-user` | `DeviceManagementManagedDevices.ReadWrite.All`, `DeviceManagementConfiguration.ReadWrite.All` |19| PIM and access review workflows | required | optional | `AzureCloud`\* | `delegated-user` | `RoleManagement.ReadWrite.Directory`, `AccessReview.ReadWrite.All`, `EntitlementManagement.ReadWrite.All` |20| Usage report workflows | required | optional | `AzureCloud`\* | `delegated-user` | `Reports.Read.All` |21| Guest / external identity workflows | required | optional | `AzureCloud`\* | `delegated-user` | `User.Invite.All`, `Policy.ReadWrite.CrossTenantAccess`, `User.ReadWrite.All` |22| Administrative unit workflows | required | optional | `AzureCloud`\* | `delegated-user` | `AdministrativeUnit.ReadWrite.All`, `RoleManagement.ReadWrite.Directory` |23| Microsoft Search admin workflows | required | optional | `AzureCloud`\* | `delegated-user` | `SearchConfiguration.ReadWrite.All` |24| Domain management workflows | required | optional | `AzureCloud`\* | `delegated-user` | `Domain.ReadWrite.All` |2526\* Use sovereign cloud values from the canonical contract when applicable.2728Fail fast before Graph/PowerShell execution when required context is missing or invalid. Redact tenant and object identifiers in outputs.293031## Microsoft Graph Admin API Overview3233The Microsoft Graph API is the unified gateway to data and intelligence in Microsoft 365. All admin operations target the base URL:3435```36https://graph.microsoft.com/v1.0/37```3839Use the `beta` endpoint only when a feature is not yet available in v1.0 (e.g., certain Entra ID Governance features). Production admin scripts should target v1.0 for stability.4041### Key Admin Endpoints4243| Endpoint | Purpose |44|---|---|45| `/users` | Create, read, update, delete users |46| `/groups` | Security groups, M365 groups, membership |47| `/subscribedSkus` | Tenant license inventory (SKU list) |48| `/users/{id}/assignLicense` | License assignment per user |49| `/auditLogs/signIns` | Sign-in activity logs |50| `/auditLogs/directoryAudits` | Directory change audit trail |51| `/users/{id}/mailboxSettings` | Exchange mailbox settings via Graph |52| `/users/{id}/mailFolders` | Mail folder listing |53| `/sites` | SharePoint site collections |54| `/sites/{id}/permissions` | Site-level permissions |55| `/sites/{id}/drives` | Document libraries on a site |56| `/$batch` | Batch up to 20 requests in a single call |5758## Authentication and Authorization5960All operations use **delegated authentication** with interactive user login. The signed-in user must have the appropriate admin roles (Global Administrator, User Administrator, Exchange Administrator, SharePoint Administrator, etc.).6162### Required Scopes by Operation Area6364Request scopes dynamically based on the operation to follow the principle of least privilege:6566| Operation Area | Scopes |67|---|---|68| User CRUD | `User.ReadWrite.All` |69| Directory and roles | `Directory.ReadWrite.All` |70| Group management | `Group.ReadWrite.All` |71| License management | `User.ReadWrite.All`, `Directory.Read.All` |72| Mail / Mailbox | `Mail.ReadWrite`, `MailboxSettings.ReadWrite` |73| SharePoint | `Sites.FullControl.All` |74| Audit logs | `AuditLog.Read.All` |75| Calendar | `Calendars.ReadWrite` |7677### Auth Pattern (MSAL with Interactive Login)7879```typescript80import { PublicClientApplication, InteractiveBrowserCredential } from "@azure/identity";81import { Client } from "@microsoft/microsoft-graph-client";82import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";8384const credential = new InteractiveBrowserCredential({85 clientId: process.env.AZURE_CLIENT_ID!,86 tenantId: process.env.AZURE_TENANT_ID!,87});8889const authProvider = new TokenCredentialAuthenticationProvider(credential, {90 scopes: ["https://graph.microsoft.com/User.ReadWrite.All"],91});9293const graphClient = Client.initWithMiddleware({ authProvider });94```9596Never hardcode client secrets or tokens. Use environment variables or Azure Key Vault. For delegated flows, the interactive browser credential prompts the user and caches tokens. Token caching persists across sessions to avoid repeated login prompts.9798### App Registration Prerequisites99100Before using the Graph API, register an application in Entra ID:1011021. Navigate to Azure Portal > Entra ID > App registrations > New registration1032. Set the redirect URI to `http://localhost` for local development1043. Under API permissions, add Microsoft Graph delegated permissions for the required scopes1054. Grant admin consent for the tenant (required for `User.ReadWrite.All`, `Directory.ReadWrite.All`, etc.)1065. Note the Application (client) ID and Directory (tenant) ID for use in the auth provider107108For multi-tenant scenarios, use `common` as the tenant ID. For single-tenant admin tools, use the specific tenant GUID.109110### Error Response Format111112Graph API errors follow a consistent format that all operations should handle:113114```typescript115interface GraphErrorResponse {116 error: {117 code: string; // e.g., "Request_ResourceNotFound", "Authorization_RequestDenied"118 message: string; // Human-readable error description119 innerError: {120 "request-id": string;121 date: string;122 "client-request-id": string;123 };124 };125}126```127128Common error codes: `Request_ResourceNotFound` (404), `Authorization_RequestDenied` (403), `Request_BadRequest` (400), `TooManyRequests` (429), `ServiceNotAvailable` (503).129130## User Lifecycle131132The standard user lifecycle in M365 administration follows a predictable sequence:1331341. **Create** -- POST to `/users` with required properties (displayName, mailNickname, userPrincipalName, passwordProfile)1352. **Set usageLocation** -- Required before license assignment (ISO 3166-1 alpha-2 country code)1363. **Assign license** -- POST to `/users/{id}/assignLicense` with skuId1374. **Add to groups** -- POST to `/groups/{id}/members/$ref` for security groups, M365 groups1385. **Configure mailbox** -- Set auto-reply, calendar permissions, delegates via Graph or PowerShell1396. **Ongoing management** -- Update properties, reassign licenses, change group memberships1407. **Offboard** -- Disable account, revoke licenses, remove from groups, set OOF, convert mailbox to shared, transfer OneDrive ownership1418. **Delete** -- Soft delete (30-day recycle bin), then permanent purge142143### Critical Ordering Rules144145- `usageLocation` must be set before any license can be assigned. If you attempt to assign a license to a user without `usageLocation`, Graph returns a 400 error with code `Request_BadRequest`.146- Account must be disabled before revoking sign-in sessions during offboarding. Disabling the account prevents new sign-ins, while `revokeSignInSessions` invalidates existing tokens.147- Licenses should be revoked before deleting a user to free up license capacity immediately.148- Group membership removal should happen before account deletion, as some group types may block removal of deleted members.149- Mailbox conversion to shared (via Exchange Online PowerShell) should happen before license removal, as the conversion process may fail if the mailbox is already deprovisioned.150151### Pagination for User Queries152153When listing users or group members, Graph returns paginated results. Always follow `@odata.nextLink` to retrieve all pages:154155```typescript156interface PagedResponse<T> {157 value: T[];158 "@odata.nextLink"?: string;159 "@odata.count"?: number;160}161162async function getAllPages<T>(graphClient: Client, initialUrl: string): Promise<T[]> {163 let all: T[] = [];164 let nextLink: string | null = initialUrl;165166 while (nextLink) {167 const response: PagedResponse<T> = await graphClient.api(nextLink).get();168 all = all.concat(response.value);169 nextLink = response["@odata.nextLink"] ?? null;170 }171172 return all;173}174```175176Default page size is 100 for most endpoints. Use `$top` to control page size (max 999 for `/users`).177178## Bulk Operations Pattern179180All bulk operations follow a consistent pipeline:181182```183CSV Input --> Validate All Rows --> Dry-Run Preview --> Execute with Rate Limiting --> Generate Report184```185186- **CSV format**: UTF-8 with headers, required columns documented per operation187- **Validation**: Check every row before executing any (email format, UPN uniqueness, SKU availability, group existence)188- **Dry-run**: Output a markdown table showing what would happen, with no API calls189- **Execution**: Batch using Graph `$batch` (up to 20 per request) or sequential with concurrency control190- **Rate limiting**: Handle HTTP 429 with `Retry-After` header, exponential backoff starting at 1 second191- **Reporting**: Markdown table with per-row status (success/failure/skipped), error messages, and summary counts192193### Graph $batch Requests194195The `$batch` endpoint accepts up to 20 individual requests in a single HTTP POST:196197```198POST https://graph.microsoft.com/v1.0/$batch199Content-Type: application/json200201{202 "requests": [203 { "id": "1", "method": "POST", "url": "/users", "body": {...}, "headers": {"Content-Type": "application/json"} },204 { "id": "2", "method": "PATCH", "url": "/users/{id}", "body": {...}, "headers": {"Content-Type": "application/json"} }205 ]206}207```208209Each response in the batch includes its own status code. Process each individually and capture per-request errors.210211### Rate Limiting212213Microsoft Graph enforces throttling at multiple levels:214215- **Per-app, per-tenant**: varies by endpoint (typically 10,000 requests per 10 minutes for most endpoints)216- **Per-mailbox**: 10,000 requests per 10 minutes for mail/calendar operations217- **Response**: HTTP 429 with `Retry-After` header (value in seconds)218219Handling pattern:220221```typescript222async function graphRequestWithRetry<T>(fn: () => Promise<T>, maxRetries = 5): Promise<T> {223 for (let attempt = 0; attempt <= maxRetries; attempt++) {224 try {225 return await fn();226 } catch (error: unknown) {227 if (error instanceof GraphError && error.statusCode === 429 && attempt < maxRetries) {228 const retryAfter = parseInt(error.headers?.get("Retry-After") ?? "1", 10);229 const delay = retryAfter * 1000 * Math.pow(2, attempt);230 await new Promise(resolve => setTimeout(resolve, delay));231 continue;232 }233 throw error;234 }235 }236 throw new Error("Max retries exceeded");237}238```239240## Exchange Online via Graph241242Graph covers a subset of Exchange administration:243244- **Mailbox settings**: GET/PATCH `/users/{id}/mailboxSettings` (auto-replies, time zone, language)245- **Mail folders**: GET `/users/{id}/mailFolders`246- **Calendar permissions**: GET/POST `/users/{id}/calendar/calendarPermissions`247- **Send mail**: POST `/users/{id}/sendMail` (with application or delegated permissions)248249Operations **not** available via Graph (require Exchange Online PowerShell):250251- Shared mailbox creation (`New-Mailbox -Shared`)252- Distribution list management (`New-DistributionGroup`, `Add-DistributionGroupMember`)253- Mail flow / transport rules (`New-TransportRule`)254- Full mailbox delegation: Full Access, Send-As, Send-on-Behalf (`Add-MailboxPermission`, `Add-RecipientPermission`)255- Mailbox type conversion (`Set-Mailbox -Type Shared`)256- Message trace (`Get-MessageTrace`)257258For PowerShell operations, use the Exchange Online Management module:259260```powershell261Install-Module -Name ExchangeOnlineManagement -Force262Connect-ExchangeOnline -UserPrincipalName admin@contoso.com263```264265## SharePoint Administration via Graph266267Graph provides site and drive access:268269- **Search sites**: GET `/sites?search={query}`270- **Get site by path**: GET `/sites/{hostname}:{serverRelativePath}`271- **Site permissions**: GET/POST `/sites/{id}/permissions`272- **Document libraries**: GET `/sites/{id}/drives`273- **Drive items**: GET `/sites/{id}/drives/{driveId}/root/children`274275Operations requiring SharePoint Admin REST or PnP PowerShell:276277- Site collection creation (SharePoint Admin REST `/_api/SPSiteManager/create`)278- Storage quota management279- Hub site registration and association280- Site designs and templates281- Sharing policy configuration at the site level282283PnP PowerShell is recommended for SharePoint-specific admin:284285```powershell286Install-Module -Name PnP.PowerShell -Force287Connect-PnPOnline -Url https://contoso-admin.sharepoint.com -Interactive288```289290### SharePoint URL Patterns291292Understanding SharePoint URL structure is essential for site operations:293294- **Root site**: `https://{tenant}.sharepoint.com`295- **Admin center**: `https://{tenant}-admin.sharepoint.com`296- **Site collection**: `https://{tenant}.sharepoint.com/sites/{sitename}`297- **OneDrive for Business**: `https://{tenant}-my.sharepoint.com/personal/{username_domain_com}`298- **Graph site ID format**: `{hostname},{siteCollectionId},{siteId}` -- three comma-separated values299300When using Graph to access sites by path, the colon syntax is required: `/sites/{hostname}:{path}`. For the root site, use `/sites/{hostname}:` with a trailing colon.301302## Audit and Compliance303304Graph provides access to audit data:305306- **Sign-in logs**: GET `/auditLogs/signIns` -- filter by user, app, status, date, IP307- **Directory audit logs**: GET `/auditLogs/directoryAudits` -- all directory changes (user creation, role assignment, group changes)308309Both support OData `$filter`, `$select`, `$top`, and `$orderby`. The `AuditLog.Read.All` scope is required and the signed-in user needs at minimum the Reports Reader role.310311### Filtering Examples312313```314GET /auditLogs/signIns?$filter=userPrincipalName eq 'user@contoso.com' and createdDateTime ge 2025-01-01T00:00:00Z315GET /auditLogs/directoryAudits?$filter=activityDisplayName eq 'Add member to group' and activityDateTime ge 2025-01-01T00:00:00Z316```317318### Data Retention319320Audit log retention depends on the tenant license:321322| License Tier | Sign-In Logs | Directory Audits |323|---|---|---|324| Azure AD Free | 7 days | 7 days |325| Azure AD Premium P1 | 30 days | 30 days |326| Azure AD Premium P2 | 30 days | 30 days |327| With Log Analytics export | Custom (years) | Custom (years) |328329For long-term retention, export audit data to Azure Log Analytics workspace or Azure Storage using diagnostic settings. This allows queries beyond the default retention period.330331### Compliance Considerations332333When building admin scripts, ensure compliance with organizational policy:334335- **Audit trail**: Log every administrative action with who, what, when, and from where336- **Approval workflows**: High-impact operations (bulk license changes, mass offboarding) should require approval337- **Change management**: Document changes in a change management system before execution338- **Data residency**: Be aware of data residency requirements when accessing audit logs and user data339- **GDPR**: User deletion must be handled in compliance with data protection regulations; use the 30-day soft delete period to ensure recoverability before permanent deletion340341## Output Convention342343Every operation produces a structured markdown report containing:3443451. **Header**: operation name, timestamp, executed by3462. **Summary**: total processed, succeeded, failed, skipped3473. **Details table**: per-item status with relevant identifiers3484. **Errors section**: detailed error messages for failed items3495. **Recommendations**: next steps or warnings350351## Reference Files352353| Reference | Path | Topics |354|---|---|---|355| Entra ID | `references/entra-id.md` | User CRUD, licenses, groups, roles, named locations, auth strength, SSPR, MFA, security defaults, sign-in audit |356| Exchange Online | `references/exchange-online.md` | Mailboxes, DLs, mail flow/transport rules, shared mailboxes, connectors, DKIM, anti-spam, resource mailboxes, message trace |357| SharePoint Admin | `references/sharepoint-admin.md` | Site collections, storage, sharing, hub sites, permissions |358| Bulk Operations | `references/bulk-operations.md` | CSV processing, dry-run, retry, rate limits, reports |359| Teams Administration | `references/teams-admin.md` | Team CRUD, channels, membership, app installation, messaging/meeting policies, Teams PowerShell |360| Intune / Device Management | `references/intune-admin.md` | Managed devices, device actions, compliance policies, configuration profiles, apps, Autopilot |361| PIM and Access Reviews | `references/pim-access.md` | Role eligibility schedules, JIT activation, access reviews, entitlement management, PIM for Groups |362| Usage Reports and Analytics | `references/reports-analytics.md` | Email/Teams/OneDrive/SharePoint/mailbox usage reports, active user counts, adoption analytics |363| External Identities | `references/external-identities.md` | Guest invitations, stale guest cleanup, cross-tenant access policy, authorization policy, B2B settings |364| Administrative Units | `references/admin-units.md` | AU CRUD, static/dynamic membership, scoped role assignments, delegated administration |365| Microsoft Search Admin | `references/search-admin.md` | Bookmarks, Q&As, acronyms, audience targeting, bulk import |366| Domain Management | `references/domain-management.md` | Custom domain add/verify/delete, DNS records, default domain, SAML/WS-Fed federation |367368## Example Files369370| Examples | Path | Scenarios |371|---|---|---|372| User Management | `examples/user-management.md` | Create, update, disable, offboard users |373| License Management | `examples/license-management.md` | Assign, revoke, reassign with SKU handling |374| Exchange Operations | `examples/exchange-operations.md` | Mailbox management, DLs, rules, calendar |375| SharePoint Operations | `examples/sharepoint-operations.md` | Site CRUD, permissions, sharing, hubs |376377## Knowledge references378379- `references/operational-knowledge.md` — compact API surface map, prerequisite matrix, deterministic failure remediation, limits/quotas and pagination/throttling guidance, and safe-default read-first/apply-second pattern.380381## Progressive Disclosure — Reference Files382383| Topic | File |384|---|---|385| Users, groups, licenses, roles, named locations, MFA, sign-in audit | [`references/entra-id.md`](./references/entra-id.md) |386| Mailboxes, distribution lists, mail flow rules, DKIM, anti-spam, message trace | [`references/exchange-online.md`](./references/exchange-online.md) |387| SharePoint site collections, storage, sharing policies, hub sites, permissions | [`references/sharepoint-admin.md`](./references/sharepoint-admin.md) |388| CSV bulk processing, dry-run, retry logic, rate limiting, audit reports | [`references/bulk-operations.md`](./references/bulk-operations.md) |389| Teams CRUD, channels, membership, app installation, meeting and messaging policies | [`references/teams-admin.md`](./references/teams-admin.md) |390| Managed devices, device actions, compliance policies, configuration profiles, Autopilot | [`references/intune-admin.md`](./references/intune-admin.md) |391| PIM role eligibility, JIT activation, approval workflows, access reviews, PIM for Groups | [`references/pim-access.md`](./references/pim-access.md) |392| Usage reports — Teams, email, OneDrive, SharePoint, mailbox activity, adoption analytics | [`references/reports-analytics.md`](./references/reports-analytics.md) |393| Guest invitations, stale guest cleanup, cross-tenant access policy, B2B settings | [`references/external-identities.md`](./references/external-identities.md) |394| Administrative unit CRUD, dynamic membership, scoped role assignments, delegation | [`references/admin-units.md`](./references/admin-units.md) |395| Bookmarks, Q&As, acronyms, audience targeting, search vertical configuration | [`references/search-admin.md`](./references/search-admin.md) |396| Custom domain add/verify/delete, DNS records, default domain, SAML/WS-Fed federation | [`references/domain-management.md`](./references/domain-management.md) |397| Onboarding wizard — provisioning checklist, welcome email, group membership | [`references/onboarding-concierge.md`](./references/onboarding-concierge.md) |398| Offboarding cleanup — disable, revoke, convert mailbox, transfer OneDrive | [`references/offboarding-cleanup.md`](./references/offboarding-cleanup.md) |399| Compact API surface map, prerequisite matrix, failure remediation, throttling | [`references/operational-knowledge.md`](./references/operational-knowledge.md) |