如何使用PowerShell 7设置Microsoft Graph API权限

发布于 2025-02-13 20:34:04 字数 4414 浏览 0 评论 0原文

要将Microsoft Graph API权限授予用户分配的托管服务身份或系统分配的托管服务身份,则必须使用PowerShell。我可以找到的所有文章(例如-p/2792127“ rel =“ noreferrer”> this )指向使用azuread powerShell模块的 cmdlet new-azureadserviceApproleassignment cmdlet,但是,此模块不支持任何比Windows PowerShell版本5.1更新的内容,并且因为我需要在Linux上完成Linux上的任务 - 基于构建代理,我需要找到PowerShell(Core)支持的方法。

查看azuread的最后更新日期,我怀疑MS没有计划进一步更新它,除了很多功能,许多功能已经移至az powershell模块,但是,关键的CMDLET似乎并没有实现。 (AzureadPreview有相同的问题)。我不确定Microsoft正在朝哪个方向前进,但是为了混淆问题,有Microsoft.graph模块。更具体地说Microsoft.graph.applications。查看模块中的CMDLET列表,实现相同任务的最有可能的候选人是new-mgserviceprincipalapproleassignment,但是,我无法正常工作。

以下是azuread Windows PowerShell(5.1)方式(可与新的az cmdlets一起使用):

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource)

# Graph API permissions to set
$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-AzureAD -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
    New-AzureAdServiceAppRoleAssignment `
      -ObjectId $oMsi.Id `
      -PrincipalId $oMsi.Id `
      -ResourceId $oGraphSpn.Id `
      -Id $AppRole.Id `
      -Verbose
}

这是我尝试使用microsoft.graph.applications的尝试带有PowerShell的模块(V.7.2.5)。

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource)

$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
  "GroupMember.ReadWrite.All"
  "User.ReadWrite.All"
  "RoleManagement.ReadWrite.Directory"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-MgGraph -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
  $oAppRoleAssignment = @{
    "PrincipalId" = $oMSI.Id
    "ResourceId" = $GraphAppId
    "AppRoleId" = $AppRole.Id
  }
  
  New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
    -BodyParameter $oAppRoleAssignment `
    -Verbose
}

这会导致以下错误:

PS C:\> . "Set-ApiPermissionsForMI.ps1"
VERBOSE: Performing the operation "New-MgServicePrincipalAppRoleAssignment_Create1" on target "Call remote 'ServicePrincipalsCreateAppRoleAssignments1' operation".
New-MgServicePrincipalAppRoleAssignment_Create1: C:\Set-ApiPermissionsForMI.ps1:36:3
Line |
  36 |    New-MgServicePrincipalAppRoleAssignment `
     |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Resource '00000003-0000-0000-c000-000000000000' does not exist or one of its queried reference-property objects are not present.

我看到MS Graph的“特殊”服务主体缺少,但是由于azuread cmdlet有效,我知道这是正确的,但我不知道如果此CMDLET甚至是正确的替换 - 如果有一个可与PowerShell Core一起使用的替换。

如果有人可以解决我的问题,如果您可以分享,我将非常感谢。

TIA

更新1

我发现文档将azuread的映射描述为Microsoft.graph cmdlets。我有正确的cmdlet:

azureadmicrosoft.graph.applications
new-azureadserviceApproleassignmentnew-mgserviceprincipalapproleassignment new-mgServiceProleasSignment

该文档还证实了Microsoft用azuread Microsoft.graph microsoft.graph module module module module。

To grant Microsoft Graph API permissions to a User-Assigned Managed Service Identity or System-Assigned Managed Service Identity, one has to use PowerShell. All the articles I can find (e.g. this) point to using the New-AzureAdServiceAppRoleAssignment cmdlet from the AzureAD PowerShell module, however, this module doesn't support anything newer than Windows PowerShell version 5.1 and as I need to complete the task on a Linux-based build agent, I need to find a way supported by PowerShell (core).

Looking at the last update date of AzureAD, I suspect MS aren't planning on updating it further and besides a lot of the functionality has already moved to the Az PowerShell module, however, the critical cmdlet doesn't appear to have made it across. (AzureADPreview has the same issues). I am not sure which direction Microsoft are heading, but to confuse matters, there is the Microsoft.Graph module; more specifically Microsoft.Graph.Applications. Reviewing the list of cmdlets in the module, the most likely candidate to achieve the same task is New-MgServicePrincipalAppRoleAssignment, however, I cannot get it to work.

The following is the AzureAD Windows PowerShell (5.1) way (that works with the new Az cmdlets):

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource)

# Graph API permissions to set
$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-AzureAD -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
    New-AzureAdServiceAppRoleAssignment `
      -ObjectId $oMsi.Id `
      -PrincipalId $oMsi.Id `
      -ResourceId $oGraphSpn.Id `
      -Id $AppRole.Id `
      -Verbose
}

