管理应用程序的现有用户 - Microsoft PowerShell

三种常见情况下,在将应用程序与 Microsoft Entra ID 治理功能(如访问评审)配合使用之前,需要用应用程序的现有用户填充 Microsoft Entra ID。

许可要求

使用此功能需要 Microsoft Entra ID Governance 许可证。 如需查找符合要求的许可证,请参阅《Microsoft Entra ID 治理许可基础知识》。

使用自己的标识提供程序后,应用程序已迁移到 Microsoft Entra ID

在第一种方案中,应用程序已存在于环境中。 应用程序以前使用自己的标识提供者或数据存储来跟踪哪些用户有权访问。

将应用程序更改为依赖于 Microsoft Entra ID 时,只有 Microsoft Entra ID 中并且允许访问该应用程序的用户才能访问它。 在配置更改过程中,可以选择将现有用户从该应用程序的数据存储引入 Microsoft Entra ID 中。 这些用户随后可以通过 Microsoft Entra ID 继续访问。

具有与 Microsoft Entra ID 中表示的应用程序关联的用户将使 Microsoft Entra ID 能够跟踪有权访问应用程序的用户,即使用户与应用程序的关系源自于其他位置。 例如,关系可能源自应用程序的数据库或目录。

Microsoft Entra ID 知道用户的分配后,它可以将更新发送到应用程序的数据存储。 更新包括该用户的属性的更改时间或是用户超出应用程序范围的时间。

不使用 Microsoft Entra ID 作为唯一标识提供者的应用程序

在第二种方案中,应用程序不只依赖 Microsoft Entra ID 作为其标识提供者。

在某些情况下,应用程序可能依赖于 AD 组。 在准备对用户对应用程序的访问权限进行访问评审的模式 B 中描述了这种情况。 你不需要按照该文中的描述为该应用程序配置预配,只需按照该文中有关如何评审 AD 组成员资格的模式 B 的说明进行操作即可。

在其他情况下,应用程序可能支持多个标识提供者,或者有其自己的内置凭据存储。 此方案在准备对用户对应用程序的访问权限进行访问评审中描述为模式 C。

可能无法从应用程序中移除其他标识提供者或本地凭据身份验证。 这种情况下,如果要使用 Microsoft Entra ID 评审谁有权访问该应用程序,或者从该应用程序中移除某人的访问权限,则需要在 Microsoft Entra ID 中创建表示应用程序用户的分配,这些用户不依赖 Microsoft Entra ID 进行身份验证。

如果计划评审有权访问应用程序的所有用户(作为访问评审的一部分),则需要使用这些分配。

例如,假设用户处于应用程序的数据存储中。 Microsoft Entra ID 配置为要求向应用程序进行角色分配。 但是,用户在 Microsoft Entra ID 中没有应用程序角色分配。

如果用户在 Microsoft Entra ID 中更新,则不会向应用程序发送任何更改。 如果审查了应用程序的角色分配,则不用审查用户。 若要让所有用户接受评审,则必须为应用程序的所有用户分配应用程序角色。

应用程序不使用 Microsoft Entra ID 作为其标识提供者,也不支持预配

对于某些旧版应用程序,可能无法从应用程序中删除其他标识提供者或本地凭据身份验证,或者无法启用对这些应用程序的预配协议的支持。

不支持预配协议的应用程序的该场景在另一篇文章(即治理不支持预配的应用程序的现有用户)中进行了介绍。

术语

本文演示了使用 Microsoft Graph PowerShell cmdlet 管理应用程序角色分配的过程。 它使用以下 Microsoft Graph 术语。

说明 Microsoft Graph 术语的图。

在 Microsoft Entra ID 中,服务主体 (ServicePrincipal) 表示特定组织目录中的应用程序。 ServicePrincipal 具有名为 AppRoles 的属性,该属性会列出应用程序支持的角色,例如 Marketing specialistAppRoleAssignment 将用户链接到服务主体,并指定用户在该应用程序中具有的角色。 如果应用程序单一登录和应用程序预配是分开处理的,则应用程序可能有多个服务主体。

还可以使用 Microsoft Entra 权利管理访问包为用户提供对应用程序的有限访问权限。 在权利管理中,AccessPackage 包含一个或多个资源角色(可能来自多个服务主体)。 AccessPackage 还使用户具有访问包分配 (Assignment)。

为用户创建访问包的分配时,Microsoft Entra ID 权利管理会自动为用户创建访问包中每个应用程序的服务主体的必要 AppRoleAssignment 实例。 有关详细信息,请参阅 Microsoft Entra ID 权利管理中的资源访问管理 教程,了解如何通过 PowerShell 创建访问包。

开始之前

  • 租户必须具有以下许可证之一:

    • Microsoft Entra ID P2 或 Microsoft Entra ID 治理
    • 企业移动性 + 安全性 E5 许可证
  • 需要具有合适的管理角色。 如果这是你第一次执行这些步骤,则需要全局管理员角色来授权在租户中使用 Microsoft Graph PowerShell。

  • 应用程序在租户中至少需要一个服务主体:

从应用程序收集现有用户

确保所有用户都记录在 Microsoft Entra ID 中的第一步是收集有权访问应用程序的现有用户的列表。

某些应用程序可能具有从其数据存储中导出当前用户列表的内置命令。 在其他情况下,应用程序可能依赖于外部目录或数据库。

