0

问题

我正在尝试编写一个 PowerShell 脚本来通过 MS Graph API 获取报告数据/reports/credentialUserRegistrationDetails。当我使用图形资源管理器时,它工作得很好,只要我Reports.Read.All在修改权限(预览)选项卡上启用。

但是,当我尝试用我的脚本来做这件事时,我得到了错误"Calling principal does not have required MSGraph permissions Reports.Read.All"

在我所有的搜索中,我只能找到如何为应用分配权限。有什么办法可以让我从我的脚本中做到这一点?


我的脚本

$azContext = Get-AzContext
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate(
    $azContext.Account,
    $azContext.Environment,
    $azContext.Tenant.Id,
    $null,
    [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never,
    $null,
    "https://graph.microsoft.com"
)

$params = @{
    Method  = "GET"
    Uri     = "https://graph.microsoft.com/beta/reports/credentialUserRegistrationDetails"
    Headers = @{
        Authorization  = "Bearer $($token.AccessToken)"
        "Content-Type" = "application/json"
    }
}
Invoke-RestMethod @params

回复

{
  "error": {
    "code":"Authentication_MSGraphPermissionMissing",
    "message":"Calling principal does not have required MSGraph permissions Reports.Read.All",
    "innerError": {
      "date":"2021-10-19T01:18:36",
       "request-id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
       "client-request-id":"6b8cc3a3-b93b-44bb-b1d4-190c618aa52a"
    }
  }
}
4

3 回答 3

0

当我使用图形资源管理器时,它工作得很好,只要我在修改权限(预览)选项卡上启用 Reports.Read.All。

因为它Microsoft Graph Explorer是 Microsoft 的企业应用程序,它存在于每个 Azure AD 租户中,您只需登录并通过提供所需的权限来使用它。

但是,当您编写运行 Powershell 脚本时,它使用Microsoft Azure Powershell. 您可以通过检查access_token收到的JWT 令牌来验证它。因此,您需要Reports.Read.All使用 appid 向租户中的同一应用程序提供 API 权限:1950a258-227b-4e31-a9cf-717495945fc2在 Enterprise Application >> Permissions 中并授予管理员同意。仅提供所需的权限后将工作。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述


另一种方法是创建一个应用程序注册,为其创建一个客户端密码,然后提供Reports.Read.AllAPI 权限并使用以下脚本:

$TenantName = "tenantname.onmicrosoft.com"
$clientID = "d344e3xxx-xxx-xxxx-xxxx-9c861d363244" # app registration clientId
$clientSecret = "fNc7Q~UNHBgv_xxxxxxxxxxxxxxxxxxxxxx-PD"
$Scope = "https://graph.microsoft.com/.default"
 
$Body = @{
    Grant_Type = "client_credentials"
    Scope = $Scope
    client_Id = $clientID
    Client_Secret = $clientSecret
}
$authUri = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
  
$TokenResponse = Invoke-RestMethod -Uri $authUri -Method POST -Body $Body

$Headers = @{
        "Authorization" = "Bearer $($TokenResponse.access_token)"
        "Content-type"  = "application/json"
    }
$apiUri = "https://graph.microsoft.com/beta/reports/credentialUserRegistrationDetails"
$response = Invoke-RestMethod -Headers $Headers -Uri $apiUri -Method GET
 
$response.value

输出:

在此处输入图像描述

注意:在某些租户中,Microsoft Azure PowerShell 可能无法从门户中看到,因此在这种情况下,请使用上述解决方案,这样会更容易。

于 2021-10-19T09:13:14.830 回答
0

对于授权代码流,请尝试以下操作 -

#region Auth1
#With User Interaction for Delegated Permission
Add-Type -AssemblyName System.Web

Function Get-AuthCode {
    Add-Type -AssemblyName System.Windows.Forms

    $form = New-Object -TypeName System.Windows.Forms.Form -Property @{Width = 440; Height = 640 }
    $web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{Width = 420; Height = 600; Url = ($url -f ($Scope -join "%20")) }

    $DocComp = {
        $Global:uri = $web.Url.AbsoluteUri        
        if ($Global:uri -match "error=[^&]*|code=[^&]*") { $form.Close() }
    }
    $web.ScriptErrorsSuppressed = $true
    $web.Add_DocumentCompleted($DocComp)
    $form.Controls.Add($web)
    $form.Add_Shown( { $form.Activate() })
    $form.ShowDialog() | Out-Null

    $queryOutput = [System.Web.HttpUtility]::ParseQueryString($web.Url.Query)
    $output = @{}
    foreach ($key in $queryOutput.Keys) {
        $output["$key"] = $queryOutput[$key]
    }

    #$output
}

Get-AuthCode
#Extract Access token from the returned URI
$regex = '(?<=code=)(.*)(?=&)'
$authCode = ($uri | Select-string -pattern $regex).Matches[0].Value

Write-output "Received an authCode, $authCode"

$tokenBody = @{  
    Grant_Type    = "authorization_code"  
    Scope         = "https://graph.microsoft.com/.default"  
    Client_Id     = $clientId  
    Client_Secret = $clientSecret
    redirect_uri  = $redirectUri
    code          = $authCode
    ressource     = $resource
}   

$tokenResponse = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -ErrorAction STOP

#endregion Auth1

对于委派权限,请使用以下内容 -

$tokenBody = @{  
    Grant_Type = "password"  
    Scope      = "user.read%20openid%20profile%20offline_access"  
    Client_Id  = $clientId  
    username   =  $User
    password   = $pw
    resource  = $resource
}   

$tokenResponse = Invoke-RestMethod https://login.microsoftonline.com/common/oauth2/token -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -ErrorAction STOP

#endregion Auth2

对于应用程序权限(使用客户端凭据流)使用类似这样的东西

$tokenBody = @{  
    Grant_Type    = "client_credentials"  
    Scope         = "https://graph.microsoft.com/.default"  
    Client_Id     = $clientId  
    Client_Secret = $clientSecret  
}   

$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$Tenantid/oauth2/v2.0/token" -Method POST -Body $tokenBody  


#endregion Auth3

不管您选择了哪种方法,tokenRepsonse 变量都持有我们针对 Microsoft GRAPH API 进行查询的密钥。

我们想要一个我们租户中所有团队的列表,所以这需要适当的应用程序权限。因此,例如 - 我们的 Powershell 获得所有团队的完整列​​表如下所示 -

$headers = @{
        "Authorization" = "Bearer $($tokenResponse.access_token)"
        "Content-type"  = "application/json"
    }

$URL = "https://graph.microsoft.com/beta/groups?`$filter=resourceProvisioningOptions/Any(x:x eq 'Team')"  
$AllTeams = (Invoke-RestMethod -Headers $headers -Uri $URL -Method GET).value 

谢谢。

于 2021-10-19T11:17:38.780 回答
0

我最终放弃了使用 REST API 并开始使用Microsoft.GraphPowerShell 模块。我发现文档很少,但至少它适用于我需要的东西。:)

Import-Module "Microsoft.Graph.Identity.Signins"
Import-Module "Microsoft.Graph.Users"
Import-Module "Microsoft.Graph.Groups"
Connect-MgGraph -TenantId $TenantId  -Scopes "Directory.Read.All", "UserAuthenticationMethod.Read.All" -ForceRefresh
Select-MgProfile -Name "beta"

$report = Get-MgReportCredentialUserRegistrationDetail
于 2021-10-21T15:48:41.237 回答