Forum Discussion

stribor45's avatar
stribor45
Icon for Post Prodigy rankPost Prodigy
6 months ago
Solved

Phasing out the report

I’m trying to retire a report that is currently published in our workspace. When I check Manage permissions, I can see that several users have access either through direct access or shareable links (dlinks).

Is there a way to notify all of these users that the report will be phased out?

I considered emailing them, but gathering all the names from the links section and the direct access list is time‑consuming, and those entries only show first and last names without email addresses.

As an administrator in a Premium workspace, is there a more efficient way to handle this?

I’m also considering placing a text box directly on the report with a message and a specific date indicating when the report will be deleted. Is this approach acceptable or recommended?

  • Hi stribor45 , 

    Yes, we can put a banner in the report as a notification stating that this report will be retired and provide the link to the new report.

    To get the list of users, we can directly hit the REST API to retrieve users from the semantic model's manage permissions, as this is managed at the semantic model level, not the report level.

    import msal
    import requests
    import csv
    
    
    # Creds
    CLIENT_ID ='abc'
    CLIENT_SECRET = 'abc'
    TENANT_ID = 'abc'
    
    WORKSPACE_ID ='abc'
    DATASET_ID = 'abc''
    
    AUTHORITY_URL = f"https://login.microsoftonline.com/{TENANT_ID}"
    SCOPE = ["https://analysis.windows.net/powerbi/api/.default"]
    
    # Bearer token
    def get_access_token():
        app = msal.ConfidentialClientApplication(
            CLIENT_ID,
            authority=AUTHORITY_URL,
            client_credential=CLIENT_SECRET
        )
    
        result = app.acquire_token_for_client(scopes=SCOPE)
    
        if "access_token" in result:
            return result["access_token"]
        else:
            raise Exception(f"Token Error: {result.get('error_description')}")
    
    # Get users
    def get_dataset_users(access_token):
        url = f"https://api.powerbi.com/v1.0/myorg/groups/{WORKSPACE_ID}/datasets/{DATASET_ID}/users"
    
        headers = {
            "Authorization": f"Bearer {access_token}"
        }
    
        users = []
    
        while url:
            response = requests.get(url, headers=headers, timeout=30)
    
            if response.status_code != 200:
                raise Exception(f"API Error {response.status_code}: {response.text}")
    
            data = response.json()
            users.extend(data.get("value", []))
    
            # Handle pagination
            url = data.get("@odata.nextLink")
    
        return users
    
    # check access
    try:
        print("Authenticating...")
        token = get_access_token()
    
        print("Fetching semantic model users...")
        users = get_dataset_users(token)
    
        print("\n--- Users with Direct Access to Semantic Model ---\n")
    
        for user in users:
            print(
                f"Identifier: {user.get('identifier')} | "
                f"Principal Type: {user.get('principalType')} | "
                f"Access Right: {user.get('datasetUserAccessRight')}"
            )
    
    except Exception as e:
        print(f"Error: {e}")

     
    Thanks 

    If this response was helpful in any way, I’d gladly accept a kudo.
    Please mark it as the correct solution. It helps other community members find their way faster

5 Replies

  • Hi stribor45 , 

    Yes, we can put a banner in the report as a notification stating that this report will be retired and provide the link to the new report.

    To get the list of users, we can directly hit the REST API to retrieve users from the semantic model's manage permissions, as this is managed at the semantic model level, not the report level.

    import msal
    import requests
    import csv
    
    
    # Creds
    CLIENT_ID ='abc'
    CLIENT_SECRET = 'abc'
    TENANT_ID = 'abc'
    
    WORKSPACE_ID ='abc'
    DATASET_ID = 'abc''
    
    AUTHORITY_URL = f"https://login.microsoftonline.com/{TENANT_ID}"
    SCOPE = ["https://analysis.windows.net/powerbi/api/.default"]
    
    # Bearer token
    def get_access_token():
        app = msal.ConfidentialClientApplication(
            CLIENT_ID,
            authority=AUTHORITY_URL,
            client_credential=CLIENT_SECRET
        )
    
        result = app.acquire_token_for_client(scopes=SCOPE)
    
        if "access_token" in result:
            return result["access_token"]
        else:
            raise Exception(f"Token Error: {result.get('error_description')}")
    
    # Get users
    def get_dataset_users(access_token):
        url = f"https://api.powerbi.com/v1.0/myorg/groups/{WORKSPACE_ID}/datasets/{DATASET_ID}/users"
    
        headers = {
            "Authorization": f"Bearer {access_token}"
        }
    
        users = []
    
        while url:
            response = requests.get(url, headers=headers, timeout=30)
    
            if response.status_code != 200:
                raise Exception(f"API Error {response.status_code}: {response.text}")
    
            data = response.json()
            users.extend(data.get("value", []))
    
            # Handle pagination
            url = data.get("@odata.nextLink")
    
        return users
    
    # check access
    try:
        print("Authenticating...")
        token = get_access_token()
    
        print("Fetching semantic model users...")
        users = get_dataset_users(token)
    
        print("\n--- Users with Direct Access to Semantic Model ---\n")
    
        for user in users:
            print(
                f"Identifier: {user.get('identifier')} | "
                f"Principal Type: {user.get('principalType')} | "
                f"Access Right: {user.get('datasetUserAccessRight')}"
            )
    
    except Exception as e:
        print(f"Error: {e}")

     
    Thanks 

    If this response was helpful in any way, I’d gladly accept a kudo.
    Please mark it as the correct solution. It helps other community members find their way faster

    • stribor45's avatar
      stribor45
      Icon for Post Prodigy rankPost Prodigy

      Would this get all the users regardless whether link or direct access? Also I am, not sure I have this 

      CLIENT_SECRET = 'abc'