在某些环境中,应用程序可能位于不适用于管理对 Microsoft Entra ID 的访问权限的网络段或系统上。 因此可能需要从该目录或数据库提取用户列表,然后将其作为文件传输到可用于 Microsoft Entra 交互的另一个系统。

本部分介绍了四种获取逗号分隔值 (CSV) 文件的用户列表的方法:

  • 从 LDAP 目录
  • 从 Microsoft SQL Server 数据库
  • 从另一个基于 SQL 的数据库
  • 从 SAP 云标识服务

从使用 LDAP 目录的应用程序收集现有用户

本部分适用于将 LDAP 目录用作基础数据存储的应用程序,这些数据存储适用于未向 Microsoft Entra ID 进行身份验证的用户。 许多 LDAP 目录(如 Active Directory)都包含输出用户列表的命令。

  1. 确定该目录中哪些用户属于应用程序用户。 此选项将取决于应用程序的配置。 对于某些应用程序,LDAP 目录中存在的任何用户都是有效的用户。 其他应用程序可能要求用户具有特定属性或者是该目录中的组成员。

  2. 运行从目录中检索该用户子集的命令。 确保输出包含将用于与 Microsoft Entra ID 匹配的用户的属性。 这些属性的示例包括员工 ID、帐户名称和电子邮件地址。

    例如,此命令将在当前文件系统目录中生成 CSV 文件,其中包含 LDAP 目录中每个人的属性 userPrincipalName

    $out_filename = ".\users.csv"
    csvde -f $out_filename -l userPrincipalName,cn -r "(objectclass=person)"
    
  3. 如果需要,请将包含用户列表的 CSV 文件传输到安装了 Microsoft Graph PowerShell cmdlet 的系统。

  4. 继续阅读本文后面的确认 Microsoft Entra ID 具有与应用程序用户匹配的用户部分。

使用 Microsoft SQL Server 向导从应用程序的数据库表中收集现有用户

本部分适用于使用 Microsoft SQL Server 作为其基础数据存储的应用程序。

首先,从表中获取用户列表。 大多数数据库提供了将表的内容导出到标准文件格式的方法,例如 CSV 文件。 如果应用程序使用 Microsoft SQL Server 数据库,可以使用 Microsoft SQL Server 导入和导出向导导出数据库部分。 如果没有数据库的实用工具,可以将 ODBC 驱动程序与 PowerShell 配合使用,如下一部分所述。

  1. 登录到安装了 Microsoft SQL Server 的系统。
  2. 打开 Microsoft SQL Server 2019 导入和导出(64 位)或数据库的等效项。
  3. 选择现有数据库作为源。
  4. 选择平面文件目标作为目标。 提供文件名,并将“代码页”值更改为 65001 (UTF-8)。
  5. 完成向导,然后选择立即运行的选项。
  6. 等待执行完成。
  7. 如果需要,请将包含用户列表的 CSV 文件传输到安装了 Microsoft Graph PowerShell cmdlet 的系统。
  8. 继续阅读本文后面的确认 Microsoft Entra ID 具有与应用程序用户匹配的用户部分。

使用 PowerShell 从应用程序的数据库表中收集现有用户

本部分适用于使用另一个 SQL 数据库作为基础数据存储的应用程序,其中可使用 ECMA 连接器主机将用户预配到该应用程序。 如果尚未配置预配代理,请使用该指南创建将在本节中使用的 DSN 连接文件。

  1. 登录到预配代理所在或将安装的系统。

  2. 打开 PowerShell。

  3. 构造连接字符串以连接数据库系统。

    连接字符串的组件将取决于数据库的要求。 如果使用 Microsoft SQL Server,请参阅 DSN 和连接字符串关键字和属性的列表

    如果使用其他数据库,则需要包含连接到该数据库的必需关键字。 例如,如果数据库使用 DSN 文件的完全限定路径名、用户 ID 和密码,则使用以下命令构造连接字符串:

    $filedsn = "c:\users\administrator\documents\db.dsn"
    $db_cs = "filedsn=" + $filedsn + ";uid=p;pwd=secret"
    
  4. 使用以下命令打开与数据库的连接,并提供连接字符串:

    $db_conn = New-Object data.odbc.OdbcConnection
    $db_conn.ConnectionString = $db_cs
    $db_conn.Open()
    
  5. 构造 SQL 查询以从数据库表检索用户。 请务必包含将用于将应用程序数据库中的用户与 Microsoft Entra ID 中的用户匹配的列。 列可能包括员工 ID、帐户名称或电子邮件地址。

    例如,如果用户保存在名为 USERS 和具有列 nameemail 的数据库表中,则输入以下命令:

    $db_query = "SELECT name,email from USERS"
    
    
  6. 通过连接将查询发送到数据库:

    $result = (new-object data.odbc.OdbcCommand($db_query,$db_conn)).ExecuteReader()
    $table = new-object System.Data.DataTable
    $table.Load($result)
    

    结果可获得表示从查询检索到的用户的行列表。

  7. 将结果写入 CSV 文件:

    $out_filename = ".\users.csv"
    $table.Rows | Export-Csv -Path $out_filename -NoTypeInformation -Encoding UTF8
    
  8. 如果此系统未安装 Microsoft Graph PowerShell cmdlet,或未连接到 Microsoft Entra ID,则将包含用户列表的 CSV 文件传输到安装了 Microsoft Graph PowerShell cmdlet 的系统。

