Microsoft 365 租户管理器

ms365-tenant-manager
分类通用
作者Alireza Rezvani
许可MIT
评分4.50/5
使用2.3K

Microsoft 365 租户管理器

为管理租户设置、用户生命周期、安全策略和组织优化的 Microsoft 365 全局管理员提供专家级指导与自动化方案。

---

快速上手

执行安全审计

powershell
Connect-MgGraph -Scopes "Directory.Read.All","Policy.Read.All","AuditLog.Read.All"
Get-MgSubscribedSku | Select-Object SkuPartNumber, ConsumedUnits, @{N="Total";E={$_.PrepaidUnits.Enabled}}
Get-MgPolicyAuthorizationPolicy | Select-Object AllowInvitesFrom, DefaultUserRolePermissions

通过 CSV 批量创建用户

powershell
# CSV 列:DisplayName, UserPrincipalName, Department, LicenseSku
Import-Csv .\new_users.csv | ForEach-Object {
    $passwordProfile = @{ Password = (New-Guid).ToString().Substring(0,16) + "!"; ForceChangePasswordNextSignIn = $true }
    New-MgUser -DisplayName $_.DisplayName -UserPrincipalName $_.UserPrincipalName 
               -Department $_.Department -AccountEnabled -PasswordProfile $passwordProfile
}

创建条件访问策略(管理员 MFA)