Here is my attempt at using the Microsoft.Graph.Applications module with PowerShell (v.7.2.5).

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource)

$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
  "GroupMember.ReadWrite.All"
  "User.ReadWrite.All"
  "RoleManagement.ReadWrite.Directory"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-MgGraph -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
  $oAppRoleAssignment = @{
    "PrincipalId" = $oMSI.Id
    "ResourceId" = $GraphAppId
    "AppRoleId" = $AppRole.Id
  }
  
  New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
    -BodyParameter $oAppRoleAssignment `
    -Verbose
}

This results in the following error:

PS C:\> . "Set-ApiPermissionsForMI.ps1"
VERBOSE: Performing the operation "New-MgServicePrincipalAppRoleAssignment_Create1" on target "Call remote 'ServicePrincipalsCreateAppRoleAssignments1' operation".
New-MgServicePrincipalAppRoleAssignment_Create1: C:\Set-ApiPermissionsForMI.ps1:36:3
Line |
  36 |    New-MgServicePrincipalAppRoleAssignment `
     |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Resource '00000003-0000-0000-c000-000000000000' does not exist or one of its queried reference-property objects are not present.

I see it's complaining that the "special" service principal for MS Graph is missing, but as the AzureAD cmdlet worked, I know it is correct, but I don't know if this cmdlet is even the correct replacement - if there even is a replacement that works with PowerShell core.

If anyone has a solution for my problem, I'd be very grateful if you could share, please.

T.I.A.

Update 1

I've found this document describing the mapping of AzureAD to Microsoft.Graph cmdlets. I have the correct cmdlet:

AzureADMicrosoft.Graph.Applications
New-AzureADServiceAppRoleAssignmentNew-MgServicePrincipalAppRoleAssignment

The document also confirms that Microsoft are replacing the AzureAD module with the Microsoft.Graph module.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

高冷爸爸 2025-02-20 20:34:04

漫长的一天!问题在于椅子和键盘之间!这是工作解决方案:

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use the same name as resource).

$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
  "GroupMember.ReadWrite.All"
  "User.ReadWrite.All"
  "RoleManagement.ReadWrite.Directory"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-MgGraph -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
  $oAppRoleAssignment = @{
    "PrincipalId" = $oMSI.Id
    #"ResourceId" = $GraphAppId
    "ResourceId" = $oGraphSpn.Id
    "AppRoleId" = $AppRole.Id
  }
  
  New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
    -BodyParameter $oAppRoleAssignment `
    -Verbose
}

问题是在hashtable $ oapproleassignment.resourceid中。
它应该是$ ographspn.id而不是$ graphappid。我通过应用程序ID,而不是应用程序的SPN ID。

自动身份验证。

您可能已经注意到connect-mggraph cmdlet。正如我在问题中提到的那样,这将需要在构建代理上工作,因此我需要自动化的凭据。 Microsoft决定让我们跳过一堆篮球。我们不能将其作为pscredential对象。我们必须创建另一个基于证书的SPN并设置公共和私钥。我还没有做这件事,但是有一个指南此处请参阅更新2

。 github 在这里。如果您希望Connect-mggraph支持-Credential,请考虑将其贴上大拇指。

基于秘密的SPN

不再需要。请参阅更新2。

这是如何使用基于秘密的SPN进行身份验证的

# Replace below with your details (these are not the actual GUIDs).
$appid = '1a0f530d-e288-4f71-9870-f72e0079e6c3'
$tenantid = '9734136b-c9d8-43f7-9c99-29737c23e5c9'
$secret = '<YOUR-CLIENT-SECRET>'

 
$body =  @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $appid
    Client_Secret = $secret
}
 
$connection = Invoke-RestMethod `
    -Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token `
    -Method POST `
    -Body $body
 