从 SAP 云标识服务收集现有用户

本部分适用于将 SAP 云标识服务用作用户预配的基础服务的 SAP 应用程序。

  1. 登录到 SAP 云标识服务管理控制台 https://<tenantID>.accounts.ondemand.com/admin(如果是试用,则 https://<tenantID>.trial-accounts.ondemand.com/admin)。
  2. 导航到“用户和授权 > 导出用户”。
  3. 选择将 Microsoft Entra 用户与 SAP 中的用户匹配所需的所有特性。 这包括你的 SAP 系统中可能正在使用的 SCIM IDuserNameemails 以及其他特性。
  4. 选择“导出”并等待浏览器下载 CSV 文件。
  5. 如果此系统未安装 Microsoft Graph PowerShell cmdlet,或未连接到 Microsoft Entra ID,则将包含用户列表的 CSV 文件传输到安装了 Microsoft Graph PowerShell cmdlet 的系统。

确认 Microsoft Entra ID 具有与应用程序用户匹配的用户

现在,你已获得从应用程序获取的所有用户的列表,会将应用程序数据存储中的这些用户与 Microsoft Entra ID 中的用户匹配。

在继续操作之前,请查看有关匹配源系统和目标系统中的用户的信息。 稍后将使用等效映射配置 Microsoft Entra 预配。 此步骤允许 Microsoft Entra 预配使用相同的匹配规则查询应用程序的数据存储。

检索 Microsoft Entra ID 中用户的 ID

本部分介绍如何使用 Microsoft Graph PowerShell cmdlet 与 Microsoft Entra ID 交互。

