Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.
Register now!The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more
My end goal is to find all RLS setting used in a Power BI Dataset and to see which AD groups have been connected to these roles. To do this, I have followed the GetScanResult API, and have implemented this in a PySpark Notebook inside of Azure Synapse.
According to this page, there should be a dictionary with the key "Roles", but in my response of the API there is no such field. This is what I am looking for:
Goal output:
......
"roles": [
{
"name": "Teams",
"modelPermission": "Read",
"members": [
{
"memberName": "john@contoso.com",
"memberId": "ee96296b-fb71-4f65-a8af-c0ec5a7daced",
"memberType": "User",
"identityProvider": "AzureAD"
},
{
"memberName": "group@contoso.com",
"memberId": "0a1cdbc3-f82c-4001-8b96-be04ae9d25a3",
"memberType": "Group",
"identityProvider": "AzureAD"
}
],
"tablePermissions": [
{
"name": "DW_Revenues DW_RevenuesTest",
"filterExpression": "[InTeams] = \"True\""
}
]
}
],
......
However, this is the entire response I get (when I select one of the datasets that the API call):
[
{
"id":"--------------",
"name":"--------------",
"tables":[
],
"configuredBy":"--------------",
"configuredById":"--------------",
"isEffectiveIdentityRequired":true,
"isEffectiveIdentityRolesRequired":true,
"refreshSchedule":{
"days":[
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"times":[
"01:00",
"08:00",
"09:00",
"10:00",
"11:00",
"13:00",
"14:00",
"15:00",
"16:00",
"17:00"
],
"enabled":true,
"localTimeZoneId":"Romance Standard Time",
"notifyOption":"NoNotification"
},
"targetStorageMode":"PremiumFiles",
"createdDate":"2022-12-08T12:22:43.013",
"contentProviderType":"PbixInImportMode"
}
]
As can be seen, the "Tables" dictionary only contains an empty list (which is different from the example output of GetScanResult), but also the "Roles" field is missing.
Things I have tried:
1. Checked the tenant settings to ensure metadata scanning has been enabled (info), I was hoping the settings were turned off and causing this issue, but they were turned on
2. Specified parameters in the getInfo Post API call:
def initiate_scan(aad_token, workspaces):
url = 'https://api.powerbi.com/v1.0/myorg/admin/workspaces/getInfo'
headers = {
'Authorization': f'Bearer {aad_token}',
'Content-Type': 'application/json'
}
body = {
"workspaces": workspaces,
"datasetExpressions": True,
"datasetSchema": True,
"datasourceDetails": True,
"getArtifactUsers": True,
"lineage": True
}
response = requests.post(url, headers=headers, json=body)
if response.status_code == 202:
scan_id = response.json().get('id')
print(f'Scan initiated successfully. Scan ID: {scan_id}, workspaceIDs = {body["workspaces"]} ')
return scan_id
else:
print(f'Failed to initiate scan: {response.status_code}, {response.text}')
return None
3. Tried a different API Call looking something like this: 'https://api.powerbi.com/v1.0/myorg/admin/datasets/{dataset_id}, this results in:
Failed to get dataset info: 404, {"error":{"code":"ItemNotFound","message":"Dataset abcde-12345-12345-abcde is not found."}}.
Additional Information
1. I am using an AAD token which I obtain in the following way:
def get_AAD_token(tenant_id, client_id, client_secret, resource):
token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/token"
data = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'resource': resource
}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.post(token_url, data=data, headers=headers)
if response.status_code == 200:
json_response = response.json()
aad_token = json_response['access_token']
print('Bearer token was obtained successfully')
return aad_token
else:
print(f'Failed to obtain bearer token: {response.status_code}, {response.text}')
return None
2. I am a noob when it comes to Permissions and rights granted via Azure Synapse and this universe in general
3. I think it has something to do with rights, since in the example output there is info about tables and roles
4. I have checked this page
4.1 I have checked this page
5. I have read to wait a bit between starting the scan and reading the scan, I check for the status to be "Succeeded" before getting the results.
6. I Have ensured roles have been set for the dataset I am checking
7. In short, this is my code:
def initiate_scan(aad_token, workspaces):
url = 'https://api.powerbi.com/v1.0/myorg/admin/workspaces/getInfo'
headers = {
'Authorization': f'Bearer {aad_token}',
'Content-Type': 'application/json'
}
body = {
"workspaces": workspaces,
"datasetExpressions": True,
"datasetSchema": True,
"datasourceDetails": True,
"getArtifactUsers": True,
"lineage": True
}
response = requests.post(url, headers=headers, json=body)
if response.status_code == 202:
scan_id = response.json().get('id')
print(f'Scan initiated successfully. Scan ID: {scan_id}, workspaceIDs = {body["workspaces"]} ')
return scan_id
else:
print(f'Failed to initiate scan: {response.status_code}, {response.text}')
return None
def check_scan_status(aad_token, scan_id):
url = f'https://api.powerbi.com/v1.0/myorg/admin/workspaces/scanStatus/{scan_id}'
headers = {
'Authorization': f'Bearer {aad_token}',
'Content-Type': 'application/json'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
status_info = response.json()
status = status_info.get('status')
print(f'Scan status: {status}')
return status, status_info
else:
print(f'Failed to check scan status: {response.status_code}, {response.text}')
return None, None
def get_scan_result(aad_token, scan_id):
print(f"collecting results for scan {scan_id}")
url = f'https://api.powerbi.com/v1.0/myorg/admin/workspaces/scanResult/{scan_id}'
headers = {
'Authorization': f'Bearer {aad_token}',
'Content-Type': 'application/json'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
scan_result = response.json()
print('Scan result retrieved successfully')
return scan_result
elif response.status_code == 404:
print(f'Scan result not found. The scan may have expired or the ID is invalid: {response.text}')
return None
else:
print(f'Failed to get scan result: {response.status_code}, {response.text}')
return None
Any help is greatly appreciated
Hi @Anonymous ,
Regarding your use of this Power BI admin API you will also encounter the specific 404 error status code "404, {"error":{"code": "ItemNotFound", "message": "Dataset abcde-12345-12345-abcde is not found."}}." At your convenience, can you verify that the account you generated and used the AAD token for has access to the dataset ID "abcde-12345-12345-abcde"? You can also consider using service principal authentication to execute this API, provided that you also meet the prerequisites of the API for service principals in the documentation.
Admin - Datasets GetDatasetsAsAdmin - REST API (Power BI Power BI REST APIs) | Microsoft Learn
Best Regards,
Liu Yang
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.
The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!
| User | Count |
|---|---|
| 4 | |
| 3 | |
| 2 | |
| 2 | |
| 1 |
| User | Count |
|---|---|
| 4 | |
| 4 | |
| 4 | |
| 3 | |
| 3 |