次の方法で共有

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

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

本文介绍如何使用 Microsoft Graph PowerShell 为具有单个角色的单个应用程序创建访问包。 此方案主要适用于使用权限管理自动化特定的业务应用程序或中间件持续访问的环境。 您可以根据本文及其他文章中的指南进行拓展,应用于更复杂的场景,例如跨多个应用程序进行访问,或者跨应用程序和其他类型资源的访问。 具有多个资源或具有多个角色的资源的组织还可以使用访问包为其访问策略建模:

先决条件

使用此功能需要Microsoft Entra ID Governance 或 Microsoft Entra Suite 许可证。 若要查找符合要求的正确许可证,请参阅 Microsoft Entra ID Governance 许可基础知识

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

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

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

向 Microsoft Entra ID 进行身份验证

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

当您的组织首次在此场景中使用这些 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 -Environment China -ClientId 'YOUR_CLIENT_ID' -TenantId 'YOUR_TENANT_ID' -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" }
    

将组作为资源添加到目录

如果应用程序依赖于安全组,请将该组添加到目录中,以便将其作为资源包含。 如果应用程序不依赖于安全组,请在下一部分继续操作。

  1. 指定组的 ID。 使用组的 ID 作为 servicePrincipalName 的值。

    $groupId = "7c2b967b-68c2-418a-a1c6-a3c7efb895a7"
    
  2. 检查该组是否已作为资源存在于目录中。 如果已存在,请继续执行本部分的步骤 4。

    $groupResourceId = $null
    foreach ($r in $catalog.Resources) { if ($r.OriginId -eq $groupId) { $groupResourceId = $r.id; break } }
    if ($groupResourceId -ne $null) { write-output "resource for group already in catalog" } else {write-output "resource for group not yet in catalog"}
    
  3. 将组作为资源添加到目录中。

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

    $groupResource = $null
    $groupResourceId = $null
    $groupResourceScope = $null
    $catalogResources = Get-MgEntitlementManagementCatalogResource -AccessPackageCatalogId $CatalogId -ExpandProperty "scopes" -all
    
    foreach ($r in $catalogResources) { if ($r.OriginId -eq $groupId) { $groupResource = $r; $groupResourceId = $r.id; $groupResourceScope = $r.Scopes[0]; break } }
    if ($groupResourceId -eq $null) { throw "resource was not added" }
    
  5. 检索该目录中member组资源的角色。

    $grFilter = "(originSystem eq 'AadGroup' and resource/id eq '" + $groupResourceId + "')"
    $grrs = Get-MgEntitlementManagementCatalogResourceRole -AccessPackageCatalogId $CatalogId -Filter $grFilter -ExpandProperty "resource"
    $grMember = $grrs | where DisplayName -eq "Member"
    

为应用程序创建访问包

接下来,你将使用 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

将组添加到访问包

如果应用程序依赖于组,则将组的组成员身份链接到访问包。 如果应用程序不依赖于组,请继续到下一节。

 $grrsParams = @{
  role = @{
      displayName =  "Member"
      description =  ""
      originSystem =  $grMember.OriginSystem
      originId =  $grMember.OriginId
      resource = @{
          id = $groupResource.Id
          originId = $groupResource.OriginId
          originSystem = $groupResource.OriginSystem
      }
  }
  scope = @{
      id = $groupResourceScope.Id
      originId = $groupResourceScope.OriginId
      originSystem = $groupResourceScope.OriginSystem
  }
 }

 $groupRrsAddRes = New-MgEntitlementManagementAccessPackageResourceRoleScope -AccessPackageId $accessPackageId -BodyParameter $grrsParams

为直接分配创建访问包分配策略

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

  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. 指定与此访问包不兼容的其他访问包。 在 Microsoft Entra 授权管理中,将 incompatibleAccessPackageId 的值更改为另一个访问包的 ID。

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

    $incompatible1params = @{
     "@odata.id" = "https://microsoftgraph.chinacloudapi.cn/v1.0/identityGovernance/entitlementManagement/accessPackages/" + $incompatibleAccessPackageId
    }
    New-MgEntitlementManagementAccessPackageIncompatibleAccessPackageByRef -AccessPackageId $accessPackageId -BodyParameter $incompatible1params
    
  3. 在其他访问包上创建不兼容的引用。

    $incompatible2params = @{
     "@odata.id" = "https://microsoftgraph.chinacloudapi.cn/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 nameassignmentPolicyId
    :要为用户分配的访问包的分配策略 ID,例如在不需要审批的情况下,使用$directAssignmentPolicyId的值。

    nameaccessPackageId
    :要分配给用户的访问包的访问包 ID $accessPackageId
  3. 使用 New-MgIdentityGovernanceLifecycleWorkflowNewVersion 命令创建工作流的新版本,包括新任务。

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

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

    任务显示名称 taskDefinitionId 争论
    移除用户的访问包分配 4a0b64f2-c7ec-46ba-b117-18f262946c50 nameaccessPackageId
    :要从用户取消分配的访问包的有效访问包 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
}

后续步骤