如何使用 MS Graph API 以编程方式配置云同步

以下文档介绍如何只使用 MSGraph API 从头开始复制同步配置文件。
如何复制同步配置文件的结构包括以下步骤。 它们分别是:

请使用这些 Microsoft Graph PowerShell 命令来为生产租户启用同步,这是能够为该租户调用管理 Web 服务的先决条件。

基本设置

启用租户标志

Connect-MgGraph -Scopes "DeviceManagementConfiguration.ReadWrite.All" ('-Environment <AzureEnvironment>')
$organizationId = (Get-MgOrganization).Id
$params = @{
	onPremisesSyncEnabled = $true
}
Update-MgBetaOrganization -OrganizationId $organizationId -BodyParameter $params

此 cmdlet 将为租户启用同步。 它使用 Get-MgOrganization 来获取组织的 ID。

创建服务主体

接下来,我们需要创建 AD2AAD 应用程序/服务主体

需要使用此应用程序 ID 1a4721b3-e57f-4451-ae87-ef078703ec94。 displayName 如果在门户(例如 contoso.com)中使用,则为 AD 域 URL,但它可以被命名为其他内容。

POST https://graph.microsoft.com/beta/applicationTemplates/1a4721b3-e57f-4451-ae87-ef078703ec94/instantiate
Content-type: application/json
{
    displayName: [your app name here]
}

创建同步作业

前面命令的输出会返回已创建的服务主体的 objectId。 对于本示例,该 objectId 为 aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb。 使用 Microsoft Graph 将 synchronizationJob 添加到该服务主体。

可在此处找到有关创建同步作业的文档。

如果未记录该 ID,可运行以下 MS Graph 调用来查找服务主体。 进行该调用需要有 Directory.Read.All 权限:

GET https://graph.microsoft.com/beta/servicePrincipals

然后,在输出中查找你的应用名称。

运行以下两个命令来创建两个作业:一个用于用户/组预配,另一个用于密码哈希同步。 它是两次发出同一请求,但具有不同的模板 ID。

调用以下两个请求:

POST https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs
Content-type: application/json
{
"templateId":"AD2AADProvisioning"
} 
POST https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs
Content-type: application/json
{
"templateId":"AD2AADPasswordHash"
}

如果两个都要创建,则需要两个调用。

示例返回值(用于预配):

HTTP 201/Created
{
    "@odata.context": "https://graph.microsoft.com/beta/$metadata#servicePrincipals('aaaaaaaa-0000-1111-2222-bbbbbbbbbbbbc')/synchronization/jobs/$entity",
    "id": "AD2AADProvisioning.fc96887f36da47508c935c28a0c0b6da",
    "templateId": "ADDCInPassthrough",
    "schedule": {
        "expiration": null,
        "interval": "PT40M",
        "state": "Disabled"
    },
    "status": {
        "countSuccessiveCompleteFailures": 0,
        "escrowsPruned": false,
        "code": "Paused",
        "lastExecution": null,
        "lastSuccessfulExecution": null,
        "lastSuccessfulExecutionWithExports": null,
        "quarantine": null,
        "steadyStateFirstAchievedTime": "0001-01-01T00:00:00Z",
        "steadyStateLastAchievedTime": "0001-01-01T00:00:00Z",
        "troubleshootingUrl": null,
        "progress": [],
        "synchronizedEntryCountByType": []
    }
}

更新目标域

对于此租户,该服务主体的对象标识符和应用程序标识符如下所示:

ObjectId:bbbbbbbb-1111-2222-3333-cccccccccccc AppId:00001111-aaaa-2222-bbbb-3333cccc4444 DisplayName:testApp

我们将需要更新此配置所针对的域,因此,请更新此域的机密。

请确保你使用的域名与你为本地域控制器设置的 URL 相同。

PUT – https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/secrets

根据要尝试执行的操作,在下面的值数组中添加以下键/值对:

  • 将 PHS 和同步租户标志都启用 { key: "AppKey", value: "{"appKeyScenario":"AD2AADPasswordHash"}" }

  • 只启用同步租户标志(不打开 PHS){ key: "AppKey", value: "{"appKeyScenario":"AD2AADProvisioning"}" }

Request body –
{
   "value": [
              {
                "key": "Domain",
                "value": "{\"domain\":\"ad2aadTest.com\"}"
              }
            ]
}

正确的响应为 ... HTTP 204/无内容

在这里,突出显示的“域”值是要从中将条目预配到 Microsoft Entra ID 的本地 Active Directory 域的名称。

启用配置边栏选项卡上的同步密码哈希