组织首次将这些 cmdlet 用于此方案时,需要具有全局管理员角色才能允许将 Microsoft Graph PowerShell 用于租户。 后续交互可以使用较低特权角色,例如:

  • 用户管理员(如果预计会创建新用户)。
  • 应用程序管理员或标识治理管理员(如果只是管理应用程序角色分配)。
  1. 打开 PowerShell。

  2. 如果尚未安装 Microsoft Graph PowerShell 模块,请使用以下命令安装 Microsoft.Graph.Users 模块和其他模块:

    Install-Module Microsoft.Graph
    

    如果已安装模块,请确保使用的是最新版本:

    Update-Module microsoft.graph.users,microsoft.graph.identity.governance,microsoft.graph.applications
    
  3. 连接到 Microsoft Entra ID:

    $msg = Connect-MgGraph -ContextScope Process -Scopes "User.ReadWrite.All,Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All,EntitlementManagement.ReadWrite.All"
    
  4. 如果这是你第一次使用此命令,则可能需要同意允许 Microsoft Graph 命令行工具具有这些权限。

  5. 将从应用程序数据存储中获取的用户列表读取到 PowerShell 会话中。 如果用户列表位于 CSV 文件中,则可以使用 PowerShell cmdlet Import-Csv,并将上一部分中的文件的名称作为参数提供。

    例如,如果将从 SAP 云标识服务获取的文件命名为 Users-exported-from-sap.csv 并位于当前目录中,则输入此命令。

    $filename = ".\Users-exported-from-sap.csv"
    $dbusers = Import-Csv -Path $filename -Encoding UTF8
    

    另举一例,如果使用了数据库或目录,并将该文件命名为 users.csv 且位于当前目录中,则输入以下命令:

    $filename = ".\users.csv"
    $dbusers = Import-Csv -Path $filename -Encoding UTF8
    
  6. 选择与 Microsoft Entra ID 用户属性匹配的 users.csv 文件的列。

    如果使用 SAP 云标识服务,则默认映射是 SAP SCIM 属性 userName 与 Microsoft Entra ID 属性 userPrincipalName

    $db_match_column_name = "userName"
    $azuread_match_attr_name = "userPrincipalName"
    

    另举一例,如果使用了数据库或目录,则在你拥有用户的数据库中,名为 EMail 的列中的值将与 Microsoft Entra 属性 userPrincipalName 中的值相同:

    $db_match_column_name = "EMail"
    $azuread_match_attr_name = "userPrincipalName"
    
  7. 检索 Microsoft Entra ID 中的这些用户的 ID。

    以下 PowerShell 脚本使用前面指定的 $dbusers$db_match_column_name$azuread_match_attr_name 值。 它会查询 Microsoft Entra ID 以查找属性具有源文件中每个记录的匹配值的用户。 如果从源 SAP 云标识服务、数据库或目录获取的文件中存在许多用户,则可能需要几分钟时间才能完成此脚本。 如果在 Microsoft Entra ID 中没有具有该值的属性,并且需要使用 contains 或其他筛选表达式,则需要在下面的步骤 11 中自定义此脚本和该内容,以使用其他筛选表达式。

    $dbu_not_queried_list = @()
    $dbu_not_matched_list = @()
    $dbu_match_ambiguous_list = @()
    $dbu_query_failed_list = @()
    $azuread_match_id_list = @()
    $azuread_not_enabled_list = @()
    $dbu_values = @()
    $dbu_duplicate_list = @()
    
    foreach ($dbu in $dbusers) { 
       if ($null -ne $dbu.$db_match_column_name -and $dbu.$db_match_column_name.Length -gt 0) { 
          $val = $dbu.$db_match_column_name
          $escval = $val -replace "'","''"
          if ($dbu_values -contains $escval) { $dbu_duplicate_list += $dbu; continue } else { $dbu_values += $escval }
          $filter = $azuread_match_attr_name + " eq '" + $escval + "'"
          try {
             $ul = @(Get-MgUser -Filter $filter -All -Property Id,accountEnabled -ErrorAction Stop)
             if ($ul.length -eq 0) { $dbu_not_matched_list += $dbu; } elseif ($ul.length -gt 1) {$dbu_match_ambiguous_list += $dbu } else {
                $id = $ul[0].id; 
                $azuread_match_id_list += $id;
                if ($ul[0].accountEnabled -eq $false) {$azuread_not_enabled_list += $id }
             } 
          } catch { $dbu_query_failed_list += $dbu } 
        } else { $dbu_not_queried_list += $dbu }
    }
    
    
  8. 查看以前查询的结果。 请查看 SAP 云标识服务、数据库或目录中是否存在任何用户由于错误或缺少匹配项而无法在 Microsoft Entra ID 中找到。

    以下 PowerShell 脚本将显示未找到的记录计数:

    $dbu_not_queried_count = $dbu_not_queried_list.Count
    if ($dbu_not_queried_count -ne 0) {
      Write-Error "Unable to query for $dbu_not_queried_count records as rows lacked values for $db_match_column_name."
    }
    $dbu_duplicate_count = $dbu_duplicate_list.Count
    if ($dbu_duplicate_count -ne 0) {
      Write-Error "Unable to locate Microsoft Entra ID users for $dbu_duplicate_count rows as multiple rows have the same value"
    }
    $dbu_not_matched_count = $dbu_not_matched_list.Count
    if ($dbu_not_matched_count -ne 0) {
      Write-Error "Unable to locate $dbu_not_matched_count records in Microsoft Entra ID by querying for $db_match_column_name values in $azuread_match_attr_name."
    }
    $dbu_match_ambiguous_count = $dbu_match_ambiguous_list.Count
    if ($dbu_match_ambiguous_count -ne 0) {
      Write-Error "Unable to locate $dbu_match_ambiguous_count records in Microsoft Entra ID as attribute match ambiguous."
    }
    $dbu_query_failed_count = $dbu_query_failed_list.Count
    if ($dbu_query_failed_count -ne 0) {
      Write-Error "Unable to locate $dbu_query_failed_count records in Microsoft Entra ID as queries returned errors."
    }
    $azuread_not_enabled_count = $azuread_not_enabled_list.Count
    if ($azuread_not_enabled_count -ne 0) {
     Write-Error "$azuread_not_enabled_count users in Microsoft Entra ID are blocked from sign-in."
    }
    if ($dbu_not_queried_count -ne 0 -or $dbu_duplicate_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0 -or $azuread_not_enabled_count) {
     Write-Output "You will need to resolve those issues before access of all existing users can be reviewed."
    }
    $azuread_match_count = $azuread_match_id_list.Count
    Write-Output "Users corresponding to $azuread_match_count records were located in Microsoft Entra ID." 
    
  9. 脚本完成以后,如果数据源中有任何记录在 Microsoft Entra ID 中无法找到,系统会提示错误。 如果并非应用程序数据存储中用户的所有记录都可以在 Microsoft Entra ID 中作为用户找到,则需要调查哪些记录不匹配以及原因。

    例如,某人在 Microsoft Entra ID 中的电子邮件地址和 userPrincipalName 可能已更改,但在应用程序的数据源中未更新其相应的 mail 属性。 或者,用户可能已经离开了组织,但仍处于应用程序的数据源中。 或者,应用程序数据源中可能有一个供应商或超级管理员帐户,该帐户与 Microsoft Entra ID 中的任何特定人员都不对应。

  10. 如果存在无法在 Microsoft Entra ID 中找到的用户,或有用户未处于活动状态并且能够登录,但你想要审查其权限或在 SAP 云标识服务、数据库或目录中更新其属性,则需要更新应用程序、匹配规则,或为其更新或创建 Microsoft Entra 用户。 有关要进行的更改的详细信息,请参阅管理应用程序中与 Microsoft Entra ID 中用户不匹配的映射和用户帐户

    如果选择用于在 Microsoft Entra ID 中创建用户的选项,则可以使用以下任一方法批量创建用户:

    确保使用 Microsoft Entra ID 所需的属性填充这些新用户,以便稍后将其与应用程序中的现有用户以及 Microsoft Entra ID 所需的属性(包括 userPrincipalNamemailNicknamedisplayName)匹配。 userPrincipalName 对于目录中的所有用户必须是唯一的。

    例如,数据库中可能有用户,其中,EMail 列中的值是要用作 Microsoft Entra 用户主体名称的值,Alias 列中的值包含 Microsoft Entra ID 邮件别名,Full name 列中的值包含用户的显示名称:

    $db_display_name_column_name = "Full name"
    $db_user_principal_name_column_name = "Email"
    $db_mail_nickname_column_name = "Alias"
    

    然后,可以使用此脚本为 SAP 云标识服务、数据库或目录中与 Microsoft Entra ID 用户不匹配的用户创建 Microsoft Entra 用户。 请注意,可能需要修改此脚本以添加组织中所需的其他 Microsoft Entra 属性,或者如果 $azuread_match_attr_name 既不是 mailNickname 也不是 userPrincipalName,则提供该 Microsoft Entra 属性。

    $dbu_missing_columns_list = @()
    $dbu_creation_failed_list = @()
    foreach ($dbu in $dbu_not_matched_list) {
       if (($null -ne $dbu.$db_display_name_column_name -and $dbu.$db_display_name_column_name.Length -gt 0) -and
           ($null -ne $dbu.$db_user_principal_name_column_name -and $dbu.$db_user_principal_name_column_name.Length -gt 0) -and
           ($null -ne $dbu.$db_mail_nickname_column_name -and $dbu.$db_mail_nickname_column_name.Length -gt 0)) {
          $params = @{
             accountEnabled = $false
             displayName = $dbu.$db_display_name_column_name
             mailNickname = $dbu.$db_mail_nickname_column_name
             userPrincipalName = $dbu.$db_user_principal_name_column_name
             passwordProfile = @{
               Password = -join (((48..90) + (96..122)) * 16 | Get-Random -Count 16 | % {[char]$_})
             }
          }
          try {
            New-MgUser -BodyParameter $params
          } catch { $dbu_creation_failed_list += $dbu; throw }
       } else {
          $dbu_missing_columns_list += $dbu
       }
    }
    
  11. 将任何缺失的用户添加到 Microsoft Entra ID 后,再次运行步骤 7 中的脚本。 然后运行步骤 8 中的脚本。 检查是否未报告任何错误。

    $dbu_not_queried_list = @()
    $dbu_not_matched_list = @()
    $dbu_match_ambiguous_list = @()
    $dbu_query_failed_list = @()
    $azuread_match_id_list = @()
    $azuread_not_enabled_list = @()
    $dbu_values = @()
    $dbu_duplicate_list = @()
    
    foreach ($dbu in $dbusers) { 
       if ($null -ne $dbu.$db_match_column_name -and $dbu.$db_match_column_name.Length -gt 0) { 
          $val = $dbu.$db_match_column_name
          $escval = $val -replace "'","''"
          if ($dbu_values -contains $escval) { $dbu_duplicate_list += $dbu; continue } else { $dbu_values += $escval }
          $filter = $azuread_match_attr_name + " eq '" + $escval + "'"
          try {
             $ul = @(Get-MgUser -Filter $filter -All -Property Id,accountEnabled -ErrorAction Stop)
             if ($ul.length -eq 0) { $dbu_not_matched_list += $dbu; } elseif ($ul.length -gt 1) {$dbu_match_ambiguous_list += $dbu } else {
                $id = $ul[0].id; 
                $azuread_match_id_list += $id;
                if ($ul[0].accountEnabled -eq $false) {$azuread_not_enabled_list += $id }
             } 
          } catch { $dbu_query_failed_list += $dbu } 
        } else { $dbu_not_queried_list += $dbu }
    }
    
    $dbu_not_queried_count = $dbu_not_queried_list.Count
    if ($dbu_not_queried_count -ne 0) {
      Write-Error "Unable to query for $dbu_not_queried_count records as rows lacked values for $db_match_column_name."
    }
    $dbu_duplicate_count = $dbu_duplicate_list.Count
    if ($dbu_duplicate_count -ne 0) {
      Write-Error "Unable to locate Microsoft Entra ID users for $dbu_duplicate_count rows as multiple rows have the same value"
    }
    $dbu_not_matched_count = $dbu_not_matched_list.Count
    if ($dbu_not_matched_count -ne 0) {
      Write-Error "Unable to locate $dbu_not_matched_count records in Microsoft Entra ID by querying for $db_match_column_name values in $azuread_match_attr_name."
    }
    $dbu_match_ambiguous_count = $dbu_match_ambiguous_list.Count
    if ($dbu_match_ambiguous_count -ne 0) {
      Write-Error "Unable to locate $dbu_match_ambiguous_count records in Microsoft Entra ID as attribute match ambiguous."
    }
    $dbu_query_failed_count = $dbu_query_failed_list.Count
    if ($dbu_query_failed_count -ne 0) {
      Write-Error "Unable to locate $dbu_query_failed_count records in Microsoft Entra ID as queries returned errors."
    }
    $azuread_not_enabled_count = $azuread_not_enabled_list.Count
    if ($azuread_not_enabled_count -ne 0) {
     Write-Warning "$azuread_not_enabled_count users in Microsoft Entra ID are blocked from sign-in."
    }
    if ($dbu_not_queried_count -ne 0 -or $dbu_duplicate_count -ne 0 -or $dbu_not_matched_count -ne 0 -or $dbu_match_ambiguous_count -ne 0 -or $dbu_query_failed_count -ne 0 -or $azuread_not_enabled_count -ne 0) {
     Write-Output "You will need to resolve those issues before access of all existing users can be reviewed."
    }
    $azuread_match_count = $azuread_match_id_list.Count
    Write-Output "Users corresponding to $azuread_match_count records were located in Microsoft Entra ID." 
    

