使用 PowerShell 或 Microsoft Graph API 配置跨租户同步

本文介绍使用 Microsoft Graph PowerShell 或 Microsoft Graph API 配置跨租户同步的关键步骤。 配置后,Microsoft Entra ID 会自动预配和取消预配目标租户中的 B2B 用户。 有关使用 Microsoft Entra 管理中心的详细步骤,请参阅配置跨租户同步

显示源租户与目标租户之间的跨租户同步的关系图。

先决条件

源租户的图标。
源租户

目标租户的图标。
目标租户

步骤 1:登录到目标租户

目标租户的图标。
目标租户

  1. 启动 PowerShell。

  2. 如有必要,请安装 Microsoft Graph PowerShell SDK

  3. 获取源租户和目标租户的租户 ID 并初始化变量。

    $SourceTenantId = "<SourceTenantId>"
    $TargetTenantId = "<TargetTenantId>"
    
  4. 使用 Connect-MgGraph 命令登录到目标租户并同意以下所需权限。

    • Policy.Read.All
    • Policy.ReadWrite.CrossTenantAccess
    Connect-MgGraph -TenantId $TargetTenantId -Scopes "Policy.Read.All","Policy.ReadWrite.CrossTenantAccess"
    

步骤 2:在目标租户中启用用户同步

目标租户的图标。
目标租户

  1. 在目标租户中,使用 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]]}
    
  2. 使用 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
    
  3. 使用 Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令验证 IsSyncAllowed 是否设置为 True。

    (Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
    
    IsSyncAllowed
    -------------
    True
    

步骤 3:在目标租户中自动兑换邀请

目标租户的图标。
目标租户

  1. 在目标租户中,使用 Update-MgPolicyCrossTenantAccessPolicyPartner 命令自动兑换邀请并禁止入站访问的同意提示。

    $AutomaticUserConsentSettings = @{
        "InboundAllowed"="True"
    }
    Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
    

步骤 4:登录到源租户

源租户的图标。
源租户

  1. 启动 PowerShell 的实例。

  2. 获取源租户和目标租户的租户 ID 并初始化变量。

    $SourceTenantId = "<SourceTenantId>"
    $TargetTenantId = "<TargetTenantId>"
    
  3. 使用 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:在源租户中自动兑换邀请

源租户的图标。
源租户

  1. 在源租户中,使用 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]]}
    
    
  2. 使用 Update-MgPolicyCrossTenantAccessPolicyPartner 命令自动兑换邀请并禁止出站访问的同意提示。

    $AutomaticUserConsentSettings = @{
        "OutboundAllowed"="True"
    }
    Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $TargetTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
    

步骤 6:在源租户中创建配置应用程序

源租户的图标。
源租户

  1. 在源租户中,使用 Invoke-MgInstantiateApplicationTemplate 命令将配置应用程序的实例从 Microsoft Entra 应用程序库添加到租户中。

    Invoke-MgInstantiateApplicationTemplate -ApplicationTemplateId "518e5f48-1fc8-4c48-9387-9fdf28b0dfe7" -DisplayName "Fabrikam"
    
  2. 使用 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                      :
    
    ...
    
  3. 初始化服务主体 ID 的变量。

    请务必使用服务主体 ID 而不是应用程序 ID。

    $ServicePrincipalId = "<ServicePrincipalId>"
    
  4. 初始化应用角色 ID 的变量。

    $AppRoleId= "<AppRoleId>"
    

步骤 7:测试与目标租户的连接

源租户的图标。
源租户

  1. 在源租户中,使用 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:在源租户中创建预配作业

源租户的图标。
源租户

在源租户中,若要启用预配,请创建预配作业。

  1. 确定要使用的同步模板,例如 Azure2Azure

    模板具有已预配置的同步设置。

  2. 在源租户中,使用 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]}
    
  3. 初始化作业 ID 的变量。

    $JobId = "<JobId>"
    

步骤 9:保存凭据

源租户的图标。
源租户

  1. 在源租户中,使用 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:将用户分配到配置

源租户的图标。
源租户

若要使跨租户同步工作,必须向配置分配至少一个内部用户。

  1. 在源租户中,使用 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:测试按需预配

源租户的图标。
源租户

完成配置后,可以使用其中一个用户测试按需预配。

  1. 在源租户中,使用 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 : {}
    
  2. 初始化规则 ID 的变量。

    $RuleId = "<RuleId>"
    
  3. 使用 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:启动预配作业

源租户的图标。
源租户

  1. 配置预配作业后,请在源租户中使用 Start-MgServicePrincipalSynchronizationJob 命令启动预配作业。

    Start-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId
    

步骤 13:监视预配

源租户的图标。
源租户

  1. 现在预配作业正在运行,请在源租户中使用 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]}
    
  2. 除了监视预配作业的状态外,还可以使用 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        : cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec
    Id                   : Sync_cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec_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        : cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec
    Id                   : Sync_cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec_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        : cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec
    Id                   : Sync_cc519f3b-fb72-4ea2-9b7b-8f9dc271c5ec_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.

原因

登录用户没有足够的权限,或者你需要同意其中一个所需的权限。

解决方案

  1. 确保为你分配了所需的角色。 请参阅本文前面的先决条件

  2. 使用 Connect-MgGraph 登录时,请确保指定所需的范围。 请参阅本文前面的步骤 1:登录到目标租户步骤 4:登录到源租户

症状 - New-MgPolicyCrossTenantAccessPolicyPartner_Create 错误

尝试创建新的合作伙伴配置时,会收到类似于以下内容的错误消息:

New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists.

原因

你可能正在试图根据以前的配置创建一个已经存在的配置或对象。

解决方案

  1. 检查你的语法以及你使用的租户 ID 是否正确。

  2. 使用 Get-MgPolicyCrossTenantAccessPolicyPartner 命令列出现有对象。

  3. 如果你有现有的对象,则可能需要使用 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.", ... }}}

原因

你可能正在试图根据以前的配置创建一个已经存在的策略。

解决方案

  1. 检查你的语法以及你使用的租户 ID 是否正确。

  2. 使用 Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令列出 IsSyncAllowed 设置。

    (Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
    
  3. 如果你已有策略,则可能需要使用 Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization 命令进行更新,以启用用户同步。

    $Params = @{
        userSyncInbound = @{
            isSyncAllowed = $true
        }
    }
    Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -BodyParameter $Params
    

后续步骤