本部分介绍如何为某个特定配置启用同步密码哈希。 这种情况不同于启用租户级别功能标志的 AppKey 机密。 此过程仅适用于单个域/配置。需要将应用程序密钥设置为 PHS 密钥,以便让此过程以端到端方式工作。

  1. 获取架构(请注意,架构非常大):

    GET –https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs/ [AD2AADProvisioningJobId]/schema
    
  2. 采用此 CredentialData attribute 映射:

    {
    "defaultValue": null,
    "exportMissingReferences": false,
    "flowBehavior": "FlowWhenChanged",
    "flowType": "Always",
    "matchingPriority": 0,
    "targetAttributeName": "CredentialData",
    "source": {
    "expression": "[PasswordHash]",
    "name": "PasswordHash",
    "type": "Attribute",
    "parameters": []
    }
    
  3. 在架构中查找具有以下名称的对象映射

    • 预配 Active Directory 用户
    • 预配 Active Directory inetOrgPersons

    对象映射位于 schema.synchronizationRules[0].objectMappings 之内(目前你可以假定只有一个同步规则)

  4. 采用步骤 (2) 中的 CredentialData 映射,并将其插入到步骤 (3) 中的对象映射

    你的对象映射会如下所示:

    {
    "enabled": true,
    "flowTypes": "Add,Update,Delete",
    "name": "Provision Active Directory users",
    "sourceObjectName": "user",
    "targetObjectName": "User",
    "attributeMappings": [
    ...
    } 
    

    创建 AD2AADProvisioning and AD2AADPasswordHash 作业步骤中的映射复制/粘贴到 attributeMappings 数组。

    此数组中的元素顺序并不重要(后端将会进行排序)。 如果该名称已存在于数组中(例如,如果 attributeMappings 中已经有具有 targetAttributeName CredentialData 的项),在添加此属性映射时要小心,可能会遇到冲突错误,或者,预先存在的和新的映射可能会合并到一起(通常不是正确结果)。 后端不会为你消除重复数据。

    请记得对用户和 inetOrgpersons 都执行此操作。

  5. 保存创建的架构:

    PUT –
    https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs/ [AD2AADProvisioningJobId]/schema
    

在请求正文中添加该架构。

Exchange 混合写回(公共预览版)

此部分介绍如何以编程方式启用/禁用和使用 Exchange 混合写回

以编程方式启用 Exchange 混合写回需要两个步骤。

  1. 架构验证
  2. 创建 Exchange 混合写回作业

架构验证

在启用和使用 Exchange 混合写回之前,云同步需要确定是否已扩展本地 Active Directory 以包含 Exchange 架构。

可使用 directoryDefinition:discover 来启动架构发现。

POST https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs/[AD2AADProvisioningJobId]/schema/directories/[ADDirectoryID]/discover

正确的响应为 ... HTTP 200/OK

响应应当类似于以下输出:

HTTP/1.1 200 OK
Content-type: application/json
{
  "objects": [
    {
      "name": "user",
      "attributes": [
        {
          "name": "mailNickName",
          "type": "String"
        },
        ...
      ]
    },
    ...
  ]
}

现在检查来查看是否存在 mailNickName 属性。 如果存在,则架构会经过验证并包含 Exchange 属性。 如果没有,请查看 Exchange 混合写回的先决条件

创建 Exchange 混合写回作业

验证架构后,可以创建作业。

POST https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs
Content-type: application/json
{
"templateId":"AAD2ADExchangeHybridWriteback"
}

意外删除

本部分介绍如何以编程方式启用/禁用和使用意外删除

启用并设置阈值

每个作业设置都有两个你可以使用,它们分别是:

  • DeleteThresholdEnabled - 在设置为“true”时,为作业启用意外删除防护。 默认设置为“true”。
  • DeleteThresholdValue - 定义在启用了意外删除防护时每次执行作业所允许的最大删除次数。 在默认情况下,该值设置为 500。 因此,如果将该值设置为 500,则每次执行时允许的最大删除数是 499。

删除阈值设置是 SyncNotificationSettings 的一部分,可以通过图形进行修改。

我们将需要更新此配置所针对的 SyncNotificationSettings,因此,请更新机密。

PUT – https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/secrets

根据要尝试执行的操作,在下面的值数组中添加以下键/值对:

Request body -
{
  "value":[
    {
      "key":"SyncNotificationSettings",
      "value": "{\"Enabled\":true,\"Recipients\":\"foobar@xyz.com\",\"DeleteThresholdEnabled\":true,\"DeleteThresholdValue\":50}"
     }
  ]
}

该示例中的“已启用”设置用于在隔离作业时启用/禁用通知电子邮件。

目前,我们不支持机密的 PATCH 请求,因此需要在 PUT 请求的正文中添加所有值(如该示例中所示),以便保留其他值。

可以通过使用以下命令来检索所有机密的现有值:

GET https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/secrets 

允许删除

若要在作业进入隔离后允许这些删除流过,则需要发出只以“ForceDeletes”作为范围的重启。

Request:
POST https://graph.microsoft.com/beta/servicePrincipals/{id}/synchronization/jobs/{jobId}/restart
Request Body:
{
  "criteria": {"resetScope": "ForceDeletes"}
}

启动同步作业

可通过以下命令再次检索这些作业:

GET https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs/

可在此处找到有关检索作业的文档。

若要启动作业,请使用在第一步中创建的服务主体的 objectId 以及从创建作业的请求返回的作业标识符来发出此请求。

可在此处找到有关如何启动作业的文档。

POST  https://graph.microsoft.com/beta/servicePrincipals/8895955e-2e6c-4d79-8943-4d72ca36878f/synchronization/jobs/AD2AADProvisioning.fc96887f36da47508c935c28a0c0b6da/start

正确的响应为 ... HTTP 204/无内容。

此处还介绍了其他用于控制作业的命令。

若要重新启动作业,请使用:

POST  https://graph.microsoft.com/beta/servicePrincipals/8895955e-2e6c-4d79-8943-4d72ca36878f/synchronization/jobs/AD2AADProvisioning.fc96887f36da47508c935c28a0c0b6da/restart
{
  "criteria": {
    "resetScope": "Full"
  }
}

查看状态

请通过以下命令检索作业状态:

GET https://graph.microsoft.com/beta/servicePrincipals/[SERVICE_PRINCIPAL_ID]/synchronization/jobs/ 

请在返回对象的“状态”部分下查找相关详细信息

后续步骤