powershell
$adminRoles = (Get-MgDirectoryRole | Where-Object { $_.DisplayName -match "Admin" }).Id
$policy = @{
    DisplayName = "Require MFA for Admins"
    State = "enabledForReportingButNotEnforced"   # 初始设置为仅报告模式
    Conditions = @{ Users = @{ IncludeRoles = $adminRoles } }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

内置 Python 生成器

提供三个基于标准库的工具,可确定性地生成 PowerShell 交付物 —— 对于批量或重复性工作,建议优先使用这些工具而非手动编写脚本。输入示例:sample_input.json;预期格式:expected_output.json

bash
# 租户设置:清单 + DNS 记录 + 许可证计划 (JSON),或完整的设置脚本
python3 scripts/tenant_setup.py --config sample_input.json --format json -o tenant_plan.json
python3 scripts/tenant_setup.py --config sample_input.json --format powershell -o tenant_setup.ps1

用户生命周期:先验证,再生成创建/离职脚本

python3 scripts/user_management.py --domain acme.com --action validate --users users.json python3 scripts/user_management.py --domain acme.com --action create --users users.json -o create_users.ps1 python3 scripts/user_management.py --domain acme.com --action offboard --user-email [email protected] -o offboard.ps1

管理脚本:条件访问策略 / 安全审计 / 批量授权

python3 scripts/powershell_generator.py --tenant-domain acme.com --task conditional-access --policy-config policy.json -o ca_policy.ps1 python3 scripts/powershell_generator.py --tenant-domain acme.com --task security-audit -o audit.ps1 python3 scripts/powershell_generator.py --tenant-domain acme.com --task bulk-license --users-csv users.csv --license-sku ENTERPRISEPACK -o licenses.ps1

门禁: 对于用户创建,请先运行 --action validate,并要求每条条目必须通过验证。
在生成创建脚本之前,请先输出
"is_valid": true。在租户中运行任何生成的 .ps1 脚本前,请对照以下工作流进行审核。

---

工作流

工作流 1:新租户设置

步骤 1:生成设置检查清单

运行 python3 scripts/tenant_setup.py --config tenant.json --format json 并分阶段完成 setup_checklist;其中 dns_records 用于步骤 2,license_recommendations 用于许可工作流。

在配置前确认先决条件:

  • 已创建全局管理员账户并启用 MFA 保护

  • 已购买自定义域名且可进行 DNS 编辑

  • 已确认许可 SKU(记录 E3 与 E5 的功能需求差异)

步骤 2:配置并验证 DNS 记录

powershell
# 在 M365 管理中心添加域名后,在继续操作前验证传播情况
$domain = "company.com"
Resolve-DnsName -Name "_msdcs.$domain" -Type NS -ErrorAction SilentlyContinue

同时在 shell 提示符下运行:

nslookup -type=MX company.com

nslookup -type=TXT company.com # 确认 SPF 记录

在批量创建用户前,请等待 DNS 传播(最多 48 小时)。

步骤 3:应用安全基线

powershell
# 禁用传统身份验证(拦截 Basic Auth 协议)
$policy = @{
    DisplayName = "Block Legacy Authentication"
    State = "enabled"
    Conditions = @{ ClientAppTypes = @("exchangeActiveSync","other") }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("block") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

启用统一审核日志

Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

步骤 4:配置用户

powershell
$licenseSku = (Get-MgSubscribedSku | Where-Object { $_.SkuPartNumber -eq "ENTERPRISEPACK" }).SkuId

Import-Csv .\employees.csv | ForEach-Object {
try {
$user = New-MgUser -DisplayName $_.DisplayName -UserPrincipalName $_.UserPrincipalName

-AccountEnabled -PasswordProfile @{ Password = (New-Guid).ToString().Substring(0,12)+"!"; ForceChangePasswordNextSignIn = $true }
Set-MgUserLicense -UserId $user.Id -AddLicenses @(@{ SkuId = $licenseSku }) -RemoveLicenses @()
Write-Host "Provisioned: $($_.UserPrincipalName)"
} catch {
Write-Warning "Failed $($_.UserPrincipalName): $_"
}
}

验证: 在 M365 管理门户中随机抽查 3-5 个账户;确认许可状态显示为“已激活”。

---

工作流 2:安全加固

步骤 1:运行安全审计

powershell
Connect-MgGraph -Scopes "Directory.Read.All","Policy.Read.All","AuditLog.Read.All","Reports.Read.All"

导出条件访问策略清单

Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State | Export-Csv .\ca_policies.csv -NoTypeInformation

查找未注册 MFA 的账户

$report = Get-MgReportAuthenticationMethodUserRegistrationDetail $report | Where-Object { -not $_.IsMfaRegistered } | Select-Object UserPrincipalName, IsMfaRegistered | Export-Csv .\no_mfa_users.csv -NoTypeInformation

Write-Host "Audit complete. Review ca_policies.csv and no_mfa_users.csv."

步骤 2:创建 MFA 策略(先设为仅报告模式)

powershell
$policy = @{
    DisplayName = "Require MFA All Users"
    State = "enabledForReportingButNotEnforced"
    Conditions = @{ Users = @{ IncludeUsers = @("All") } }
    GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $policy

验证: Af
48 小时后,在 Entra ID 中审查登录日志;确认预期用户会被要求验证,然后将 State 更改为 "enabled"

步骤 3:审查安全分数 (Secure Score)

powershell
# 获取当前安全分数和首要改进项
Get-MgSecuritySecureScore -Top 1 | Select-Object CurrentScore, MaxScore, ActiveUserCount
Get-MgSecuritySecureScoreControlProfile | Sort-Object -Property ActionType |
    Select-Object Title, ImplementationStatus, MaxScore | Format-Table -AutoSize

---

工作流 3:用户离职处理 (Offboarding)

步骤 1:禁用登录并撤销会话

powershell
$upn = "[email protected]"
$user = Get-MgUser -Filter "userPrincipalName eq '$upn'"

立即禁用登录

Update-MgUser -UserId $user.Id -AccountEnabled:$false

撤销所有活动令牌

Invoke-MgInvalidateAllUserRefreshToken -UserId $user.Id Write-Host "已禁用 $upn 的登录并撤销其会话"

步骤 2:使用 -WhatIf 预览(许可证移除)

powershell
# 识别已分配的许可证
$licenses = (Get-MgUserLicenseDetail -UserId $user.Id).SkuId

模拟运行:打印将要移除的内容

$licenses | ForEach-Object { Write-Host "[WhatIf] 将移除 SKU: $_" }

步骤 3:执行离职处理

powershell
# 移除许可证
Set-MgUserLicense -UserId $user.Id -AddLicenses @() -RemoveLicenses $licenses

将邮箱转换为共享邮箱(需要 ExchangeOnlineManagement 模块)

Set-Mailbox -Identity $upn -Type Shared

从所有组中移除

Get-MgUserMemberOf -UserId $user.Id | ForEach-Object { try { Remove-MgGroupMemberByRef -GroupId $_.Id -DirectoryObjectId $user.Id } catch {} } Write-Host "$upn 的离职处理已完成"

验证: 在 M365 管理中心确认该账户显示为“已禁用”、无活动许可证且邮箱类型为“共享”。

---

最佳实践

租户设置

1. 在添加用户前启用 MFA
2. 为条件访问 (Conditional Access) 配置命名位置
3. 使用带有 PIM 的独立管理员账户
4. 在批量创建用户前验证自定义域名(及 DNS 生效情况)
5. 应用 Microsoft 安全分数 (Secure Score) 的建议

安全运营

1. 将条件访问策略先设置为“仅报告”模式
2. 在强制执行新策略前,审查 48 小时的登录日志
3. 严禁在脚本中硬编码凭据 —— 请使用 Azure Key Vault 或 Get-Credential
4. 为所有操作启用统一审核日志
5. 每季度进行一次安全审查和安全分数检查

PowerShell 自动化

1. 优先使用 Microsoft Graph (Microsoft.Graph 模块) 而非旧版 MSOnline
2. 包含 try/catch 块以进行错误处理
3. 实现 Write-Host/Write-Warning 日志记录以留存审计轨迹
4. 在执行批量破坏性操作前,使用 -WhatIf 或模拟运行输出
5. 先在非生产环境租户中进行测试

---

参考指南

references/powershell-templates.md

  • 即用脚本模板

  • 条件访问策略示例

  • 批量用户配置脚本

  • 安全审计脚本

references/security-policies.md

  • 条件访问配置

  • MFA 强制执行策略

  • DLP 和保留策略

  • 安全基线设置

references/troubleshooting.md

  • 常见错误解决方案

  • PowerShell 模块问题

  • 权限故障排除

  • DNS 生效问题

---

限制条件

| 约束 | 影响 |
|------------|--------|
| 需要全局管理员权限 | 完整的租户设置需要最高权限 |
| API 速率限制 | 批量操作可能会被限流 |
| 许可证依赖 | 高级功能需要 E3/E5 许可证 |
高级功能 |
| 混合场景 | 本地 AD 需要额外配置 |
| PowerShell 前置条件 | 需要 Microsoft.Graph 模块 |

所需 PowerShell 模块

powershell
Install-Module Microsoft.Graph -Scope CurrentUser
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Install-Module MicrosoftTeams -Scope CurrentUser

所需权限

  • 全局管理员 (Global Administrator) — 完整的租户设置
  • 用户管理员 (User Administrator) — 用户管理
  • 安全管理员 (Security Administrator) — 安全策略
  • Exchange 管理员 (Exchange Administrator) — 邮箱管理