通过 PowerShell 访问 MS Graph API 的权限
Permissions to access to MS Graph API via PowerShell
问题
我正在尝试编写 PowerShell 脚本以通过 MS Graph API /reports/credentialUserRegistrationDetails
获取报告数据。
当我使用 Graph Explorer 它工作得很好,只要我在修改权限(预览)选项卡上启用 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"
}
}
}
When I use Graph Explorer it works just fine, as long as I enable
Reports.Read.All on the Modify permissions (Preview) tab.
这是因为 Microsoft Graph Explorer
是 Microsoft 的企业应用程序,它存在于每个 Azure AD 租户上,您只需要通过提供所需的权限来登录和使用它。
但是当您编写 运行 您的 Powershell 脚本时,它使用 Microsoft Azure Powershell
。您可以通过检查 JWT Token 中收到的 access_token
来验证它。因此,您需要向您的租户中具有 appid 的同一应用程序提供 Reports.Read.All
API 权限:1950a258-227b-4e31-a9cf-717495945fc2
在 Enterprise Application >> Permissions 中授予管理员同意。提供所需的权限后,它才会起作用。
另一种方法是创建应用程序注册,为其创建客户端密码,然后提供 Reports.Read.All
API 权限并使用以下脚本:
$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 可能无法从门户中看到,因此在这种情况下,请使用上述解决方案,它会更容易。
对于授权代码流程,尝试这样的事情-
#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
谢谢。
我终于放弃了使用 REST API,开始使用 Microsoft.Graph
PowerShell 模块。我发现文档非常稀疏,但至少它可以满足我的需要。 :)
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
问题
我正在尝试编写 PowerShell 脚本以通过 MS Graph API /reports/credentialUserRegistrationDetails
获取报告数据。
当我使用 Graph Explorer 它工作得很好,只要我在修改权限(预览)选项卡上启用 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"
}
}
}
When I use Graph Explorer it works just fine, as long as I enable Reports.Read.All on the Modify permissions (Preview) tab.
这是因为 Microsoft Graph Explorer
是 Microsoft 的企业应用程序,它存在于每个 Azure AD 租户上,您只需要通过提供所需的权限来登录和使用它。
但是当您编写 运行 您的 Powershell 脚本时,它使用 Microsoft Azure Powershell
。您可以通过检查 JWT Token 中收到的 access_token
来验证它。因此,您需要向您的租户中具有 appid 的同一应用程序提供 Reports.Read.All
API 权限:1950a258-227b-4e31-a9cf-717495945fc2
在 Enterprise Application >> Permissions 中授予管理员同意。提供所需的权限后,它才会起作用。
另一种方法是创建应用程序注册,为其创建客户端密码,然后提供 Reports.Read.All
API 权限并使用以下脚本:
$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 可能无法从门户中看到,因此在这种情况下,请使用上述解决方案,它会更容易。
对于授权代码流程,尝试这样的事情-
#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
谢谢。
我终于放弃了使用 REST API,开始使用 Microsoft.Graph
PowerShell 模块。我发现文档非常稀疏,但至少它可以满足我的需要。 :)
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