注册应用程序

如果应用程序已在 Microsoft Entra ID 中注册,则继续执行下一步。

检查尚未分配给应用程序的用户

前面的步骤已确认应用程序数据存储中的所有用户都作为 Microsoft Entra ID 中的用户存在。 但是,它们可能并未在当前全部都分配给 Microsoft Entra ID 中的应用程序角色。 因此,后续步骤是查看哪些用户没有分配应用程序角色。

  1. 查找应用程序服务主体的服务主体 ID。 如果最近为使用 LDAP 目录或 SQL 数据库的应用程序创建了服务主体,请使用该服务主体的名称。

    例如,如果企业应用程序命名为 CORPDB1,请输入以下命令:

    $azuread_app_name = "CORPDB1"
    $azuread_sp_filter = "displayName eq '" + ($azuread_app_name -replace "'","''") + "'"
    $azuread_sp = Get-MgServicePrincipal -Filter $azuread_sp_filter -All
    
  2. 检索当前已分配到 Microsoft Entra ID 中应用程序的用户。

    这建立在上一命令中设置的 $azuread_sp 变量的基础上。

    $azuread_existing_assignments = @(Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $azuread_sp.Id -All)
    
  3. 将上一部分的用户 ID 列表与当前分配给应用程序的用户进行比较:

    $azuread_not_in_role_list = @()
    foreach ($id in $azuread_match_id_list) {
       $found = $false
       foreach ($existing in $azuread_existing_assignments) {
          if ($existing.principalId -eq $id) {
             $found = $true; break;
          }
       }
       if ($found -eq $false) { $azuread_not_in_role_list += $id }
    }
    $azuread_not_in_role_count = $azuread_not_in_role_list.Count
    Write-Output "$azuread_not_in_role_count users in the application's data store are not assigned to the application roles."
    

    如果没有用户未分配到应用程序角色,这表明所有用户都分配到应用程序角色,则在执行访问评审之前无需任何进一步更改。

    但是,如果当前未将一个或多个用户分配到应用程序角色,则需要继续执行该过程,将它们添加到应用程序角色之一。

  4. 选择要向其分配剩余用户的应用程序角色。

    应用程序可能有多个角色,服务主体可能有其他角色。 使用此命令列出服务主体的可用角色:

    $azuread_sp.AppRoles | where-object {$_.AllowedMemberTypes -contains "User"} | ft DisplayName,Id
    

    从列表中选择相应的角色,并获取其角色 ID。 例如,如果角色名称为 Admin,请在以下 PowerShell 命令中提供该值:

    $azuread_app_role_name = "Admin"
    $azuread_app_role_id = ($azuread_sp.AppRoles | where-object {$_.AllowedMemberTypes -contains "User" -and $_.DisplayName -eq $azuread_app_role_name}).Id
    if ($null -eq $azuread_app_role_id) { write-error "role $azuread_app_role_name not located in application manifest"}
    

