使用 PowerShell 为具有单个角色的应用程序在权利管理中创建访问包
在 Microsoft Entra 权利管理中,访问包包含有关用户如何获取一个或多个资源角色分配的策略。 这些资源可能包括组、应用程序和 SharePoint Online 网站。
本文介绍如何使用 Microsoft Graph PowerShell 为具有单个角色的单个应用程序创建访问包。 此方案主要适用于使用权利管理来自动执行特定业务或中间件应用程序的持续访问的环境。 具有多个资源或资源具有多个角色的组织还可以使用访问包为其访问策略建模:
- 如果组织已经拥有针对其业务角色的现有组织角色模型,则可以将该模型迁移到 Microsoft Entra ID Governance,并使用组织角色模型管理访问权限。
- 如果组织内有具有多个角色的应用程序,则可以部署组织策略以控制对与 Microsoft Entra ID 集成的应用程序的访问
- 有关为其他方案创建访问包的详细信息,请参阅教程:管理对权利管理中资源的访问权限,以及如何在权利管理中创建访问包。
先决条件
使用此功能需要 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 用于租户。 后续交互可以使用较低特权角色,例如:
打开 PowerShell。
如果尚未安装 Microsoft Graph PowerShell 模块,请使用以下命令安装
Microsoft.Graph.Identity.Governance
模块和其他模块:Install-Module Microsoft.Graph
如果已安装模块,请确保使用的是最新版本:
Update-Module microsoft.graph.users,microsoft.graph.identity.governance,microsoft.graph.applications
连接到 Microsoft Entra ID:
$msg = Connect-MgGraph -ContextScope Process -Scopes "User.ReadWrite.All,Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All,EntitlementManagement.ReadWrite.All"
如果这是你第一次使用此命令,则可能需要同意允许 Microsoft Graph 命令行工具具有这些权限。
在 Microsoft Entra 权利管理中创建目录
默认情况下,当管理员首次与权利管理交互时,会自动创建默认目录。 但是,受治理应用程序的访问包应位于指定目录中。
指定目录的名称。
$catalogName = "Business applications"
如果已有用于应用程序治理方案的目录,请继续执行本部分的步骤 4。
如果还没有用于应用程序治理方案的目录,请创建目录。
$catalog = New-MgEntitlementManagementCatalog -DisplayName $catalogName
查找目录的 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
将应用程序作为资源添加到目录
创建目录后,请将应用程序添加为该目录中的资源。
指定应用程序的名称和应用程序角色的名称。 将应用程序的名称作为
servicePrincipalName
的值。$servicePrincipalName = "SAP Cloud Identity Services" $servicePrincipalRoleName = "User"
查找应用程序服务主体的 ID。
$servicePrincipalFilter = "displayName eq '" + $applicationName + "'" $servicePrincipal = Get-MgServicePrincipal -Filter $servicePrincipalFilter -all if ($servicePrincipal -eq $null) { throw "service principal $servicePrincipalName not found" } $servicePrincipalId = $servicePrincipal.Id
检查应用程序是否已作为资源存在于目录中。 如果已存在,请继续执行本部分的步骤 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"}
将应用程序的服务主体作为资源添加到目录中。
$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
检索该目录中资源的 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" }
检索应用程序的角色。
$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" }
选择要包含在访问包中的角色。
$resourceRole = $null foreach ($r in $resourceRoles) { if ($r.DisplayName -eq $servicePrincipalRoleName) { $resourceRole = $r; break; } } if ($resourceRole -eq $null) { throw "role $servicePrincipalRoleName not located" }
为应用程序创建访问包
接下来,你将使用 PowerShell 在目录中创建包含应用程序角色的访问包。
指定访问包的名称和说明。
$accessPackageName = "SAP Cloud Identity Services" $accessPackageDescription = "A user of SAP Cloud Identity Services" $accessPackageHidden = $true
检查确定访问包尚不存在。
foreach ($a in $catalog.AccessPackages) { if ($a.DisplayName -eq $accessPackageName) { throw "access package $accessPackageName already exists" } }
创建访问包。
$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
创建用于进行直接分配的访问包分配策略
在本部分中,将在访问包中创建第一个访问包分配策略,这是一个用于进行直接分配的访问包分配策略,可用于跟踪哪些用户已有权访问应用程序。 在本部分创建的示例策略中,只有管理员或访问包分配管理员可以分配访问权限,用户将无限期地保留访问权限,并且没有审批或访问评审过程。
创建策略。
$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 将访问包配置为不兼容。
指定与此访问包不兼容的另一个访问包。 请将
incompatibleAccessPackageId
的值更改为 Microsoft Entra 权利管理中另一个访问包的 ID。$incompatibleAccessPackageId = "67cc7175-7a3d-4cb2-860f-4d9217ba96ca"
在此访问包上创建不兼容的引用。
$incompatible1params = @{ "@odata.id" = "https://graph.microsoft.com/v1.0/identityGovernance/entitlementManagement/accessPackages/" + $incompatibleAccessPackageId } New-MgEntitlementManagementAccessPackageIncompatibleAccessPackageByRef -AccessPackageId $accessPackageId -BodyParameter $incompatible1params
在另一个访问包上创建不兼容的引用。
$incompatible2params = @{ "@odata.id" = "https://graph.microsoft.com/v1.0/identityGovernance/entitlementManagement/accessPackages/" + $accessPackageId } New-MgEntitlementManagementAccessPackageIncompatibleAccessPackageByRef -AccessPackageId $incompatibleAccessPackageId -BodyParameter $incompatible2params
对任何其他访问包重复此操作。
如果你的方案需要能够替代职责分离检查,则还可以为这些替代方案设置其他访问包。
添加对已有权访问应用程序的现有用户的分配
向访问包及其直接分配策略添加对已有权访问应用程序的现有用户的分配。 你可以直接将每个用户分配给访问包。
检索现有的应用程序角色分配。
$existingAppRoleAssignments = @(Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $servicePrincipalId -All)
为了避免创建重复分配,请检索访问包的任何现有分配。
$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}
创建新分配。
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 文件,用于通过其直接分配策略将这些用户分配到访问包。
指定该输入文件的名称。
$inputpath = "users.csv"
为了避免创建重复分配,请检索访问包的任何现有分配。
$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}
创建新分配。
$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" } }
将策略添加到访问包以进行自动分配
如果组织有关可为哪些人分配对应用程序的访问权限的策略包括基于用户属性的规则,以便根据这些属性自动分配和移除访问权限,则可以使用自动分配策略来表示此策略。 一个访问包最多可以有一个自动分配策略。 如果没有自动分配的要求,请继续进行下一部分的操作。
指定用于决定哪些用户可接收分配的自动分配筛选表达式。 请将
autoAssignmentPolicyFilter
的值更改为用于筛选 Microsoft Entra ID 中相应范围内的用户的筛选器。 Microsoft Entra ID 中的动态成员资格组规则中提供语法和允许的属性。$autoAssignmentPolicyFilter = '(user.city -eq "Redmond")'
使用 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。
指定名称、策略说明以及将成为审批者的 Microsoft Entra 用户的 ID。
$policy3Name = "example policy" $policy3Description = "example of a policy for users to request assignment" $policy3ApproverSingleUserId = "1aaaaaa1-2bb2-3cc3-4dd4-5eeeeeeeeee5"
创建策略。
$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 生命周期工作流,则还可以向这些工作流添加任务,以添加或移除此访问包的分配。 如果不使用生命周期工作流,请继续进行下一部分的操作。
此示例演示如何更改入职和离职事件工作流。
使用 Get-MgIdentityGovernanceLifecycleWorkflow 命令检索
joiner
类别的工作流及其任务。将任务添加到该工作流中的任务列表。
任务显示名称 taskDefinitionId 参数 请求用户访问包分配 c1ec1e76-f374-4375-aaa6-0bb6bd4c60be
name: assignmentPolicyId
值:要为用户分配的访问包的分配策略 ID,例如来自$directAssignmentPolicyId
的值(如果不需要审批)。
name:accessPackageId
值:要为用户分配的访问包的访问包 ID$accessPackageId
。使用 New-MgIdentityGovernanceLifecycleWorkflowNewVersion 命令创建新版本的工作流(包括该新任务)。
使用 Get-MgIdentityGovernanceLifecycleWorkflow 命令检索
leaver
类别的工作流及其任务。将任务添加到该工作流中的任务列表。
任务显示名称 taskDefinitionId 参数 移除用户的访问包分配 4a0b64f2-c7ec-46ba-b117-18f262946c50
name: accessPackageId
值:要为用户取消分配的访问包的有效访问包 IDaccessPackageId
。使用 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
}