$token = $connection.access_token
 
Connect-MgGraph -AccessToken $token

方法: https://helloitsliam.com/2022/04/20/connect-to-microsoft-graph-powershell-using-an-app-registration/

请记住要分配服务原理(SPN) API Application 在Azure AD中的权限。

旁注:

add-azadapppermission cmdlet,但不幸的是,这仅适用于广告应用程序msis。我尝试运行它,但是它错误,无法找到我的Objectid

更新2(2年后),

我被要求更新此信息,但是很久以前,我并不是100%确定自己想做什么,所以请阅读评论。 Microsoft已为Microsoft.graph.graph PS模块做了很多工作,我注意到人们现在可以使用基于秘密的SPN登录。

我知道MS文档总是显示-scopes,但是说实话,我不明白为什么我需要添加“范围”。当然,它应该能够确定我的用户/SPN的权限。我经常不需要添加任何范围。也许那是因为我是当时正在从事的房客的全球管理员。

Long day! The problem was between the chair and the keyboard! Here is the working solution:

$DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
$MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use the same name as resource).

$oPermissions = @(
  "Directory.ReadWrite.All"
  "Group.ReadWrite.All"
  "GroupMember.ReadWrite.All"
  "User.ReadWrite.All"
  "RoleManagement.ReadWrite.Directory"
)

$GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.

$oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
$oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"

$oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}

Connect-MgGraph -TenantId $DestinationTenantId

foreach($AppRole in $oAppRole)
{
  $oAppRoleAssignment = @{
    "PrincipalId" = $oMSI.Id
    #"ResourceId" = $GraphAppId
    "ResourceId" = $oGraphSpn.Id
    "AppRoleId" = $AppRole.Id
  }
  
  New-MgServicePrincipalAppRoleAssignment `
    -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
    -BodyParameter $oAppRoleAssignment `
    -Verbose
}

The problem was in the hashtable $oAppRoleAssignment.ResourceId.
It should be $oGraphSpn.Id and not $GraphAppId. I was passing the App ID, not the SPN ID of the App.

Automated authentication.

You may have noticed the Connect-MgGraph cmdlet. As I mentioned in the question, this will need to work on a build agent and therefore I need automated credentials. Microsoft have decided to make us jump through a bunch of hoops. We can't pass it as a PSCredential object. We have to create another certificate-based SPN and set up the public and private keys. I haven't done this bit yet, but there is a guide here. See Update 2.

There is an open issue on Github here. If you'd like Connect-MgGraph to support -Credential please consider giving it the thumbs up.

Secret-Based SPN

This isn't required anymore. See update 2.

Here's how to authenticate with a secret-based SPN:

# Replace below with your details (these are not the actual GUIDs).
$appid = '1a0f530d-e288-4f71-9870-f72e0079e6c3'
$tenantid = '9734136b-c9d8-43f7-9c99-29737c23e5c9'
$secret = '<YOUR-CLIENT-SECRET>'

 
$body =  @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $appid
    Client_Secret = $secret
}
 