配置应用程序预配

如果你的应用程序使用 LDAP 目录、SQL 数据库、SAP 云标识服务或支持 SCIM,则请在创建新分配之前,为应用程序配置 Microsoft Entra 用户预配。 在创建分配之前配置预配将使 Microsoft Entra ID 能够将 Microsoft Entra ID 中的用户与应用程序数据存储中已有用户的应用程序角色分配相匹配。 如果应用程序有一个要预配的本地目录或数据库,并且还支持联合 SSO,那么你可能需要两个服务主体来表示目录中的应用程序:一个用于预配,一个用于 SSO。 如果应用程序不支持预配,请继续阅读下一部分。

  1. 确保应用程序配置为要求用户分配应用程序角色,以便仅将选定的用户预配到应用程序。

  2. 如果尚未为应用程序配置预配,则立即进行配置(但不启动预配):

  3. 检查应用程序的“属性”选项卡。 验证“需要进行用户分配?”选项是否设置为“”。 如果设置为“否”,则目录中的所有用户(包括外部标识)都可以访问应用程序,并且无法评审对应用程序的访问。

  4. 检查要预配到该应用程序的属性映射。 请确保为上述部分中用于匹配的 Microsoft Entra 属性和列设置了“使用此属性匹配对象”。

    如果这些规则未使用前面使用的相同属性,则在创建应用程序角色分配时,Microsoft Entra ID 可能无法在应用程序的数据存储中找到现有用户。 Microsoft Entra ID 随后可能会无意中创建重复用户。

  5. 检查是否存在 isSoftDeleted 到应用程序属性的属性映射。

    当用户从应用程序取消分配、在 Microsoft Entra ID 中被软删除或被阻止登录时,Microsoft Entra 预配将更新映射到 isSoftDeleted 的属性。 如果未映射任何属性,则以后从应用程序角色取消分配的用户将继续存在于应用程序的数据存储中。

  6. 如果已为应用程序启用预配,请检查应用程序预配是否未处于隔离状态。 在继续之前解决导致隔离的所有问题。

在 Microsoft Entra ID 中创建应用角色分配

若要 Microsoft Entra ID 将应用程序中的用户与 Microsoft Entra ID 中的用户匹配,需要在 Microsoft Entra ID 中创建应用程序角色分配。 每个应用程序角色分配都会将一个用户关联到一个服务主体的一个应用程序角色。

如果在 Microsoft Entra ID 中为用户创建应用程序角色分配(分配到应用程序),且该应用程序支持预配,则:

  • Microsoft Entra ID 将通过 SCIM 或者其目录或数据库来查询应用程序,以确定用户是否已存在。
  • 对 Microsoft Entra ID 中的用户特性进行后续更新时,Microsoft Entra ID 会将这些更新发送到应用程序。
  • 除非在 Microsoft Entra ID 外部更新,或者直到移除 Microsoft Entra ID 中的分配,否则用户将无限期保留在应用程序中。
  • 在该应用程序的角色分配的下一次访问评审时,该用户将被包含在访问评审内。
  • 如果用户在访问评审中被拒绝,将移除其应用程序角色分配。 Microsoft Entra ID 将通知应用程序用户被阻止登录。

