合作伙伴赚取的额度故障排除指南
适当的角色:用户管理管理员 |管理员代理 |计费管理员 |销售代理
排查常见方案的问题
借助 Azure 新的商业体验,合作伙伴可以通过合作伙伴赚取的返点 (PEC) 获得所管理服务的折扣。 仅向具有合格权限的合作伙伴授予 PEC。 了解有资格获得 PEC 的人员、计算方式和付款方式。
本文提供基本故障排除指南(如果未授予 PEC)。
先决条件
如果 PEC 出现问题(如访问或缺少信息),请先检查以下项目。
注意
只有间接提供商和直接计费合作伙伴才有资格获得 PEC。
请确保查看 G(新商业体验)发票和对帐文件。 Azure 计划和 PEC 不会显示在 D(旧版)发票或对帐文件中。
确认Microsoft AI 云合作伙伴计划协议处于活动状态。
确认产品/服务符合条件。 (旧版 Azure 产品/服务、Azure 预留实例、Azure 储蓄计划、Azure SPOT VM 和第三方产品不符合条件。
确认(或作为 Azure 计划记录经销商设置的间接经销商)对订阅/资源组/资源的订阅/资源组/资源具有有效的管理(AOBO)或 Azure 基于角色的访问控制(Azure RBAC)角色。 也可使用以下命令:
- 如果使用的是 Azure Lighthouse,请确保 PartnerID 已链接到至少一个用户帐户。 另请检查它是否有权访问该客户的订阅/资源组。
- 如果使用的是 Azure RBAC 关联,请确保用户在每个客户租户上下文中对 PEC 和 Azure RBAC 设置具有符合条件的角色。
查看客户是否已删除 AOBO 权限。 预配 Azure 计划时,默认设置权限。 如果已删除,请参阅恢复客户的 Azure 云解决方案提供商 (CSP) 订阅的管理员权限。
确认拥有一整天的管理员访问权限。
确认正在查看对帐文件中的正确列。 有关详细信息,请参阅 Azure 计划计费:关于发票对帐文件。
多部分方案
对于 PEC,事务处理合作伙伴设置任何可用权限选项都很重要。 对于间接模型,它可以是提供商或经销商,也可以是两者。
另一个合作伙伴设置其他 AOBO 或其他权限,并为具有 Azure RBAC 权限的用户设置其他 Azure RBAC 不会影响交易合作伙伴的 PEC。
请参见下表。 MPN1 是间接提供商,MPN2 是作为记录经销商链接到交易的间接经销商,MPN3 是另一个 CSP 合作伙伴(直接或另一个间接经销商):
交易合作伙伴 (BillTo) | Azure RBAC(适用于具有符合 PEC 资格角色的用户或 Lighthouse) | AOBO(符合 PEC 资格的角色) | PEC |
---|---|---|---|
MPN1 | MPN1 | 空值 | 是 |
MPN1 | 空值 | MPN1 | 是 |
MPN1 | MPN2 | 空值 | 是 |
MPN1 | 空值 | MPN2 | 是 |
MPN1 | MPN3 | MPN1 | 是 |
MPN1 | MPN1 | MPN3 | 是 |
MPN1 | MPN1 | MPN2 | 是 |
MPN1 | MPN2 | MPN1 | 是 |
MPN1 | MPN2 | MPN3 | 是 |
MPN1 | MPN3 | MPN2 | 是 |
MPN1 | MPN3 | 空值 | 否 |
MPN1 | 空值 | MPN3 | 否 |
MPN1 | 空值 | 空值 | 否 |
MPN1 | MPN3 | MPN3 | 否 |
Azure 订阅传输
当合作伙伴从其他合作伙伴转移 Azure 订阅时,不会更改此转移的权限。
因此,如果在传输之前使用了 AOBO 或其他权限模型,并且为旧的“交易伙伴”设置了权限,则权限仍将指向转移后的旧合作伙伴。 但现在,另一个合作伙伴成为“交易伙伴”。
对于任何 Azure 订阅转移,建议新目标合作伙伴在传输之前添加权限,例如 Azure RBAC。 他们可以安全地做到这一点,而不会影响老伙伴的PEC,直到转会。
PartnerID 更新
合作伙伴中心允许更改 与 CSP 注册关联的 PartnerID。 将 PartnerID 更新到同一Microsoft AI 云合作伙伴计划全球组织(同一Microsoft AI 云合作伙伴计划全局 ID 下的另一个Microsoft AI 云合作伙伴计划位置 ID)中的另一个Microsoft AI 云合作伙伴计划位置 ID 不会影响 PEC。
但是,当 PartnerID 更改为不同Microsoft AI 云合作伙伴计划组织中的位置 ID 时,PEC 可能会受到影响。 在此实例中,当 PEC 原来缺少时,我们建议联系支持人员(提及你最近将 CSP 注册重新映射到其他Microsoft AI 云合作伙伴计划组织)。
如何验证 AOBO 权限
当合作伙伴为客户创建 Azure 计划订阅时,AOBO 以“外部主体”的形式设置。 外部主体继承对 Azure 订阅的所有者权限。 AOBO 权限意味着 CSP 合作伙伴中心租户(管理员代理)中的某个组将继承 这些权限。
如Azure 门户所示的外国主体不包括有关它映射到特定合作伙伴租户中的组的详细信息。
在Azure 门户中查看外主体时,它会显示合作伙伴名称,例如“Contoso 的外主体”...“,但”Contoso“只是合作伙伴Microsoft Entra 租户的显示名称,并且不是唯一的。
使用 AZ PowerShell 或 Azure CLI 需要验证是否正确设置了 AOBO,并指向正确 CSP 租户中的正确组。
步骤 1 - 标识交易伙伴的代理组的 objectID
- 通过Azure 门户:合作伙伴可以在自己的租户中登录到Azure 门户,并在 Microsoft Entra ID > 组中搜索相应的组。 ObjectID 显示在组名称右侧。
- 通过 PowerShell:启动 PowerShell( 本地 PowerShell 或 Azure Cloud Shell)。
使用 Azure Cloud Shell 之前,需要设置存储帐户。 此帐户在租户上下文中提供的 Azure 订阅中每月会产生少量费用。 可以在执行以下步骤后删除共享。
注意
自 2024 年 3 月 30 日起,Azure AD 和 MSOnline PowerShell 模块已弃用。 若要了解详细信息,请阅读有关弃用的更新。 在此日期之后,对这些模块的支持仅限于到 Microsoft Graph PowerShell SDK 的迁移帮助和安全性修复。 弃用的模块将持续运行至 2025 年 3 月 30 日。
我们建议迁移到 Microsoft Graph PowerShell,以便与 Microsoft Entra ID(以前称为 Azure AD)进行交互。 有关常见迁移问题,请参阅迁移常见问题解答。 注意:2024 年 6 月 30 日之后,MSOnline 版本 1.0.x 可能会遇到中断。
请确保已安装以下模块并将其更新到最新版本:
- AzureAD 模块
- AZ PowerShell 模块 (Cloud Shell 不需要)
如果需要,请使用 PowerShell 窗口中的以下内容 cmdlets
安装这些模块:
Install-Module -Name AzureAD -Force
Install-Module -Name Az -AllowClobber -Force
首先,使用合作伙伴中心用户帐户连接到合作伙伴中心租户,并获取 AdminAgents 和 HelpdeskAgents 组的对象 ID:
Connect-AzureAD -TenantDomain CSPtenantname.onmicrosoft.com
使用合作伙伴中心凭据登录:
查询有关代理组的信息:
Get-AzureADGroup | Where-Object { $_.DisplayName.Endswith('Agents') }
组 ObjectID
的名称将显示:
注意
如果未获得结果,请确保已连接到合作伙伴中心帐户。
注意
间接经销商看不到 SalesAgents 组。 此步骤只需执行一次,因为每个客户租户中的 AOBO 都将使用相同的 ID。
步骤 2 - 将 ObjectID 与外主体使用的对象进行比较
请务必将 TenantID 用作租户参数(而不是租户域名)的值,其用户帐户之一是: - 有权访问多个目录/租户(如合作伙伴中心用户帐户),或者已作为来宾添加到多个租户。
因此,需要给定客户的 TenantID。
通过Azure 门户:可以从合作伙伴中心的客户列表中轻松获取 TenantID。 tenantID 标记为“Microsoft ID”:
通过 PowerShell:使用有效凭据连接到客户的 Azure 订阅。 凭据应有权读取客户租户的 Azure 订阅和 AzureAD:
Connect-AzAccount -Tenant $CustomerTenantID
- 读取客户的 Azure 订阅的外主体的角色分配:
Get-AzRoleassignment | ? {$_.DisplayName -like "Foreign*"}
- 生成的 ObjectID 应与步骤 1 中标识的 AdminAgent 或 HelpDeskAgent 组的 ObjectID 匹配。
总结
每个方面都需要匹配才能通过 AOBO 接收 PEC:
- 客户的 Azure 订阅具有具有合格 Azure RBAC 角色分配的外国主体。
- 外部主体使用的组的 ObjectID 是指合作伙伴租户中 AdminAgent 或 HelpdeskAgent 组的 ObjectID。
- “合作伙伴租户”是指直接计费合作伙伴租户。 在间接模型中,这意味着间接提供商或间接经销商合作伙伴租户。
示例脚本
本部分包含的示例脚本可帮助跨多个订阅收集信息并将其存储在其中。CSV 文件。 这些脚本是示例,在不受支持的情况下按原样提供。 尽管脚本未在设置中进行修改,但应对其进行全面测试,并且可能需要对具体的合作伙伴/客户方案进行自定义。
- 列出单个客户的 AOBO 详细信息:此示例使用 Microsoft Entra ID 和 Azure PowerShell 模块。
### Install-Module -Name AzureAD -Force ###
### Install-Module -Name Az -AllowClobber -Force ###
### Variables ####
$CSVname = "c:tempAOBOchecker.csv"
$CustomertenantId = ""
### Get Agent-Groups Object IDs and write to CSV - This step needs to be done with a Partner Center User ###
Connect-AzureAD -TenantDomain $PartnerTenantDomain
$Headers = "GroupName`tObjectID`tPartnerTenantName`tPartnerTenantID" >>$CSVname
$PartnerTenant = Get-AzureADTenantDetail
$groups = Get-AzureADGroup | Where-Object { $_.DisplayName.Endswith('Agents') }
ForEach ($Group in $Groups)
{
$NewLine = $Group.DisplayName + "`t" + $Group.ObjectID + "`t" + $PartnerTenant.DisplayName + "`t" + $PartnerTenant.ObjectID
$NewLine >>$CSVname
}
### Get list of Azure Subscriptions for a customer, get list of Foreign Principals and add them to the same CSV ###
Clear-AzContext -Scope CurrentUser -Force
Connect-AzAccount -Tenant $CustomertenantId
$CustomerTenant = Get-AzureADTenantDetail
$CustomerTenantSubscriptions = Get-AzSubscription -TenantId $CustomertenantId
ForEach ($Subscription in $CustomerTenantSubscriptions)
{
$Roles = Get-AzRoleassignment -Scope /subscriptions/$Subscription | ? {$_.DisplayName -like "Foreign*"}
ForEach ($Role in $Roles)
{
$NewLine = $CustomerTenant.Domain + "`t" + $CustomerTenant.CustomerId + "`t" + $Subscription.Id + "`t" + $Role.DisplayName + "`t" + $Role.ObjectID + "`t" + $Role.RoleDefinitionName
$NewLine >>$CSVname
}
}
- 列出多个客户的 AOBO 详细信息:此代码仅用于说明目的。
- 获取 CSP 客户和所有外部主体的所有订阅的列表,并确定是否存在不匹配。 此代码还可用于收集支持信息。
- 检查是否已销售哪些 Azure 订阅(Azure 计划权利),以及哪些订阅可通过当前凭据进行访问。
- 对于间接经销商,此脚本也有效。 但是,即使所有订阅是此销售记录的合作伙伴,所有订阅都将有“未出售”的便条。
### Note - below examples use interactive login experience and aren't suitable for production use ###
### See https://learn.microsoft.com/partner-center/develop/enable-secure-app-model#powershell for info on how to authenticate to each customer tenant silently using secure app model ###
### Below examples use AzureAD, AZ and Partner Center PowerShell modules ###
### Install-Module -Name AzureAD -Force ###
### Install-Module -Name Az -AllowClobber -Force ###
### Install-Module -Name PartnerCenter -Force ###
### Variables ####
$PartnertenantDomain = "xyz.onmicrosoft.com"
$PartnerTenantID = ""
$CSVname = "c:tempAOBOchecker.csv"
### Get Agent-Groups Object IDs and write to CSV ###
Connect-AzureAD -TenantDomain $PartnerTenantDomain
$Headers = "GroupName`tObjectID`tPartnerTenantName`tPartnerTenantID" >>$CSVname
$PartnerTenant = Get-AzureADTenantDetail
$groups = Get-AzureADGroup | Where-Object { $_.DisplayName.Endswith('Agents') }
ForEach ($Group in $Groups)
{
$NewLine = $Group.DisplayName + "`t" + $Group.ObjectID + "`t" + $PartnerTenant.DisplayName + "`t" + $PartnerTenant.ObjectID
$NewLine >>$CSVname
}
### Get list of CSP Customers, get List of Azure Subscriptions, get list of Foreign Principals and add them to the same CSV ###
Connect-PartnerCenter -TenantID $PartnertenantID
$Customers = Get-PartnerCustomer
$Headers = "`r`nCustomerTenantName`tCustomerTenantID`tSubscriptionId`tForeignPrincipalName`tObjectID`tAzureRBACRole`tTimeChecked`tNotes`tCredentialsUsedForAccessCheck" >>$CSVname
Foreach ($customer in $Customers)
{
$AzurePlanId = Get-PartnerCustomerSubscription -CustomerId $Customer.CustomerId | ? {$_.OfferName -eq "Azure Plan"}
if ($AzurePlanID -eq $null)
{
Write-Host "Customer $($Customer.Name) does not have Azure Plan"
}
else
{
$AzurePlanSubscriptionsSold = Get-PartnerCustomerAzurePlanEntitlement -CustomerId $Customer.CustomerId -SubscriptionId $AzurePlanId.SubscriptionId
}
Clear-AzContext -Scope CurrentUser -Force
Connect-AzAccount -Tenant $Customer.CustomerId
$CurrentUser = Get-azcontext
$CustomerTenantSubscriptionsAccessible = Get-AzSubscription -TenantId $Customer.CustomerId
$SoldAndAccessibleSubscriptions = $AzurePlanSubscriptionsSold | Where {$CustomerTenantSubscriptionsAccessible -Contains $_}
$SoldButNotAccessibleSubscriptions = $AzurePlanSubscriptionsSold | Where {$CustomerTenantSubscriptionsAccessible -notcontains $_}
$NotSoldButAccessibleSubscriptions = $CustomerTenantSubscriptionsAccessible | Where {$AzurePlanSubscriptionsSold -notcontains $_}
ForEach ($Subscription in $SoldAndAccessibleSubscriptions)
{
$Roles = Get-AzRoleassignment -Scope /subscriptions/$Subscription | ? {$_.DisplayName -like "Foreign*"}
ForEach ($Role in $Roles)
{
$CurrentTime = Get-Date -format "dd-MMM-yyyy HH:mm:ss"
$NewLine = $Customer.Domain + "`t" + $Customer.CustomerId + "`t" + $Subscription.Id + "`t" + $Role.DisplayName + "`t" + $Role.ObjectID + "`t" + $Role.RoleDefinitionName + "`t" + $CurrentTime + "`t" + "Access with current credentials and sold as CSP Partner" + "`t" + $CurrentUser.Account.Id
$NewLine >>$CSVname
}
}
ForEach ($Subscription in $SoldButNotAccessibleSubscriptions)
{
$CurrentTime = Get-Date -format "dd-MMM-yyyy HH:mm:ss"
$NewLine = $Customer.Domain + "`t" + $Customer.CustomerId + "`t" + "N/A" + "`t" + "N/A" + "`t" + "N/A" + "`t" + "N/A" + "`t" + $CurrentTime + "`t" + "Sold via CSP, but no access with current credentials" + "`t" + $CurrentUser.Account.Id
$NewLine >>$CSVname
}
ForEach ($Subscription in $NotSoldButAccessibleSubscriptions)
{
$Roles = Get-AzRoleassignment -Scope /subscriptions/$Subscription | ? {$_.DisplayName -like "Foreign*"}
ForEach ($Role in $Roles)
{
$CurrentTime = Get-Date -format "dd-MMM-yyyy HH:mm:ss"
$NewLine = $Customer.Domain + "`t" + $Customer.CustomerId + "`t" + $Subscription.Id + "`t" + $Role.DisplayName + "`t" + $Role.ObjectID + "`t" + $Role.RoleDefinitionName + "`t" + $CurrentTime + "`t" + "Access with current credentials, but not sold as CSP Partner" + "`t" + $CurrentUser.Account.Id
$NewLine >>$CSVname
}
}
}
如何验证 Azure Lighthouse 权限和 Azure PAL
与 AOBO 一样, Azure Lighthouse 允许(合作伙伴)管理租户中的用户组继承客户的 Azure 订阅中的委派权限。 区别在于,它允许比 AOBO 更精细地定义组和权限级别。
对于此权限模型,使用 Azure 门户 UI 验证是否已正确设置权限模型更容易。 只有合作伙伴才能提供 Azure Lighthouse 设置正确的完整验证。
以下步骤介绍如何确定 Azure RBAC 角色权限已永久委托给哪些客户以及哪些组。 然后,可以检查具有 Azure RBAC 关联的用户是否是这些组的成员。
步骤 1 - 检查 Lighthouse 对客户的委托
验证适用的委派是否使用符合 PEC 资格的 Azure RBAC 角色。
打开Azure 门户(与合作伙伴管理租户中的用户一起)。 然后搜索“Lighthouse”并选择“ 我的客户”。
在客户概述中,选择 左侧的“委派 ”。 这样做会打开提供委派访问权限的资源列表(订阅或资源组):
在“角色分配”下的右侧列中打开委派,查看合作伙伴/管理租户中的哪个用户组继承了每种权限(请参阅“角色”列)。 还可以查看这些权限是否永久(请参阅“访问类型”列):
步骤 2 - 检查组成员身份
选择组的显示名称。 请打开组详细信息。 选择“成员”来控制哪个用户设置了 Azure RBAC,并且是相应组的成员:
步骤 3 – 检查用户是否已设置 Azure PAL
只有已设置 Azure PAL 的用户才能检查 Azure PAL 分配;其他管理员用户无法执行此操作。 有关用户如何通过 UI 或 PowerShell 验证是否已设置 Azure PAL 的详细信息,请参阅如何实现说明合作伙伴管理员链接(PAL)与我的客户?在将 Azure 帐户链接到 PartnerID 中。
注意
Azure PAL 应使用作为此 Azure 订阅交易合作伙伴的同一Microsoft AI 云合作伙伴计划组织的一部分的 PartnerID。 在间接模型中,可以是提供商的 PartnerID 或附加到此销售的特定经销商。
步骤 4 - 检查时间限制组分配
由于组成员身份可能不是永久性的,因此请检查是否已为该组启用了特权访问管理。 在组设置的“活动”下,查看左侧的“特权访问”。 如果为 true,请检查用户是否有活动分配和此分配的时间范围。
注意
由于分配“结束时间”是用户自动从组中删除时,因此对于设置了 Azure RBAC 的用户,PEC 将会丢失。 同样,只有在分配“开始时间”之后才授予 PEC。
如何验证单个用户分配和 Azure PAL
在某些情况下,使用对 Azure 订阅具有权限的单个用户帐户可能更合适。 这些帐户可以是来宾用户帐户(来自任何租户)或客户租户或服务主体中创建的用户帐户。
将单个用户帐户用作获取 PEC 的工具时,检查只需查看用户的 Azure 订阅管理中分配的权限,并验证用户是否已正确设置 Azure RBAC。 使用服务主体时,需要通过 PowerShell 检查 Azure RBAC。
步骤 1 - 查看 Azure 订阅管理中的权限
打开 Azure 门户。 请确保以具有 Azure RBAC 角色的用户身份登录,该用户至少具有对该订阅的读取访问权限。
在搜索栏中搜索“订阅”以打开订阅详细信息:
转到订阅详细信息中的“访问控制(IAM)。” 然后选择“角色分配”以查看在订阅级别具有访问权限的用户,如果“角色”列显示符合 PEC 资格的 Azure RBAC 角色。 如果已在资源组级别设置权限,资源组中也提供了相同的“访问控制(IAM)”视图。
注意
还可以向一组用户授予权限,其中还需要验证具有 Azure RBAC 集的用户的组成员身份。
步骤 2 – 确保权限是永久性的,并且不会应用拒绝分配
尽管用户可能具有访问权限,但他们的权限仍可能是临时的,或者通过拒绝分配阻止。
使用 Privileged Identity Management (PIM) Azure RBAC 角色分配可能会有时间限制。 虽然你可能会看到具有权限的用户,但它们可能只存在很短的时间。 若要验证 Azure RBAC 角色分配是否为永久性,请检查Azure 门户中的 PIM 管理。 具体而言,检查订阅中的 Azure 资源由 PIM 策略管理的位置,以及用户是否受任何策略的约束。
此外,权限列表可能显示用户对订阅具有权限,但可能存在拒绝分配,但仍会阻止用户访问某些内容。 在“访问控制(IAM)”中,选择“拒绝分配”选项卡以查看“拒绝分配”是否适用:
注意
为了完成,合作伙伴还应验证资源组中是否存在拒绝分配。
步骤 3 – 检查用户是否已设置 Azure PAL
只有已设置 Azure PAL 的用户才能检查 Azure PAL 分配;其他管理员用户无法执行此操作。 有关如何验证 Azure PAL 是否已设置的详细信息,请参阅 将 Azure 帐户链接到 PartnerID。
注意
Azure PAL 应使用作为此 Azure 订阅交易合作伙伴的同一Microsoft AI 云合作伙伴计划组织的一部分的 PartnerID。 在间接模型中,这可以是提供商的 PartnerID,也可以是附加到此销售的经销商的 PartnerID。