使用 PowerShell 为具有单个角色的应用程序在权利管理中创建访问包

在 Microsoft Entra 权利管理中,访问包包含有关用户如何获取一个或多个资源角色分配的策略。 这些资源可能包括组、应用程序和 SharePoint Online 网站。

本文介绍如何使用 Microsoft Graph PowerShell 为具有单个角色的单个应用程序创建访问包。 此方案主要适用于使用权利管理来自动执行特定业务或中间件应用程序的持续访问的环境。 具有多个资源或资源具有多个角色的组织还可以使用访问包为其访问策略建模:

先决条件

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

在开始创建访问包之前,必须将应用程序与 Microsoft Entra ID 集成。 如果 Microsoft Entra ID 租户中尚不存在该应用程序,请按照该文章中的说明为对象创建应用程序和服务主体。 此外,请确保 Microsoft Entra ID 租户满足为 Microsoft Entra ID 配置标识治理之前的先决条件

若要创建访问包及其关联的策略和分配,需要准备好以下信息:

用例 配置设置 PowerShell 变量
全部 Microsoft Entra ID 租户中的应用程序的名称 $servicePrincipalName
全部 应用程序角色的名称 $servicePrincipalRoleName
全部 包含访问包的目录的名称 $catalogName
全部 要为访问包提供的名称 $accessPackageName
全部 要为访问包提供的说明 $accessPackageDescription
有关不兼容访问包的职责分离要求 不兼容访问包的 ID $incompatibleAccessPackageId(如果需要)
尚未获得分配且不会自动获得分配的用户 用户列表 $inputpath(如果需要)
具有特定属性的用户将自动获得分配 针对范围内用户的查询表达式 $autoAssignmentPolicyFilter(如果需要)
允许没有获得分配的用户请求分配 可以请求分配的用户所在的范围、审批者和访问评审期 取决于具体的要求
基于生命周期工作流中的入职或离职工作流自动创建或移除分配 提供和移除访问权限的工作流的名称 取决于具体的要求

向 Microsoft Entra ID 进行身份验证

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

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

  1. 打开 PowerShell。

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

    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 命令行工具具有这些权限。

在 Microsoft Entra 权利管理中创建目录

默认情况下,当管理员首次与权利管理交互时,会自动创建默认目录。 但是,受治理应用程序的访问包应位于指定目录中。

  1. 指定目录的名称。

    $catalogName = "Business applications"
    
  2. 如果已有用于应用程序治理方案的目录,请继续执行本部分的步骤 4。

  3. 如果还没有用于应用程序治理方案的目录,请创建目录

    $catalog = New-MgEntitlementManagementCatalog -DisplayName $catalogName
    
  4. 查找目录的 ID。

    $catalogFilter = "displayName eq '" + $catalogName + "'"
    $catalog = Get-MgEntitlementManagementCatalog -Filter $catalogFilter -All -expandProperty resources,accessPackages
    if ($catalog -eq $null) { throw "catalog $catalogName not found" }
    $catalogId = $catalog.Id
    

将应用程序作为资源添加到目录