如果应用程序不支持预配,则:

  • 除非在 Microsoft Entra ID 外部更新,或者直到移除 Microsoft Entra ID 中的分配,否则用户将无限期保留在应用程序中。
  • 在下一次评审该应用程序的角色分配时,用户将参加评审。
  • 如果用户在访问评审中被拒绝,将移除其应用程序角色分配。 用户将无法再从 Microsoft Entra ID 登录到应用程序。
  1. 为当前没有角色分配的用户创建应用程序角色分配:

    foreach ($u in $azuread_not_in_role_list) {
       $res = New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $azuread_sp.Id -AppRoleId $azuread_app_role_id -PrincipalId $u -ResourceId $azuread_sp.Id 
    }
    
  2. 等待一分钟,以便在 Microsoft Entra ID 中传播更改。

检查 Microsoft Entra 预配是否与现有用户匹配

  1. 查询 Microsoft Entra ID 以获取更新的角色分配列表:

    $azuread_existing_assignments = @(Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $azuread_sp.Id -All)
    
  2. 将上一部分的用户 ID 列表与当前分配给应用程序的用户进行比较:

    $azuread_still_not_in_role_list = @()
    foreach ($id in $azuread_match_id_list) {
       $found = $false
       foreach ($existing in $azuread_existing_assignments) {
          if ($existing.principalId -eq $id) {
             $found = $true; break;
          }
       }
       if ($found -eq $false) { $azuread_still_not_in_role_list += $id }
    }
    $azuread_still_not_in_role_count = $azuread_still_not_in_role_list.Count
    if ($azuread_still_not_in_role_count -gt 0) {
       Write-Output "$azuread_still_not_in_role_count users in the application's data store are not assigned to the application roles."
    }
    

    如果未将任何用户分配到应用程序角色,请检查 Microsoft Entra 审核日志中是否存在上一步中发生的错误。

  3. 如果应用程序服务主体为预配进行了配置,但服务主体的“预配状态”为“关”,请将其设置为“开”。 还可以使用图形 API 开始预配。

  4. 根据用户预配时间指南,等待 Microsoft Entra 预配将应用程序的现有用户与刚刚分配的用户匹配。

  5. 通过门户或图形 API 监视预配状态,以确保所有用户都成功匹配。

    如果未看到正在预配的用户,请查看有关未预配任何用户的故障排除指南。 如果在预配状态中看到错误,并且正在预配到本地应用程序,请查看本地应用程序预配的故障排除指南

  6. 通过 Microsoft Entra 管理中心Graph API 检查预配日志。 按状态“失败”筛选日志。 如果发生失败并且 ErrorCode 为 DuplicateTargetEntries,则这表示预配匹配规则中存在歧义,需要更新用于匹配的 Microsoft Entra 用户或映射,以确保每个 Microsoft Entra 用户都与一个应用程序用户匹配。 然后按操作“创建”和状态“已跳过”来筛选日志。 如果跳过的用户的 SkipReason 代码为 NotEffectivelyEntitled,则这可能表明 Microsoft Entra ID 中的用户帐户由于用户帐户状态为“已禁用”而不匹配。

Microsoft Entra ID 预配服务基于创建的应用程序角色分配与用户匹配之后,对这些用户的后续更改将发送到应用程序。

选择适当的审阅者

创建每个访问评审时,管理员可以选择一个或多个审阅者。 审阅者都可以通过选择继续访问资源的用户或将其删除来执行评审。

通常,资源所有者负责执行评审。 如果要创建组评审,作为评审模式 B 中集成的应用程序的访问权限的一部分,则可以选择组所有者作为审阅者。 因为 Microsoft Entra ID 中的应用程序不一定具有所有者,因此无法选择应用程序所有者作为审阅者。 相反,在创建评审时,可以提供应用程序所有者的名称作为审阅者。

在创建组或应用程序的评审时,还可以选择进行多阶段评审。 例如,可以选择让每个分配的用户的经理执行评审的第一个阶段,让资源所有者执行第二阶段。 这样,资源所有者就可以专注于已获得其经理批准的用户。

在创建评审之前,请检查租户中是否有足够的 Microsoft Entra ID P2 或 Microsoft Entra ID Governance SKU 席位。 此外,请检查所有审阅者是否都是具有电子邮件地址的活动用户。 访问评审开始后,他们都会查看来自 Microsoft Entra ID 的电子邮件。 如果审阅者没有邮箱,则在评审开始时,他们不会收到电子邮件或电子邮件提醒。 而且,如果阻止他们登录 Microsoft Entra ID,则他们将无法执行评审。

配置访问评审或权利管理

一旦用户担任应用程序角色,并且你确定了审阅者,那么你就可以通过访问评审或权利管理来治理这些用户以及需要访问权限的任何其他用户。

使用访问评审或应用角色分配来评审和移除现有访问权限

如果应用程序具有多个应用程序角色而且由多个服务主体表示,或者想要设置一个流程让用户请求应用程序的访问权限或者向用户分配访问权限,请继续阅读本文的以下部分以使用权利管理治理访问权限

