使用 PowerShell 或 Microsoft Graph API 配置跨租户同步
本文介绍使用 Microsoft Graph PowerShell 或 Microsoft Graph API 配置跨租户同步的关键步骤。 配置后,Microsoft Entra ID 会自动预配和取消预配目标租户中的 B2B 用户。 有关使用 Microsoft Entra 管理中心的详细步骤,请参阅配置跨租户同步。
先决条件
源租户
- Microsoft Entra ID P1 或 P2 许可证。 有关详细信息,请参阅许可证要求。
- 用于配置跨租户访问设置的安全管理员角色。
- 用于配置跨租户同步的混合标识管理员角色。
- 用于将用户分配到某个配置和删除配置的云应用程序管理员或应用程序管理员角色。
- 用于同意所需权限的全局管理员角色。
目标租户
步骤 1:登录到目标租户
目标租户
启动 PowerShell。
如有必要,请安装 Microsoft Graph PowerShell SDK。
获取源租户和目标租户的租户 ID 并初始化变量。
$SourceTenantId = "<SourceTenantId>" $TargetTenantId = "<TargetTenantId>"
使用 Connect-MgGraph 命令登录到目标租户并同意以下所需权限。
Policy.Read.All
Policy.ReadWrite.CrossTenantAccess
Connect-MgGraph -TenantId $TargetTenantId -Scopes "Policy.Read.All","Policy.ReadWrite.CrossTenantAccess"
步骤 2:在目标租户中启用用户同步
目标租户
在目标租户中,使用 New-MgPolicyCrossTenantAccessPolicyPartner 命令在目标租户和源租户之间的跨租户访问策略中创建新的合作伙伴配置。 在请求中使用源租户 ID。
如果收到错误
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists
,则可能已有现有配置。 有关详细信息,请参阅 Symptom - New-MgPolicyCrossTenantAccessPolicyPartner_Create error。$Params = @{ TenantId = $SourceTenantId } New-MgPolicyCrossTenantAccessPolicyPartner -BodyParameter $Params | Format-List
AutomaticUserConsentSettings : Microsoft.Graph.PowerShell.Models.MicrosoftGraphInboundOutboundPolicyConfiguration B2BCollaborationInbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BCollaborationOutbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BDirectConnectInbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BDirectConnectOutbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting IdentitySynchronization : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantIdentitySyncPolicyPartner InboundTrust : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyInboundTrust IsServiceProvider : TenantId : <SourceTenantId> TenantRestrictions : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyTenantRestrictions AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#policies/crossTenantAccessPolicy/partners/$entity], [crossCloudMeetingConfiguration, System.Collections.Generic.Dictionary`2[System.String,System.Object]], [protectedContentSharing, System.Collections.Generic.Dictionary`2[System.String,System.Object]]}
使用 Invoke-MgGraphRequest 命令在目标租户中启用用户同步。
如果收到错误
Request_MultipleObjectsWithSameKeyValue
,则可能已有现有策略。 有关详细信息,请参阅症状 - Request_MultipleObjectsWithSameKeyValue 错误。$Params = @{ userSyncInbound = @{ isSyncAllowed = $true } } Invoke-MgGraphRequest -Method PUT -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/$SourceTenantId/identitySynchronization" -Body $Params
使用 Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令验证
IsSyncAllowed
是否设置为 True。(Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
IsSyncAllowed ------------- True
步骤 3:在目标租户中自动兑换邀请
目标租户
在目标租户中,使用 Update-MgPolicyCrossTenantAccessPolicyPartner 命令自动兑换邀请并禁止入站访问的同意提示。
$AutomaticUserConsentSettings = @{ "InboundAllowed"="True" } Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
步骤 4:登录到源租户
源租户
启动 PowerShell 的实例。
获取源租户和目标租户的租户 ID 并初始化变量。
$SourceTenantId = "<SourceTenantId>" $TargetTenantId = "<TargetTenantId>"
使用 Connect-MgGraph 命令登录到源租户并同意以下所需权限。
Policy.Read.All
Policy.ReadWrite.CrossTenantAccess
Application.ReadWrite.All
Directory.ReadWrite.All
AuditLog.Read.All
Connect-MgGraph -TenantId $SourceTenantId -Scopes "Policy.Read.All","Policy.ReadWrite.CrossTenantAccess","Application.ReadWrite.All","Directory.ReadWrite.All","AuditLog.Read.All"
步骤 5:在源租户中自动兑换邀请
源租户
在源租户中,使用 New-MgPolicyCrossTenantAccessPolicyPartner 命令在源租户和目标租户之间的跨租户访问策略中创建新的合作伙伴配置。 在请求中使用目标租户 ID。
如果收到错误
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists
,则可能已有现有配置。 有关详细信息,请参阅 Symptom - New-MgPolicyCrossTenantAccessPolicyPartner_Create error。$Params = @{ TenantId = $TargetTenantId } New-MgPolicyCrossTenantAccessPolicyPartner -BodyParameter $Params | Format-List
AutomaticUserConsentSettings : Microsoft.Graph.PowerShell.Models.MicrosoftGraphInboundOutboundPolicyConfiguration B2BCollaborationInbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BCollaborationOutbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BDirectConnectInbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting B2BDirectConnectOutbound : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyB2BSetting IdentitySynchronization : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantIdentitySyncPolicyPartner InboundTrust : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyInboundTrust IsServiceProvider : TenantId : <TargetTenantId> TenantRestrictions : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCrossTenantAccessPolicyTenantRestrictions AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#policies/crossTenantAccessPolicy/partners/$entity], [crossCloudMeetingConfiguration, System.Collections.Generic.Dictionary`2[System.String,System.Object]], [protectedContentSharing, System.Collections.Generic.Dictionary`2[System.String,System.Object]]}
使用 Update-MgPolicyCrossTenantAccessPolicyPartner 命令自动兑换邀请并禁止出站访问的同意提示。
$AutomaticUserConsentSettings = @{ "OutboundAllowed"="True" } Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $TargetTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
步骤 6:在源租户中创建配置应用程序
源租户
在源租户中,使用 Invoke-MgInstantiateApplicationTemplate 命令将配置应用程序的实例从 Microsoft Entra 应用程序库添加到租户中。
Invoke-MgInstantiateApplicationTemplate -ApplicationTemplateId "518e5f48-1fc8-4c48-9387-9fdf28b0dfe7" -DisplayName "Fabrikam"
使用 Get-MgServicePrincipal 命令获取服务主体 ID 和应用角色 ID。
Get-MgServicePrincipal -Filter "DisplayName eq 'Fabrikam'" | Format-List
AccountEnabled : True AddIns : {} AlternativeNames : {} AppDescription : AppDisplayName : Fabrikam AppId : <AppId> AppManagementPolicies : AppOwnerOrganizationId : <AppOwnerOrganizationId> AppRoleAssignedTo : AppRoleAssignmentRequired : True AppRoleAssignments : AppRoles : {<AppRoleId>} ApplicationTemplateId : 518e5f48-1fc8-4c48-9387-9fdf28b0dfe7 ClaimsMappingPolicies : CreatedObjects : CustomSecurityAttributes : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCustomSecurityAttributeValue DelegatedPermissionClassifications : DeletedDateTime : Description : DisabledByMicrosoftStatus : DisplayName : Fabrikam Endpoints : ErrorUrl : FederatedIdentityCredentials : HomeRealmDiscoveryPolicies : Homepage : https://account.activedirectory.windowsazure.com:444/applications/default.aspx?metadata=aad2aadsync|ISV9.1|primary|z Id : <ServicePrincipalId> Info : Microsoft.Graph.PowerShell.Models.MicrosoftGraphInformationalUrl KeyCredentials : {} LicenseDetails : ...
初始化服务主体 ID 的变量。
请务必使用服务主体 ID 而不是应用程序 ID。
$ServicePrincipalId = "<ServicePrincipalId>"
初始化应用角色 ID 的变量。
$AppRoleId= "<AppRoleId>"
步骤 7:测试与目标租户的连接
源租户
在源租户中,使用 Invoke-MgGraphRequest 命令测试与目标租户的连接并验证凭据。
$Params = @{ "useSavedCredentials" = $false "templateId" = "Azure2Azure" "credentials" = @( @{ "key" = "CompanyId" "value" = $TargetTenantId } @{ "key" = "AuthenticationType" "value" = "SyncPolicy" } ) } Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$ServicePrincipalId/synchronization/jobs/validateCredentials" -Body $Params
步骤 8:在源租户中创建预配作业
源租户
在源租户中,若要启用预配,请创建预配作业。
确定要使用的同步模板,例如
Azure2Azure
。模板具有已预配置的同步设置。
在源租户中,使用 New-MgServicePrincipalSynchronizationJob 命令基于模板创建预配作业。
New-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId -TemplateId "Azure2Azure" | Format-List
Id : <JobId> Schedule : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationSchedule Schema : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationSchema Status : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationStatus SynchronizationJobSettings : {AzureIngestionAttributeOptimization, LookaheadQueryEnabled} TemplateId : Azure2Azure AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('<ServicePrincipalId>')/synchro nization/jobs/$entity]}
初始化作业 ID 的变量。
$JobId = "<JobId>"
步骤 9:保存凭据
源租户
在源租户中,使用 Invoke-MgGraphRequest 命令保存你的凭据。
$Params = @{ "value" = @( @{ "key" = "AuthenticationType" "value" = "SyncPolicy" } @{ "key" = "CompanyId" "value" = $TargetTenantId } ) } Invoke-MgGraphRequest -Method PUT -Uri "https://graph.microsoft.com/v1.0/servicePrincipals/$ServicePrincipalId/synchronization/secrets" -Body $Params
步骤 10:将用户分配到配置
源租户
若要使跨租户同步工作,必须向配置分配至少一个内部用户。
在源租户中,使用 New-MgServicePrincipalAppRoleAssignedTo 命令将内部用户分配到配置。
$Params = @{ PrincipalId = "<PrincipalId>" ResourceId = $ServicePrincipalId AppRoleId = $AppRoleId } New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $ServicePrincipalId -BodyParameter $Params | Format-List
AppRoleId : <AppRoleId> CreatedDateTime : 7/31/2023 10:27:12 PM DeletedDateTime : Id : <Id> PrincipalDisplayName : User1 PrincipalId : <PrincipalId> PrincipalType : User ResourceDisplayName : Fabrikam ResourceId : <ServicePrincipalId> AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#appRoleAssignments/$entity]}
步骤 11:测试按需预配
源租户
完成配置后,可以使用其中一个用户测试按需预配。
在源租户中,使用 Get-MgServicePrincipalSynchronizationJobSchema 命令获取架构规则 ID。
$SynchronizationSchema = Get-MgServicePrincipalSynchronizationJobSchema -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId $SynchronizationSchema.SynchronizationRules | Format-List
ContainerFilter : Microsoft.Graph.PowerShell.Models.MicrosoftGraphContainerFilter Editable : True GroupFilter : Microsoft.Graph.PowerShell.Models.MicrosoftGraphGroupFilter Id : <RuleId> Metadata : {defaultSourceObjectMappings, supportsProvisionOnDemand} Name : USER_INBOUND_USER ObjectMappings : {Provision Azure Active Directory Users, , , ...} Priority : 1 SourceDirectoryName : Azure Active Directory TargetDirectoryName : Azure Active Directory (target tenant) AdditionalProperties : {}
初始化规则 ID 的变量。
$RuleId = "<RuleId>"
使用 New-MgServicePrincipalSynchronizationJobOnDemand 命令按需预配某个测试用户。
$Params = @{ Parameters = @( @{ Subjects = @( @{ ObjectId = "<UserObjectId>" ObjectTypeName = "User" } ) RuleId = $RuleId } ) } New-MgServicePrincipalSynchronizationJobOnDemand -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId -BodyParameter $Params | Format-List
Key : Microsoft.Identity.Health.CPP.Common.DataContracts.SyncFabric.StatusInfo Value : [{"provisioningSteps":[{"name":"EntryImport","type":"Import","status":"Success","description":"Retrieved User 'user1@fabrikam.com' from Azure Active Directory","timestamp":"2023-07-31T22:31:15.9116590Z","details":{"objectId": "<UserObjectId>","accountEnabled":"True","displayName":"User1","mailNickname":"user1","userPrincipalName":"use ... AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.stringKeyStringValuePair]}
步骤 12:启动预配作业
源租户
配置预配作业后,请在源租户中使用 Start-MgServicePrincipalSynchronizationJob 命令启动预配作业。
Start-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId
步骤 13:监视预配
源租户
现在预配作业正在运行,请在源租户中使用 Get-MgServicePrincipalSynchronizationJob 命令监视当前预配周期的进度以及到目前为止的统计信息,例如已在目标系统中创建的用户和组数。
Get-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId | Format-List
Id : <JobId> Schedule : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationSchedule Schema : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationSchema Status : Microsoft.Graph.PowerShell.Models.MicrosoftGraphSynchronizationStatus SynchronizationJobSettings : {AzureIngestionAttributeOptimization, LookaheadQueryEnabled} TemplateId : Azure2Azure AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('<ServicePrincipalId>')/synchro nization/jobs/$entity]}
除了监视预配作业的状态外,还可以使用 Get-MgAuditLogProvisioning 命令检索预配日志并获取发生的所有预配事件。 例如,查询特定用户并确定他们是否已成功预配。
Get-MgAuditLogDirectoryAudit | Select -First 10 | Format-List
ActivityDateTime : 7/31/2023 12:08:17 AM ActivityDisplayName : Export AdditionalDetails : {Details, ErrorCode, EventName, ipaddr...} Category : ProvisioningManagement CorrelationId : aaaa0000-bb11-2222-33cc-444444dddddd Id : Sync_aaaa0000-bb11-2222-33cc-444444dddddd_L5BFV_161778479 InitiatedBy : Microsoft.Graph.PowerShell.Models.MicrosoftGraphAuditActivityInitiator1 LoggedByService : Account Provisioning OperationType : Result : success ResultReason : User 'user2@fabrikam.com' was created in Azure Active Directory (target tenant) TargetResources : {<ServicePrincipalId>, } AdditionalProperties : {} ActivityDateTime : 7/31/2023 12:08:17 AM ActivityDisplayName : Export AdditionalDetails : {Details, ErrorCode, EventName, ipaddr...} Category : ProvisioningManagement CorrelationId : aaaa0000-bb11-2222-33cc-444444dddddd Id : Sync_aaaa0000-bb11-2222-33cc-444444dddddd_L5BFV_161778264 InitiatedBy : Microsoft.Graph.PowerShell.Models.MicrosoftGraphAuditActivityInitiator1 LoggedByService : Account Provisioning OperationType : Result : success ResultReason : User 'user2@fabrikam.com' was updated in Azure Active Directory (target tenant) TargetResources : {<ServicePrincipalId>, } AdditionalProperties : {} ActivityDateTime : 7/31/2023 12:08:14 AM ActivityDisplayName : Synchronization rule action AdditionalDetails : {Details, ErrorCode, EventName, ipaddr...} Category : ProvisioningManagement CorrelationId : aaaa0000-bb11-2222-33cc-444444dddddd Id : Sync_aaaa0000-bb11-2222-33cc-444444dddddd_L5BFV_161778395 InitiatedBy : Microsoft.Graph.PowerShell.Models.MicrosoftGraphAuditActivityInitiator1 LoggedByService : Account Provisioning OperationType : Result : success ResultReason : User 'user2@fabrikam.com' will be created in Azure Active Directory (target tenant) (User is active and assigned in Azure Active Directory, but no matching User was found in Azure Active Directory (target tenant)) TargetResources : {<ServicePrincipalId>, } AdditionalProperties : {}
故障排除提示
故障描述 - 权限不足错误
尝试执行操作时,你收到如下所示的错误消息:
code: Authorization_RequestDenied
message: Insufficient privileges to complete the operation.
原因
登录用户没有足够的权限,或者你需要同意其中一个所需的权限。
解决方案
确保为你分配了所需的角色。 请参阅本文前面的先决条件。
使用 Connect-MgGraph 登录时,请确保指定所需的范围。 请参阅本文前面的步骤 1:登录到目标租户和步骤 4:登录到源租户。
症状 - New-MgPolicyCrossTenantAccessPolicyPartner_Create 错误
尝试创建新的合作伙伴配置时,会收到类似于以下内容的错误消息:
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists.
原因
你可能正在试图根据以前的配置创建一个已经存在的配置或对象。
解决方案
检查你的语法以及你使用的租户 ID 是否正确。
使用 Get-MgPolicyCrossTenantAccessPolicyPartner 命令列出现有对象。
如果你有现有的对象,则可能需要使用 Update-MgPolicyCrossTenantAccessPolicyPartner 进行更新
症状 - Request_MultipleObjectsWithSameKeyValue 错误
尝试启用用户同步时,会收到类似于以下内容的错误消息:
Invoke-MgGraphRequest: PUT https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/<SourceTenantId>/identitySynchronization
HTTP/1.1 409 Conflict
...
{"error":{"code":"Request_MultipleObjectsWithSameKeyValue","message":"A conflicting object with one or more of the specified property values is present in the directory.","details":[{"code":"ConflictingObjects","message":"A conflicting object with one or more of the specified property values is present in the directory.", ... }}}
原因
你可能正在试图根据以前的配置创建一个已经存在的策略。
解决方案
检查你的语法以及你使用的租户 ID 是否正确。
使用 Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令列出
IsSyncAllowed
设置。(Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
如果你已有策略,则可能需要使用 Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令进行更新,以启用用户同步。
$Params = @{ userSyncInbound = @{ isSyncAllowed = $true } } Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -BodyParameter $Params