创建目录后,请将应用程序添加为该目录中的资源

  1. 指定应用程序的名称和应用程序角色的名称。 将应用程序的名称作为 servicePrincipalName 的值。

    $servicePrincipalName = "SAP Cloud Identity Services"
    $servicePrincipalRoleName = "User"
    
  2. 查找应用程序服务主体的 ID。

    $servicePrincipalFilter = "displayName eq '" + $applicationName + "'"
    $servicePrincipal = Get-MgServicePrincipal -Filter $servicePrincipalFilter -all
    if ($servicePrincipal -eq $null) { throw "service principal $servicePrincipalName not found" }
    $servicePrincipalId = $servicePrincipal.Id
    
  3. 检查应用程序是否已作为资源存在于目录中。 如果已存在,请继续执行本部分的步骤 6。

    $resourceId = $null
    foreach ($r in $catalog.Resources) { if ($r.OriginId -eq $servicePrincipalId) { $resourceId = $r.id; break } }
    if ($resourceId -ne $null) { write-output "resource already in catalog" } else {write-output "resource not yet in catalog"}
    
  4. 将应用程序的服务主体作为资源添加到目录中。

    $resourceAddParams = @{
      requestType = "adminAdd"
      resource = @{
        originId = $servicePrincipalId
        originSystem = "AadApplication"
      }
      catalog = @{ id = $catalogId }
    }
    
    $resourceAdd = New-MgEntitlementManagementResourceRequest -BodyParameter $resourceAddParams
    if ($resourceAdd -eq $null) { throw "resource could not be added" }
    sleep 5
    
  5. 检索该目录中资源的 ID 和范围。

    $resource = $null
    $resourceId = $null
    $resourceScope = $null
    $catalogResources = Get-MgEntitlementManagementCatalogResource -AccessPackageCatalogId $CatalogId -ExpandProperty "scopes" -all
    
    foreach ($r in $catalogResources) { if ($r.OriginId -eq $servicePrincipalId) { $resource = $r; $resourceId = $r.id; $resourceScope = $r.Scopes[0]; break } }
    if ($resourceId -eq $null) { throw "resource was not added" }
    
  6. 检索应用程序的角色。

    $resourceRoleFilter = "(originSystem eq 'AadApplication' and resource/id eq '" + $resourceId + "')"
    $resourceRoles = @(get-mgentitlementmanagementcatalogresourcerole  -AccessPackageCatalogId $catalogId -Filter $resourceRoleFilter -All -ExpandProperty "resource")
    if ($resourceRoles -eq $null -or $resourceRoles.count -eq 0) { throw "no roles available" }
    
  7. 选择要包含在访问包中的角色。

    $resourceRole = $null
    foreach ($r in $resourceRoles) { if ($r.DisplayName -eq $servicePrincipalRoleName) { $resourceRole = $r; break; } }
    if ($resourceRole -eq $null) { throw "role $servicePrincipalRoleName not located" }
    

为应用程序创建访问包

接下来,你将使用 PowerShell 在目录中创建包含应用程序角色的访问包

  1. 指定访问包的名称和说明。

    $accessPackageName = "SAP Cloud Identity Services"
    $accessPackageDescription = "A user of SAP Cloud Identity Services"
    $accessPackageHidden = $true
    
  2. 检查确定访问包尚不存在。

    foreach ($a in $catalog.AccessPackages) { if ($a.DisplayName -eq $accessPackageName) { throw "access package $accessPackageName already exists" } }
    
  3. 创建访问包。

    $accessPackageParams = @{
        displayName = $accessPackageName
        description = $accessPackageDescription
        isHidden = $accessPackageHidden
        catalog = @{
            id = $catalog.id
        }
    }
    $accessPackage = New-MgEntitlementManagementAccessPackage -BodyParameter $accessPackageParams
    $accessPackageId = $accessPackage.Id
    

为访问包添加应用程序角色

创建访问包后,即可将目录中资源的角色链接到访问包。

$rrsParams = @{
 role = @{
     id =  $resourceRole.Id
     displayName =  $resourceRole.DisplayName
     description =  $resourceRole.Description
     originSystem =  $resourceRole.OriginSystem
     originId =  $resourceRole.OriginId
     resource = @{
         id = $resource.Id
         originId = $resource.OriginId
         originSystem = $resource.OriginSystem
     }
 }
 scope = @{
     id = $resourceScope.Id
     originId = $resourceScope.OriginId
     originSystem = $resourceScope.OriginSystem
 }
}

$roleAddRes = New-MgEntitlementManagementAccessPackageResourceRoleScope -AccessPackageId $accessPackageId -BodyParameter $rrsParams

创建用于进行直接分配的访问包分配策略