现在,现有用户已分配应用程序角色,可以配置 Microsoft Entra ID 以 开始这些分配的评审

  1. 对于此步骤,需要处于 Global administratorIdentity Governance administrator 角色中。

  2. 按照创建组或应用程序的访问评审的指南中的说明,创建应用程序的角色分配评审。 将评审配置为在评审完成后应用结果。 还可以使用适用于 Identity Governance 的 Microsoft Graph PowerShell cmdlet 模块中的 New-MgIdentityGovernanceAccessReviewDefinition cmdlet,在 PowerShell 中创建访问评审。 有关详细信息,请参阅示例

    注意

    如果在创建访问评审时启用评审决策帮助程序,则决策帮助程序建议基于 30 天的时间间隔,具体取决于用户上次使用 Microsoft Entra ID 登录到应用程序的时间。

  3. 访问评审开始时,要求审阅者提供输入。 默认情况下,他们每个人都会收到来自 Microsoft Entra ID 的电子邮件,其中包含指向访问权限面板的链接,他们将在访问权限面板中评审应用程序的访问权限

  4. 评审开始后,可以监视其进度,并根据需要更新审批者,直到访问评审完成。 然后,可以确认其访问权限被审阅者拒绝的用户是否已从应用程序中删除其访问权限。

  5. 如果在创建评审时未选择自动应用,则需要在评审完成后应用评审结果。

  6. 等待评审的状态更改为“已应用结果”。 几分钟后,应会看到被拒绝的用户(如果有)的应用程序角色分配被移除。

  7. 应用结果后,Microsoft Entra ID 将开始从应用程序取消预配被拒绝的用户。 根据关于预配用户需要多长时间的指导,等待 Microsoft Entra 预配开始取消预配被拒绝的用户。 通过门户或图形 API 监视预配状态,以确保所有被拒绝的用户都被成功删除。

    如果未看到正在取消预配的用户,请查看有关未预配任何用户的故障排除指南。 如果在预配状态中看到错误,并且正在预配到本地应用程序,请查看本地应用程序预配的故障排除指南

现在,你有了一个基线,可确保已评审现有访问权限,接下来可以继续在下一部分中配置权利管理,以启用新的访问请求。

使用权利管理控制访问权限

在其他情况下,例如在希望每个应用程序角色有不同审阅者的情况下,可以让应用程序由多个服务主体表示;如果希望有一个流程供用户请求(或者通过该流程向用户分配)对应用程序的访问权限,那么你可以针对每个应用程序角色为 Microsoft Entra ID 配置一个访问包。 每个访问包都可以有一个策略,用于定期评审对该访问包所做的分配。 创建访问包和策略后,可以将具有现有应用程序角色分配的用户分配给访问包,以便通过访问包来评审其分配。

在本部分中,你将配置 Microsoft Entra 权利管理,以便对包含应用角色分配的访问包分配进行评审,并且配置其他策略,让用户能够请求对应用角色的访问权限。

  1. 对于此步骤,你需要充当 Global administratorIdentity Governance administrator 角色,或者指定为目录创建者和应用程序的所有者。
  2. 如果还没有应用程序治理方案的目录,请在 Microsoft Entra 权利管理中创建目录。 可以使用 PowerShell 脚本来创建每个目录
  3. 使用必需的资源来填充目录,将应用程序以及应用程序依赖的任何 Microsoft Entra 组添加为该目录中的资源。 可以使用 PowerShell 脚本将每个资源添加到目录
  4. 对于每个应用程序及它们的每个应用程序角色或组,创建一个访问包,其中包括角色或组作为其资源。 在配置这些访问包的这一阶段,请将每个访问包中的第一个访问包分配策略配置为一个直接分配的策略,以便只有管理员可以创建该策略的分配,为现有用户(如有)设置访问评审要求,以便他们不会无限期地保留访问权限。 如果有多个访问包,可以使用 PowerShell 脚本在目录中创建每个访问包
  5. 对于每个访问包,将具有该角色的应用程序的现有用户或该组的成员分配给访问包及其直接分配策略。 你可以使用 Microsoft Entra 管理中心直接将用户分配给访问包,也可通过 Graph 或 PowerShell 批量分配。
  6. 如果在访问包分配策略中配置了访问评审,则在访问评审开始时,应让审阅者提供输入。 默认情况下,他们每个人都会收到来自 Microsoft Entra ID 的电子邮件,其中包含指向访问权限面板的链接,他们将在该面板中评审访问包分配。 评审完成之后,在几分钟内,应会看到被拒绝的用户(如果有)的应用程序角色分配被移除。 随后,Microsoft Entra ID 将开始从应用程序取消预配被拒绝的用户。 根据关于预配用户需要多长时间的指导,等待 Microsoft Entra 预配开始取消预配被拒绝的用户。 通过门户或图形 API 监视预配状态,以确保所有被拒绝的用户都被成功删除。
  7. 如果你有职责分离要求,请为访问包配置不兼容的访问包或现有组。 如果你的方案需要能够替代职责分离检查,则还可以为这些替代方案设置其他访问包
  8. 如果你希望允许尚无权请求访问权限的用户,请在每个访问包中为用户创建其他访问包分配策略以请求访问权限。在该策略中配置审批和定期访问评审要求。

后续步骤