Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Power BI Admin API issues

Hi there

 

I am attempting to use the newly released Admin features in the Power BI API but have come across a number of issues:

 

  • When I attempt to get the users belonging to the admin groups, the user list is always blank, irrespective of which group I query. I am using the expand=users request
  • When I iterate through all the admin groups and attempt to retrieve all the dashboards within the groups, I receive an Unauthorized error when I attempt to query the dashboards in a group that my account is not a member of, even though the account I am using is a Power BI admin in Office 365

 

The app I have registered in Azure has all the Power BI permissions possible (Screenshot below)

 

Azure Access.png

 

Please let me know if you require any other information. I can provide the sample Powershell script I am using if required

Status: Accepted
Comments
v-jiascu-msft
Microsoft Employee

Hi @kirby,

 

Could you please tell me which APIs exactly? We have to use right APIs to get right results. You can find the official names here.

 

Best Regards,

Dale

Vicky_Song
Impactful Individual
Status changed to: Needs Info
 
kirby
Frequent Visitor

Hi Dale

 

I am using the Admin API. Below is the body of the Powershell script I am using

 

----------------------------------------------

 

function GetAuthToken
{
[CmdletBinding()]
param([Parameter(Position=0, Mandatory=$true, ValueFromPipeline = $true)] [string]$ClientId,
[Parameter(Position=1, Mandatory=$true, ValueFromPipeline = $true)] [string]$Username,
[Parameter(Position=2, Mandatory=$true, ValueFromPipeline = $true)] [string]$Password
)

$adal = "D:\Deployments\Powershell Scripts\Libraries\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"

[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null

$redirectUri = "https://login.live.com/oauth20_desktop.srf"

$resourceAppIdURI = "https://analysis.windows.net/powerbi/api"

$authority = "https://login.windows.net/common/oauth2/authorize";

$creds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" -ArgumentList $Username,$Password

$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority

$authResult = $authContext.AcquireToken($resourceAppIdURI, $ClientId, $creds)

return $authResult
}

 

$startDateTime = Get-Date
# Get the username and password from the SQL Credential
Write-Output "Getting Credential `"$SQLCredentialName`" from secure string ..."
$SQLCredential = Get-StoredCredential -UserName $SQLCredentialName
$SQLUsername = $SQLCredential.UserName
$SQLPassword = $SQLCredential.GetNetworkCredential().Password

# Get the username and password from the Office 365 credential
Write-Output "Getting Credential `"$CredentialName`" from secure string ..."
$Credential = Get-StoredCredential -UserName $CredentialName
$pbiUsername = $Credential.UserName
$pbiPassword = $Credential.GetNetworkCredential().Password

if ($Credential -eq $null)
{
throw "Could not retrieve credential assets."
}

Write-Output "Done!"

Write-Output "Get the auth token from AAD"
$token = GetAuthToken -ClientId $clientId -Username $pbiUsername -Password $pbiPassword

Write-Output "Done!"

Write-Output "Building Rest API header with authorization token"

$headers = @{
'Content-Type'='application/json'
'Authorization'=$token.CreateAuthorizationHeader()
}

Write-Output "Done!"

Write-Output "Iterating through groups ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/groups"
$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$groups = ConvertFrom-Json $restResponse
$groups = $groups.value | Select @{N="GroupID";E={$_.id}}, @{N="GroupName";E={$_.name}}, @{N="ReadOnlyIndicator";E={$_.isReadOnly}}, @{N="OnDedicatedCapacityIndicator";E={$_.isOnDedicatedCapacity}}, @{N="CapacityID";E={$_.CapacityId}} | Out-DataTable

Write-Output "Establish SQL Azure connection ..."

$connectionString = "server=$SQLInstance" + "; uid=" + $SQLUsername + "; pwd=" + $SQLPassword + "; database=" + $SQLDatabase
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$connection.Open()

$dashboardCollection = New-Object System.Data.DataTable
$tileCollection = New-Object System.Data.DataTable
$reportCollection = New-Object System.Data.DataTable
$dataSetCollection = New-Object System.Data.DataTable
$datasourceCollection = New-Object System.Data.DataTable

foreach($group in $groups)
{
$groupName = $group.GroupName
$groupId = $group.GroupID

if ($groupName -ne "")
{

Write-Output "Iterating through objects for group $groupName ..."
Write-Output "Get the dashboards for group $groupName ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/groups/$groupId/dashboards"
$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$dashboards = ConvertFrom-Json $restResponse
$dashboards = $dashboards.value | Select @{N="DashboardID";E={$_.id}}, @{N="GroupID";E={$groupId}}, @{N="DashboardName";E={$_.displayName}}, @{N="ReadOnlyIndicator";E={$_.isReadOnly}}, @{N="EmbedURL";E={$_.embedUrl}} | Out-DataTable
$dashboardCollection.Merge($dashboards)

foreach($dashboard in $dashboards)
{
$dashboardName = $dashboard.DashboardName
$dashboardID = $dashboard.DashboardID

Write-Output "Get the tiles for dashboard $dashboardName for group $groupName ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/dashboards/$dashboardID/tiles"
$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$tiles = ConvertFrom-Json $restResponse
$tiles = $tiles.value | Select @{N="TileID";E={$_.id}}, @{N="DashboardID";E={$dashboardID}}, @{N="ReportID";E={$_.reportId}}, @{N="DatasetID";E={$_.datasetId}}, @{N="TileName";E={$_.title}}, @{N="TileSubName";E={$_.subTitle}}, @{N="EmbedURL";E={$_.embedUrl}}, @{N="RowSpan";E={$_.rowSpan}}, @{N="ColSpan";E={$_.colSpan}} | Out-DataTable
$tileCollection.Merge($tiles)
}

Write-Output "Get the reports for group $groupName ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/groups/$groupId/reports"
$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$reports = ConvertFrom-Json $restResponse
$reports = $reports.value | Select @{N="ReportID";E={$_.id}}, @{N="GroupID";E={$groupId}}, @{N="DataSetID";E={$_.datasetId}}, @{N="ReportName";E={$_.name}}, @{N="ModelID";E={$_.modelId}}, @{N="WebURL";E={$_.webUrl}}, @{N="EmbedURL";E={$_.embedUrl}}, @{N="OwnedByMeIndicator";E={$_.isOwnedByMe}}, @{N="OriginalPbixReportIndicator";E={$_.isOriginalPbixReport}} | Out-DataTable
$reportCollection.Merge($reports)

Write-Output "Get the datasets for group $groupName ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/groups/$groupId/datasets"
$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$dataSets = ConvertFrom-Json $restResponse
$dataSets = $dataSets.value | Select @{N="DatasetID";E={$_.id}}, @{N="GroupID";E={$groupId}}, @{N="DatasetName";E={$_.name}}, @{N="AddRowsAPIEnabledIndicator";E={$_.addRowsAPIEnabled}}, @{N="ConfiguredBy";E={$_.configuredBy}}, @{N="RefreshableIndicator";E={$_.isRefreshable}}, @{N="EffectiveIdentityRequiredIndicator";E={$_.isEffectiveIdentityRequired}}, @{N="EffectiveIdentityRolesRequiredIndicator";E={$_.isEffectiveIdentityRolesRequired}}, @{N="OnPremGatewayRequiredIndicator";E={$_.isOnPremGatewayRequired}} | Out-DataTable
$dataSetCollection.Merge($dataSets)

foreach($dataset in $dataSets)
{
$dataSetName = $dataset.DatasetName
$dataSetID = $dataSet.DatasetID

Write-Output "Get the datasources for dataset $dataSetName ..."

$restURL = "https://api.powerbi.com/v1.0/myorg/admin/datasets/$dataSetID/datasources"

$ErrorActionPreference = "SilentlyContinue"

$restResponse = Invoke-RestMethod -Uri $restURL -Method GET -Headers $headers | select value | ConvertTo-Json

$dataSources = ConvertFrom-Json $restResponse
$dataSources = $dataSources.value | Select @{N="DatasetID";E={$dataSetID}}, @{N="DatasourceName";E={$_.name}}, @{N="ConnectionString";E={$_.connectionString}}, @{N="DatasourceType";E={$_.datasourceType}}, @{N="Connection";E={$_.connectionDetails.Replace("@", "").Replace("{", "{""").Replace("=", """:""").Replace("; ", """,""").Replace("}", """}").Replace("\", "\\")}} | Out-DataTable
$datasourceCollection.Merge($dataSources)

$ErrorActionPreference = "Stop"
}
}
}

 

---------------------------------------------

v-jiascu-msft
Microsoft Employee

Hi @kirby,

 

Regarding to the issue 1, you didn't use any API to get users in your code. 

Regarding to the issue 2, I have reported it to the Product Team: CRI 75683447. I will update here later.

 

Best Regards,

Dale

Vicky_Song
Impactful Individual
Status changed to: Accepted
 
AlexR
Frequent Visitor

Hello,

I was also experiencing some issues with the Admin API, on top of the list of users being empty for all groups when expending the users for the API
https://api.powerbi.com/v1.0/myorg/admin/groups?$expand=users

 

My user has O365 Admin rights and all permissions are granted for the Azure Application, both for the Power BI and Azure AD services.

 

Another issue is related to the Groups for AddUserAsAdmin.
When trying to add a user to a group as admin (using the API POST https://api.powerbi.com/v1.0/myorg/admin/groups/{0}/users), the server returns 500 Internal Server Error:
{"error":{"code":"UnknownError","pbi.error":{"code":"UnknownError","parameters":{},"details":[]}}}
The same operation works fine when using the "not Admin" API (https://api.powerbi.com/v1.0/myorg/groups/{0}/users) if I'm a member of the workspace 

 

Please let me know if you require more details about this issue.
Best regards,
Alex