在本部分中,将在访问包中创建第一个访问包分配策略,这是一个用于进行直接分配的访问包分配策略,可用于跟踪哪些用户已有权访问应用程序。 在本部分创建的示例策略中,只有管理员或访问包分配管理员可以分配访问权限,用户将无限期地保留访问权限,并且没有审批或访问评审过程。

  1. 创建策略。

    $policy1Name = "Direct assignment policy"
    $policy1Description = "policy for administrative assignment"
    
    $policy1params = @{
     displayName = $policy1Name
     description = $policy1Description
     allowedTargetScope = "notSpecified"
     specificAllowedTargets = @(
     )
     expiration = @{
         endDateTime = $null
         duration = $null
         type = "noExpiration"
     }
     requestorSettings = @{
         enableTargetsToSelfAddAccess = $true
         enableTargetsToSelfUpdateAccess = $false
         enableTargetsToSelfRemoveAccess = $true
         allowCustomAssignmentSchedule = $true
         enableOnBehalfRequestorsToAddAccess = $false
         enableOnBehalfRequestorsToUpdateAccess = $false
         enableOnBehalfRequestorsToRemoveAccess = $false
         onBehalfRequestors = @(
         )
     }
     requestApprovalSettings = @{
         isApprovalRequiredForAdd = $false
         isApprovalRequiredForUpdate = $false
         stages = @(
         )
     }
     accessPackage = @{
         id = $accessPackageId
     }
    }
    
    $policy1Res = New-MgEntitlementManagementAssignmentPolicy -BodyParameter $policy1params
    $directAssignmentPolicyId = $policy1Res.Id
    
    

配置职责分离约束

Microsoft Entra 权利管理可以强制执行职责分离检查,以阻止已经分配给另一个指定访问包或已是指定组成员的用户请求访问包。

如果对此应用程序没有职责分离要求,请继续进行下一部分的操作。

如果你有职责分离要求,请为访问包配置不兼容的访问包或现有组。

对于要标记为与另一个访问包不兼容的每个访问包,可以使用 PowerShell 将访问包配置为不兼容

  1. 指定与此访问包不兼容的另一个访问包。 请将 incompatibleAccessPackageId 的值更改为 Microsoft Entra 权利管理中另一个访问包的 ID。

    $incompatibleAccessPackageId = "67cc7175-7a3d-4cb2-860f-4d9217ba96ca"
    
  2. 在此访问包上创建不兼容的引用。

    $incompatible1params = @{
     "@odata.id" = "https://graph.microsoft.com/v1.0/identityGovernance/entitlementManagement/accessPackages/" + $incompatibleAccessPackageId
    }
    New-MgEntitlementManagementAccessPackageIncompatibleAccessPackageByRef -AccessPackageId $accessPackageId -BodyParameter $incompatible1params
    
  3. 在另一个访问包上创建不兼容的引用。

    $incompatible2params = @{
     "@odata.id" = "https://graph.microsoft.com/v1.0/identityGovernance/entitlementManagement/accessPackages/" + $accessPackageId
    }
    New-MgEntitlementManagementAccessPackageIncompatibleAccessPackageByRef -AccessPackageId $incompatibleAccessPackageId -BodyParameter $incompatible2params
    
  4. 对任何其他访问包重复此操作。

  5. 如果你的方案需要能够替代职责分离检查,则还可以为这些替代方案设置其他访问包

添加对已有权访问应用程序的现有用户的分配

向访问包及其直接分配策略添加对已有权访问应用程序的现有用户的分配。 你可以直接将每个用户分配给访问包。

  1. 检索现有的应用程序角色分配。

    $existingAppRoleAssignments = @(Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $servicePrincipalId -All)
    
  2. 为了避免创建重复分配,请检索访问包的任何现有分配。

    $existingAssignments1filter = "accessPackage/id eq '" + $accessPackageId + "' and state eq 'Delivered'"
    $existingassignments1 = @(Get-MgEntitlementManagementAssignment -Filter $existingAssignments1filter -ExpandProperty target -All -ErrorAction Stop)
    $existingusers1 = @()
    foreach ($a in $existingassignments1) { $existingusers1 += $a.Target.ObjectId}
    
  3. 创建新分配。

    foreach ($ar in $existingAppRoleAssignments) {
     if ($ar.principalType -ne "User") {
       write-warning "non-user assigned to application role"
     }
     $arpid = $ar.principalId
     if ($existingusers1.contains($arpId)) { continue }
    
     $params = @{
       requestType = "adminAdd"
       assignment = @{
          targetId = $arpId
          assignmentPolicyId = $directAssignmentPolicyId
          accessPackageId = $accessPackageId
       }
     }
     try {
       New-MgEntitlementManagementAssignmentRequest -BodyParameter $params
     } catch {
       write-error "cannot create request for user $upn"
     }
    }
    

为应有权访问应用程序的任何其他用户添加分配

此脚本演示如何使用 Microsoft Graph PowerShell cmdlet 为其他用户添加分配,以便其有权访问应用程序。 如果没有任何需要访问权限的用户,并且他们不会自动获得访问权限,请继续进行下一部分的操作。

