Configuración de la sincronización entre inquilinos mediante PowerShell o Microsoft Graph API
En este artículo, se describen los pasos clave para configurar la sincronización entre inquilinos mediante PowerShell de Microsoft Graph o Microsoft Graph API. Cuando se configura, Microsoft Entra ID aprovisiona y desaprovisiona automáticamente usuarios B2B en el inquilino de destino. Para los obtener los pasos detallados con el centro de administración de Microsoft Entra, consulte Configuración de la sincronización entre inquilinos.
Requisitos previos
Inquilino de origen
- Una licencia de Microsoft Entra ID P1 o P2. Para obtener más información, consulte Requisitos de licencia.
- Rol de administrador de seguridad para establecer la configuración de acceso entre inquilinos.
- Rol de administrador de identidad híbrida para configurar la sincronización entre inquilinos.
- Rol de administrador de aplicaciones en la nube o administrador de aplicaciones para asignar usuarios a una configuración y eliminar una configuración.
- Rol de administrador global para dar consentimiento a los permisos necesarios.
Inquilino de destino
- Una licencia de Microsoft Entra ID P1 o P2. Para obtener más información, consulte Requisitos de licencia.
- Rol de administrador de seguridad para establecer la configuración de acceso entre inquilinos.
- Rol de administrador global para dar consentimiento a los permisos necesarios.
Paso 1: inicie sesión en el inquilino de destino
Inquilino de destino
Inicie PowerShell.
Si fuera necesario, instale el SDK de PowerShell de Microsoft Graph.
Obtenga el identificador de inquilino de los inquilinos de origen y de destino e inicialice las variables.
$SourceTenantId = "<SourceTenantId>" $TargetTenantId = "<TargetTenantId>"
Use el comando Connect-MgGraph para iniciar sesión en el inquilino de destino y dar su consentimiento a los siguientes permisos necesarios.
Policy.Read.All
Policy.ReadWrite.CrossTenantAccess
Connect-MgGraph -TenantId $TargetTenantId -Scopes "Policy.Read.All","Policy.ReadWrite.CrossTenantAccess"
Paso 2: Habilitar la sincronización de usuarios en el inquilino de destino
Inquilino de destino
En el inquilino de destino, use el comando New-MgPolicyCrossTenantAccessPolicyPartner para crear una nueva configuración de asociado en una directiva de acceso entre inquilinos entre el inquilino de destino y el inquilino de origen. Use el id. de inquilino de origen en la solicitud.
Si recibe un error
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists
, es posible que ya tenga una configuración existente. Para obtener más información, consulte el error Symptom - New-MgPolicyCrossTenantAccessPolicyPartner_Create.$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]]}
Use el comando Invoke-MgGraphRequest para habilitar la sincronización de usuarios en el inquilino de destino.
Si recibe un error
Request_MultipleObjectsWithSameKeyValue
, es posible que ya tenga una directiva existente. Para obtener más información, consulte Error Symptom - Request_MultipleObjectsWithSameKeyValue.$Params = @{ userSyncInbound = @{ isSyncAllowed = $true } } Invoke-MgGraphRequest -Method PUT -Uri "https://graph.microsoft.com/v1.0/policies/crossTenantAccessPolicy/partners/$SourceTenantId/identitySynchronization" -Body $Params
Use el comando Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization para comprobar si
IsSyncAllowed
está establecido en Verdadero.(Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
IsSyncAllowed ------------- True
Paso 3: Canjear automáticamente invitaciones en el inquilino de destino
Inquilino de destino
En el inquilino de destino, use el comando Update-MgPolicyCrossTenantAccessPolicyPartner para canjear automáticamente las invitaciones y suprimir las solicitudes de consentimiento para el acceso entrante.
$AutomaticUserConsentSettings = @{ "InboundAllowed"="True" } Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
Paso 4: inicie sesión en el inquilino de origen
Inquilino de origen
Inicie una instancia de PowerShell.
Obtenga el identificador de inquilino de los inquilinos de origen y de destino e inicialice las variables.
$SourceTenantId = "<SourceTenantId>" $TargetTenantId = "<TargetTenantId>"
Use el comando Connect-MgGraph para iniciar sesión en el inquilino de origen y dar su consentimiento a los siguientes permisos necesarios.
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"
Paso 5: canjear automáticamente invitaciones en el inquilino de origen
Inquilino de origen
En el inquilino de origen, use el comando New-MgPolicyCrossTenantAccessPolicyPartner para crear una nueva configuración de asociado en una directiva de acceso entre inquilinos entre el inquilino de origen y el inquilino de destino. Use el id. de inquilino de destino en la solicitud.
Si recibe un error
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists
, es posible que ya tenga una configuración existente. Para obtener más información, consulte el error Symptom - New-MgPolicyCrossTenantAccessPolicyPartner_Create.$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]]}
Use el comando Update-MgPolicyCrossTenantAccessPolicyPartner para canjear automáticamente las invitaciones y suprimir las solicitudes de consentimiento del acceso de salida.
$AutomaticUserConsentSettings = @{ "OutboundAllowed"="True" } Update-MgPolicyCrossTenantAccessPolicyPartner -CrossTenantAccessPolicyConfigurationPartnerTenantId $TargetTenantId -AutomaticUserConsentSettings $AutomaticUserConsentSettings
Paso 6: crear una aplicación de configuración en el inquilino de origen
Inquilino de origen
En el inquilino de origen, use el comando Invoke-MgInstantiateApplicationTemplate para agregar una instancia de una aplicación de configuración desde la galería de aplicaciones de Microsoft Entra al inquilino.
Invoke-MgInstantiateApplicationTemplate -ApplicationTemplateId "518e5f48-1fc8-4c48-9387-9fdf28b0dfe7" -DisplayName "Fabrikam"
Use el comando Get-MgServicePrincipal para obtener el id. de entidad de servicio y el id. de rol de aplicación.
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 : ...
Inicializar una variable para el id. de entidad de servicio.
Asegúrese de usar el identificador de la entidad de servicio en lugar del identificador de aplicación.
$ServicePrincipalId = "<ServicePrincipalId>"
Inicializar una variable para el id. de rol de la aplicación.
$AppRoleId= "<AppRoleId>"
Paso 7: probar la conexión al inquilino de destino
Inquilino de origen
En el inquilino de origen, use el comando Invoke-MgGraphRequest para probar la conexión al inquilino de destino y validar las credenciales.
$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
Paso 8: Crear un trabajo de aprovisionamiento en el inquilino de origen
Inquilino de origen
En el inquilino de origen, para habilitar el aprovisionamiento, cree un trabajo de aprovisionamiento.
Determine la plantilla de sincronización que se va a usar, por ejemplo,
Azure2Azure
.Una plantilla tiene opciones de sincronización preconfiguradas.
En el inquilino de origen, use el comando New-MgServicePrincipalSynchronizationJob para crear un trabajo de aprovisionamiento basado en una plantilla.
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]}
Inicializar una variable para el id. de trabajo.
$JobId = "<JobId>"
Paso 9: Guardar las credenciales
Inquilino de origen
En el inquilino de origen, use el comando Invoke-MgGraphRequest para guardar sus credenciales.
$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
Paso 10: asignar un usuario a la configuración
Inquilino de origen
Para que la sincronización entre inquilinos funcione, se debe asignar al menos un usuario interno a la configuración.
En el inquilino de origen, use el comando New-MgServicePrincipalAppRoleAssignedTo para asignar un usuario interno a la configuración.
$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]}
Paso 11: Probar el aprovisionamiento a petición
Inquilino de origen
Ahora que tiene una configuración, puede probar el aprovisionamiento a petición con uno de los usuarios.
En el inquilino de origen, use el comando Get-MgServicePrincipalSynchronizationJobSchema para obtener el id. de la regla de esquema.
$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 : {}
Inicializar una variable para el id. de regla.
$RuleId = "<RuleId>"
Use el comando New-MgServicePrincipalSynchronizationJobOnDemand para aprovisionar un usuario de prueba a petición.
$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]}
Paso 12: Iniciar el trabajo de aprovisionamiento
Inquilino de origen
Ahora que el trabajo de aprovisionamiento está configurado, en el inquilino de origen, use el comando Start-MgServicePrincipalSynchronizationJob para iniciar el trabajo de aprovisionamiento.
Start-MgServicePrincipalSynchronizationJob -ServicePrincipalId $ServicePrincipalId -SynchronizationJobId $JobId
Paso 13: Supervisar el aprovisionamiento
Inquilino de origen
Ahora que el trabajo de aprovisionamiento está en ejecución, en el inquilino de origen use el comando Get-MgServicePrincipalSynchronizationJob para supervisar el progreso del ciclo de aprovisionamiento actual, así como las estadísticas hasta la fecha, como el número de usuarios y grupos que se han creado en el sistema de destino.
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]}
Además de supervisar el estado del trabajo de aprovisionamiento, use el comando Get-MgAuditLogProvisioning para recuperar los registros de aprovisionamiento y obtener todos los eventos de aprovisionamiento que se hayan producido. Por ejemplo, consulte un usuario determinado y determine si se aprovisionó correctamente.
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 : {}
Sugerencias de solución de problemas
Síntoma: error de privilegios insuficientes
Al intentar realizar una acción, recibe un mensaje de error similar al siguiente:
code: Authorization_RequestDenied
message: Insufficient privileges to complete the operation.
Causa
El usuario que ha iniciado sesión no tiene privilegios suficientes o debe dar su consentimiento a uno de los permisos necesarios.
Solución
Asegúrese de que tiene asignados los roles necesarios. Consulte la sección Requisitos previos de este artículo.
Al iniciar sesión con Connect-MgGraph, asegúrese de especificar los ámbitos necesarios. Consulte Paso 1: iniciar sesión en el inquilino de destino y Paso 4: iniciar sesión en el inquilino de origen anteriormente en este artículo.
Síntoma: error New-MgPolicyCrossTenantAccessPolicyPartner_Create
Al intentar crear una nueva configuración de asociado, recibirá un mensaje de error similar al siguiente:
New-MgPolicyCrossTenantAccessPolicyPartner_Create: Another object with the same value for property tenantId already exists.
Causa
Es probable que esté intentando crear una configuración o un objeto que ya existe, posiblemente a partir de una configuración anterior.
Solución
Compruebe la sintaxis y que esté usando el identificador de inquilino correcto.
Use el comando Get-MgPolicyCrossTenantAccessPolicyPartner para enumerar el objeto existente.
Si tiene un objeto existente, es posible que deba realizar una actualización mediante Update-MgPolicyCrossTenantAccessPolicyPartner
Error Symptom - Request_MultipleObjectsWithSameKeyValue
Al intentar habilitar la sincronización de usuarios, recibirá un mensaje de error similar al siguiente:
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.", ... }}}
Causa
Es probable que esté intentando crear una directiva que ya existe, posiblemente a partir de una configuración anterior.
Solución
Compruebe la sintaxis y que esté usando el identificador de inquilino correcto.
Use el comando Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization para enumerar la configuración
IsSyncAllowed
.(Get-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId).UserSyncInbound
Si tiene una directiva existente, es posible que tenga que actualizar mediante el comando Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization para habilitar la sincronización de usuarios.
$Params = @{ userSyncInbound = @{ isSyncAllowed = $true } } Set-MgPolicyCrossTenantAccessPolicyPartnerIdentitySynchronization -CrossTenantAccessPolicyConfigurationPartnerTenantId $SourceTenantId -BodyParameter $Params