Forum Discussion
Get Bearer Token Via Power Query to Interrogate Power BI APIs
I would like to build a Power BI report based on data about my Power BI tenant via the Power BI APIs (unless of course there is another way to report directly on the tenant content...), and I can do this easily enough like this:
let
Token = [Authorization = "Bearer " & ManualToken],
API = Web.Contents("https://api.powerbi.com/v1.0/myorg/groups", [Headers=Token]),
ChangeResponseToRecord = Json.Document(Text.FromBinary(API)),
ConvertToTable = Table.FromList(ChangeResponseToRecord[value], Splitter.SplitByNothing(), {"Record"}, null, ExtraValues.Error),
ExpandColumn = Table.ExpandRecordColumn(ConvertToTable, "Record", {"id", "isReadOnly", "isOnDedicatedCapacity", "name"})
in
ExpandColumn
However what I cannot manage to get automatically is the "ManualToken". I can get a bearer token by going to https://docs.microsoft.com/en-us/rest/api/power-bi/groups/getgroups and clicking "Try It", and if I copy and paste that into my variable above it works fine, but I want an automated Power Query way to achieve this.
We have tried all sorts of combinations of App Registrations in Azure, and various authenication methods to get the token, and the results are:
The following successfully retrieves a bearer token:
let
BodyRecord = [grant_type = "client_credentials", resource = "<GUID Registered Application ID>", client_id = "<GUID Client Id>", client_secret = "<Client Secret>"],
Body = Uri.BuildQueryString(BodyRecord),
API = Web.Contents("https://login.microsoft.com/<Domain Name>.onmicrosoft.com/oauth2/token?api-version=1.0", [Content=Text.ToBinary(Body)]),
ChangeResponseToRecord = Json.Document(Text.FromBinary(API)),
GetAccessToken = ChangeResponseToRecord[access_token]
in
GetAccessToken
However that bearer token does not work with the Power BI APIs, even though the registered app has Microsoft Graph User.Read and all Power BI Service permissions.
The following successfully authenticates and calls the Power BI API:
# Install-Module -Name AzureRM.profile
$clientID = "<GUID Client Id>"
function GetAuthToken
{
if(-not (Get-Module AzureRm.Profile))
{
Import-Module AzureRm.Profile
}
$redirectUri = "urn:ietf:wg:oauth:2.0:oob"
$resourceAppIdURI = "https://analysis.windows.net/powerbi/api"
$authority = "https://login.microsoftonline.com/common/oauth2/authorize";
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
return $authResult
}
$token = GetAuthToken
Add-Type -AssemblyName System.Net.Http
# Building Rest API header with auth token
$auth_header = @{
'Content-Type'='application/json'
'Authorization'=$token.CreateAuthorizationHeader()
}
# Get groups as example:
$uri = "https://api.powerbi.com/v1.0/myorg/groups/"
$all_groups = (Invoke-RestMethod -Uri $uri –Headers $auth_header –Method GET).value
# output to terminal
write-output $all_groups
However we can see no way to convert this into Power Query.
I am open to any suggestions!
Thanks,
Joe
The only other approach I see then is to set up an Azure function which gets the auth for you.
3 Replies
- artemusMicrosoft Employee
The "easy" answer is to build your own connector which will give you access to the APIs to do this. However, you won't be able to do online refresh unless you get it certified.
- JoeEdwardsFrequent Visitor
Thanks, but ideally I would like to avoid building a custom connector, as it then has to be supported by my organisation.
A couple of points of clarity to help: I would like to access the Power BI APIs via Power BI Service Dataflows, and also I have to use multi factor authentication in our organisation.
Thanks,
Joe
- artemusMicrosoft Employee
The only other approach I see then is to set up an Azure function which gets the auth for you.