此脚本假定你有一个包含一个列(即 UserPrincipalName)的输入 CSV 文件,用于通过其直接分配策略将这些用户分配到访问包。

  1. 指定该输入文件的名称。

    $inputpath = "users.csv"
    
  2. 为了避免创建重复分配,请检索访问包的任何现有分配。

    $existingAssignments2filter = "accessPackage/id eq '" + $accessPackageId + "' and state eq 'Delivered'"
    $existingassignments2 = @(Get-MgEntitlementManagementAssignment -Filter $existingAssignments2filter -ExpandProperty target -All -ErrorAction Stop)
    $existingusers2 = @()
    foreach ($a in $existingassignments2) { $existingusers2 += $a.Target.ObjectId}
    
  3. 创建新分配。

    $users = import-csv -Path $inputpath
    foreach ($userrecord in $users) {
       $upn = $userrecord.UserPrincipalName
       if ($null -eq $upn) {throw "no UserPrincipalName" }
       $u = $null
       try {
          $u = Get-MgUser -UserId $upn
       } catch {
          write-error "no user $upn"
       }
       if ($u -eq $null) { continue }
       if ($existingusers2.contains($u.Id)) { continue }
    
       $params = @{
          requestType = "adminAdd"
          assignment = @{
             targetId = $u.Id
             assignmentPolicyId = $directAssignmentPolicyId
             accessPackageId = $accessPackageId
          }
       }
       try {
          New-MgEntitlementManagementAssignmentRequest -BodyParameter $params
       } catch {
          write-error "cannot create request for user $upn"
       }
    }
    

将策略添加到访问包以进行自动分配

如果组织有关可为哪些人分配对应用程序的访问权限的策略包括基于用户属性的规则,以便根据这些属性自动分配和移除访问权限,则可以使用自动分配策略来表示此策略。 一个访问包最多可以有一个自动分配策略。 如果没有自动分配的要求,请继续进行下一部分的操作。

  1. 指定用于决定哪些用户可接收分配的自动分配筛选表达式。 请将 autoAssignmentPolicyFilter 的值更改为用于筛选 Microsoft Entra ID 中相应范围内的用户的筛选器。 Microsoft Entra ID 中的动态成员资格组规则中提供语法和允许的属性。

    $autoAssignmentPolicyFilter = '(user.city -eq "Redmond")'
    
  2. 使用 PowerShell 在访问包中创建自动分配策略

    $policy2Name = "Automatic assignment policy"
    $policy2Description = "policy for automatic assignment"
    
    $policy2Params = @{
     DisplayName = $policy2Name
     Description = $policy2Description
     AllowedTargetScope = "specificDirectoryUsers"
     SpecificAllowedTargets = @( @{
         "@odata.type" = "#microsoft.graph.attributeRuleMembers"
         description = $policy2Description
         membershipRule = $autoAssignmentPolicyFilter
     } )
     AutomaticRequestSettings = @{
         RequestAccessForAllowedTargets = $true
     }
     AccessPackage = @{
       Id = $accessPackageId
     }
    }
    New-MgEntitlementManagementAssignmentPolicy -BodyParameter $policy2Params
    

创建其他策略以允许用户请求访问权限

对于尚无访问权限的用户,如果允许其请求为其分配应用程序,则还可以配置访问包分配策略以允许用户请求访问包。 可以将其他策略添加到访问包,并在每个策略中指定哪些用户可以请求以及哪些用户必须批准。 如果希望仅通过自动方式或由管理员为用户分配访问权限,请继续进行下一部分的操作。