$connection = Invoke-RestMethod `
    -Uri https://login.microsoftonline.com/$tenantid/oauth2/v2.0/token `
    -Method POST `
    -Body $body
 
$token = $connection.access_token
 
Connect-MgGraph -AccessToken $token

Source: https://helloitsliam.com/2022/04/20/connect-to-microsoft-graph-powershell-using-an-app-registration/

Remember to assign the Service Principal (SPN) the required Graph API Application permissions in Azure AD.

Side note:

There is the Add-AzAdAppPermission cmdlet, but, unfortunately, it appears this only works for AD applications as opposed to MSIs. I tried running it, but it errored, unable to find my ObjectID.

Update 2 (2 years later)

I've been asked to update this, but it was a long time ago and I am not 100% sure what I was trying to do, so please read the comments. Microsoft has done a lot of work to Microsoft.Graph PS module and I note one can now log in with a secret-based SPN.

I know MS documentation always shows -scopes, but to be honest, I don't get why I need to add "scopes". Surely it should be able to work out what permissions my user/SPN has. More often than not, I don't need to add any scopes. Maybe that's because I was a Global Admin on the tenant I was working on at the time.

鱼忆七猫命九 2025-02-20 20:34:04

要为多个(用户定义的)托管身份分配多个Graph API权限,我使用了以下脚本。它不取决于任何AZ-* PowerShell模块,而仅使用“ Microsoft.graph.applications” PS模块,该模块应在接下来的几年中得到支持。

    $tenantID = "12345678-1234-1234-1234-123456789abc"
    $graphAppId = "00000003-0000-0000-c000-000000000000"
    $permissions = @("User.Read.All", "Application.ReadWrite.All")
    $managedIdentities = @("mi-1", "mi-2", "mi-3") # Names of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource).
    Connect-MgGraph -TenantId $tenantID -NoWelcome -Scopes "AppRoleAssignment.ReadWrite.All", "Directory.Read.All"
    $sp = Get-MgServicePrincipal -Filter "appId eq '$graphAppId'"
    $managedIdentities | ForEach-Object {
        $msi = Get-MgServicePrincipal -Filter "displayName eq '$_'"
        $appRoles = $sp.AppRoles | Where-Object {($_.Value -in $permissions) -and ($_.AllowedMemberTypes -contains "Application")}
        $appRoles | ForEach-Object {
            $appRoleAssignment = @{
                "PrincipalId" = $msi.Id
                "ResourceId" = $sp.Id
                "AppRoleId" = $_.Id
            }
            New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appRoleAssignment.PrincipalId -BodyParameter $appRoleAssignment -Verbose
        }
    }
    Disconnect-MgGraph

此外,“ get-azadserviceprincipal”找不到托管身份(至少基于其显示名称)。

To assign multiple Graph APi permissions to multiple (user-defined) Managed Identities I used the following script. It does not depend on any Az-* Powershell Module, but solely uses the "Microsoft.Graph.Applications" PS Module which should be supported for the next few years.

    $tenantID = "12345678-1234-1234-1234-123456789abc"
    $graphAppId = "00000003-0000-0000-c000-000000000000"
    $permissions = @("User.Read.All", "Application.ReadWrite.All")
    $managedIdentities = @("mi-1", "mi-2", "mi-3") # Names of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource).
    Connect-MgGraph -TenantId $tenantID -NoWelcome -Scopes "AppRoleAssignment.ReadWrite.All", "Directory.Read.All"
    $sp = Get-MgServicePrincipal -Filter "appId eq '$graphAppId'"
    $managedIdentities | ForEach-Object {
        $msi = Get-MgServicePrincipal -Filter "displayName eq '$_'"
        $appRoles = $sp.AppRoles | Where-Object {($_.Value -in $permissions) -and ($_.AllowedMemberTypes -contains "Application")}
        $appRoles | ForEach-Object {
            $appRoleAssignment = @{
                "PrincipalId" = $msi.Id
                "ResourceId" = $sp.Id
                "AppRoleId" = $_.Id
            }
            New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $appRoleAssignment.PrincipalId -BodyParameter $appRoleAssignment -Verbose
        }
    }
    Disconnect-MgGraph

Furthermore the "Get-AzADServicePrincipal" does not find the managed identity (at least based on its displayName).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文