SKILL.md
readonly只读
name
entra-agent-user
description
在 Microsoft Entra ID 中从代理标识创建代理用户,使 AI 代理能够作为数字工作者在 Microsoft 365 和 Azure 环境中使用用户身份功能。
技能:在 Microsoft Entra 代理 ID 中创建代理用户
概述
代理用户是 Microsoft Entra ID 中的一种特殊用户身份,使 AI 代理能够作为数字工作者运行。它允许代理访问严格需要用户身份的 API 和服务(例如 Exchange 邮箱、Teams、组织架构图),同时保持适当的安全边界。
代理用户接收的令牌包含 idtyp=user,而常规代理标识接收的令牌包含 idtyp=app。
先决条件
- 一个具有代理 ID 功能的 Microsoft Entra 租户
- 从代理标识蓝图创建的代理标识(类型为
ServiceIdentity的服务主体) - 以下权限之一:
AgentIdUser.ReadWrite.IdentityParentedBy(最低权限)AgentIdUser.ReadWrite.AllUser.ReadWrite.All
- 调用者至少需要拥有代理 ID 管理员角色(在委派场景中)
重要:
identityParentId必须引用真实的代理标识(通过代理标识蓝图创建),而不是常规应用程序服务主体。可以通过检查服务主体是否具有@odata.type: #microsoft.graph.agentIdentity和servicePrincipalType: ServiceIdentity来验证。
架构
代理标识蓝图(应用程序模板)
│
├── 代理标识(服务主体 - ServiceIdentity)
│ │
│ └── 代理用户(用户 - agentUser)← 1:1 关系
│
└── 代理标识蓝图主体(租户中的服务主体)
| 组件 | 类型 | 令牌声明 | 用途 |
|---|---|---|---|
| 代理标识 | 服务主体 | idtyp=app |
后端/API 操作 |
| 代理用户 | 用户(agentUser) |
idtyp=user |
在 M365 中作为数字工作者运行 |
步骤 1:验证代理标识是否存在
在创建代理用户之前,确认代理标识是适当的 agentIdentity 类型:
GET https://graph.microsoft.com/beta/servicePrincipals/{agent-identity-id}
Authorization: Bearer <token>
验证响应包含:
{
"@odata.type": "#microsoft.graph.agentIdentity",
"servicePrincipalType": "ServiceIdentity",
"agentIdentityBlueprintId": "<blueprint-id>"
}
PowerShell
Connect-MgGraph -Scopes "Application.Read.All" -TenantId "<tenant>" -UseDeviceCode -NoWelcome
Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/beta/servicePrincipals/<agent-identity-id>" | ConvertTo-Json -Depth 3
常见错误: 使用应用注册的
appId或常规应用程序服务主体的id会导致失败。只有从蓝图创建的代理标识才有效。
步骤 2:创建代理用户
HTTP 请求
POST https://graph.microsoft.com/beta/users/microsoft.graph.agentUser
Content-Type: application/json
Authorization: Bearer <token>
{
"accountEnabled": true,
"displayName": "My Agent User",
"mailNickname": "my-agent-user",
"userPrincipalName": "my-agent-user@yourtenant.onmicrosoft.com",
"identityParentId": "<agent-identity-object-id>"
}
必需属性
| 属性 | 类型 | 描述 |
|---|---|---|
accountEnabled |
布尔值 | true 表示启用账户 |
displayName |
字符串 | 用户友好名称 |
mailNickname |
字符串 | 邮件别名(无空格/特殊字符) |
userPrincipalName |
字符串 | UPN — 必须在租户中唯一(alias@verified-domain) |
identityParentId |
字符串 | 父代理标识的对象 ID |
PowerShell
Connect-MgGraph -Scopes "User.ReadWrite.All" -TenantId "<tenant>" -UseDeviceCode -NoWelcome
$body = @{
accountEnabled = $true
displayName = "My Agent User"
mailNickname = "my-agent-user"
userPrincipalName = "my-agent-user@yourtenant.onmicrosoft.com"
identityParentId = "<agent-identity-object-id>"
} | ConvertTo-Json
Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/beta/users/microsoft.graph.agentUser" `
-Body $body -ContentType "application/json" | ConvertTo-Json -Depth 3
关键说明
- 无密码 — 代理用户不能有密码。它们通过父代理标识的凭据进行身份验证。
- 1:1 关系 — 每个代理标识最多只能有一个代理用户。尝试创建第二个会返回
400 Bad Request。 userPrincipalName必须唯一。不要重用现有用户的 UPN。
步骤 3:分配经理(可选)
分配经理允许代理用户出现在组织架构图中(例如 Teams)。
PUT https://graph.microsoft.com/beta/users/{agent-user-id}/manager/$ref
Content-Type: application/json
Authorization: Bearer <token>
{
"@odata.id": "https://graph.microsoft.com/beta/users/{manager-user-id}"
}
PowerShell
$managerBody = '{"@odata.id":"https://graph.microsoft.com/beta/users/<manager-user-id>"}'
Invoke-MgGraphRequest -Method PUT `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>/manager/`$ref" `
-Body $managerBody -ContentType "application/json"
步骤 4:设置使用位置并分配许可证(可选)
代理用户需要许可证才能拥有邮箱、Teams 状态等。必须先设置使用位置。
设置使用位置
PATCH https://graph.microsoft.com/beta/users/{agent-user-id}
Content-Type: application/json
Authorization: Bearer <token>
{
"usageLocation": "US"
}
列出可用许可证
GET https://graph.microsoft.com/beta/subscribedSkus?$select=skuPartNumber,skuId,consumedUnits,prepaidUnits
Authorization: Bearer <token>
需要 Organization.Read.All 权限。
分配许可证
POST https://graph.microsoft.com/beta/users/{agent-user-id}/assignLicense
Content-Type: application/json
Authorization: Bearer <token>
{
"addLicenses": [
{ "skuId": "<sku-id>" }
],
"removeLicenses": []
}
PowerShell(一步完成)
Connect-MgGraph -Scopes "User.ReadWrite.All","Organization.Read.All" -TenantId "<tenant>" -NoWelcome
# 设置使用位置
Invoke-MgGraphRequest -Method PATCH `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>" `
-Body '{"usageLocation":"US"}' -ContentType "application/json"
# 分配许可证
$licenseBody = '{"addLicenses":[{"skuId":"<sku-id>"}],"removeLicenses":[]}'
Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>/assignLicense" `
-Body $licenseBody -ContentType "application/json"
提示: 你也可以通过 Entra 管理中心在“标识”→“用户”→“所有用户”中选择代理用户,然后进入“许可证和应用程序”来分配许可证。
预配时间
| 服务 | 预计时间 |
|---|---|
| Exchange 邮箱 | 5–30 分钟 |
| Teams 可用性 | 15 分钟 – 24 小时 |
| 组织架构图/人员搜索 | 最多 24–48 小时 |
| SharePoint / OneDrive | 5–30 分钟 |
| 全局地址列表 | 最多 24 小时 |
代理用户功能
- ✅ 添加到 Microsoft Entra 组(包括动态组)
- ✅ 访问仅用户 API(
idtyp=user令牌) - ✅ 拥有邮箱、日历和联系人
- ✅ 参与 Teams 聊天和频道
- ✅ 出现在组织架构图和人员搜索中
- ✅ 添加到管理单元
- ✅ 分配许可证
代理用户安全约束
- ❌ 不能有密码、通行密钥或交互式登录
- ❌ 不能分配特权管理员角色
- ❌ 不能添加到可分配角色的组
- ❌ 默认权限类似于来宾用户
- ❌ 不支持自定义角色分配
故障排除
| 错误 | 原因 | 修复 |
|---|---|---|
Agent user IdentityParent does not exist |
identityParentId 指向不存在或非代理标识的对象 |
验证 ID 是 agentIdentity 服务主体,而不是常规应用 |
400 Bad Request(identityParentId 已关联) |
代理标识已有一个代理用户 | 每个代理标识仅支持一个代理用户 |
409 Conflict(UPN 冲突) |
userPrincipalName 已被占用 |
使用唯一的 UPN |
| 许可证分配失败 | 未设置使用位置 | 在分配许可证之前设置 usageLocation |