有关更多示例,请参阅通过 PowerShell 创建分配策略accessPackageAssignmentPolicy创建 assignmentPolicy

  1. 指定名称、策略说明以及将成为审批者的 Microsoft Entra 用户的 ID。

    $policy3Name = "example policy"
    $policy3Description = "example of a policy for users to request assignment"
    $policy3ApproverSingleUserId = "1aaaaaa1-2bb2-3cc3-4dd4-5eeeeeeeeee5"
    
  2. 创建策略。

    $policy3Params = @{
     displayName = $policy3Name
     description = $policy3Description
     allowedTargetScope = "allMemberUsers"
     expiration = @{
         type = "noExpiration"
     }
     requestorSettings = @{
         enableTargetsToSelfAddAccess = "true"
         enableTargetsToSelfUpdateAccess = "true"
         enableTargetsToSelfRemoveAccess = "true"
     }
     requestApprovalSettings = @{
         isApprovalRequiredForAdd = "true"
         isApprovalRequiredForUpdate = "true"
         stages = @(
             @{
                 durationBeforeAutomaticDenial = "P7D"
                 isApproverJustificationRequired = "false"
                 isEscalationEnabled = "false"
                 fallbackPrimaryApprovers = @(
                 )
                 escalationApprovers = @(
                 )
                 fallbackEscalationApprovers = @(
                 )
                 primaryApprovers = @(
                     @{
                         "@odata.type" = "#microsoft.graph.singleUser"
                         userId = $policy3ApproverSingleUserId
                     }
                 )
             }
         )
     }
     accessPackage = @{
         id = $accessPackageId
     }
    }
    
    New-MgEntitlementManagementAssignmentPolicy -BodyParameter $policy3Params
    

配置生命周期工作流任务

如果使用处理员工入职、调动和离职事件的 Microsoft Entra 生命周期工作流,则还可以向这些工作流添加任务,以添加或移除此访问包的分配。 如果不使用生命周期工作流,请继续进行下一部分的操作。

此示例演示如何更改入职和离职事件工作流。

  1. 使用 Get-MgIdentityGovernanceLifecycleWorkflow 命令检索 joiner 类别的工作流及其任务。

  2. 任务添加到该工作流中的任务列表。

    任务显示名称 taskDefinitionId 参数
    请求用户访问包分配 c1ec1e76-f374-4375-aaa6-0bb6bd4c60be name: assignmentPolicyId
    :要为用户分配的访问包的分配策略 ID,例如来自 $directAssignmentPolicyId 的值(如果不需要审批)。

    name: accessPackageId
    值:要为用户分配的访问包的访问包 ID $accessPackageId
  3. 使用 New-MgIdentityGovernanceLifecycleWorkflowNewVersion 命令创建新版本的工作流(包括该新任务)。

  4. 使用 Get-MgIdentityGovernanceLifecycleWorkflow 命令检索 leaver 类别的工作流及其任务。

  5. 任务添加到该工作流中的任务列表。

    任务显示名称 taskDefinitionId 参数
    移除用户的访问包分配 4a0b64f2-c7ec-46ba-b117-18f262946c50 name: accessPackageId
    值:要为用户取消分配的访问包的有效访问包 ID accessPackageId
  6. 使用 New-MgIdentityGovernanceLifecycleWorkflowNewVersion 命令创建新版本的工作流(包括该新任务)。

管理分配

创建访问包、策略和初始分配后,将向用户分配对应用程序角色的访问权限。

稍后,你可以监视对这些分配的更改,或者以编程方式添加或移除分配。

检索现有分配

此脚本演示如何使用筛选器来检索状态为 Delivered 的访问包分配。 该脚本将生成 CSV 文件 assignments.csv,其中包含具有分配的用户所组成的列表,每个分配显示为一行。

$assignmentFilter = "accessPackage/id eq '" + $accessPackageId + "' and state eq 'Delivered'"
$assignments = @(Get-MgEntitlementManagementAssignment -Filter $assignmentFilter -ExpandProperty target -All -ErrorAction Stop)
$sp = $assignments | select-object -Property Id,{$_.Target.id},{$_.Target.ObjectId},{$_.Target.DisplayName},{$_.Target.PrincipalName}
$sp | Export-Csv -Encoding UTF8 -NoTypeInformation -Path ".\assignments.csv"

移除分配

你可以使用 New-MgEntitlementManagementAssignmentRequest cmdlet 移除用户的分配。

$userId = "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"
$filter = "accessPackage/Id eq '" + $accessPackageId + "' and state eq 'Delivered' and target/objectId eq '" + $userId + "'"
$assignment = Get-MgEntitlementManagementAssignment -Filter $filter -ExpandProperty target -all -ErrorAction stop
if ($assignment -ne $null) {
   $params = @{
      requestType = "adminRemove"
      assignment = @{ id = $assignment.id }
   }
   New-MgEntitlementManagementAssignmentRequest -BodyParameter $params
}

后续步骤