Azure

Power BI API Connector (sample application)

PowerBIApiConnector is a simple console application that will help you to test two things: a connection to Azure Active Directory and that you have properly configured an Azure application to access the Power BI Admin Read-Only API.

Application is created in .NET.Core 5.0 and you can download it as:

How to use it?

Extract the executable package files to a directory. You have two options how to launch the application:

A) Setup parameters at the application launch:

PowerBIApiConnector.exe {Application (client) ID} {Directory (tenant) ID} {Client Secret}

B) Execute it without parameters. Then you will be prompted for input values:

Input parameters are:

  • Application (client) ID: This is an Azure Application ID
  • Directory (tenant) ID: Your organization (tenant) ID
  • Client Secret: Application secret value

You can get proper values for these parameters in Azure Portal: Navigate to your Application in Azure Active Directory and copy the first two parameters from the Application Overview page:

For the Client Secret navigate as in the image below and copy the Value or create a new secret:

When you launch the application and authentication to Azure AD will succeed, you will see an authentication token printed to the console window:

Same time you will be prompted if you would like to test the Power BI Admin Read-Only API access. You can skip this step in case you would like to test the Azure AD authentication only.

If you will input “Y” the GetGroupsAsAdmin() API call will be executed and when the application has properly configured access to the Power BI Admin API available tenant workspaces will be listed by name:

Solution content

Two dependency packages are required (will be automatically downloaded via NuGet packages manager):

Main method code:

using Microsoft.Identity.Client;
using Microsoft.PowerBI.Api;
using Microsoft.Rest;
using System.Linq;
using System;

namespace PowerBIApiConnector
{
    class Program
    {

        static PowerBIClient powerBIClient = null;
        static string accesToken = null;
        static IConfidentialClientApplication app;

        // Authentication variables
        private static string clientId;
        private static string tenantId;
        private static string clientSecret;

        // Power BI API paths
        private const string resource = "https://analysis.windows.net/powerbi/api";
        private const string ApiUrl = "https://api.powerbi.com";

        private static string authority;

        public static void Main(string[] args)
        {
            // Capture users input via prompt
            if (args.Count() == 0)
            {
                Console.WriteLine("Application (client) ID:");
                clientId = Console.ReadLine();

                Console.WriteLine("Directory (tenant) ID:");
                tenantId = Console.ReadLine();

                Console.WriteLine("Client Secret:");
                clientSecret = Console.ReadLine();
            }
            // Capture users input as launch parameters
            else if (args.Count() == 3)
            {
                clientId = args[0];
                tenantId = args[1];
                clientSecret = args[2];

                Console.WriteLine("------------------------");
                Console.WriteLine($"Application (client) ID: {clientId}");
                Console.WriteLine($"Directory (tenant) ID: {tenantId}");
                Console.WriteLine($"Client Secret: {clientSecret}");
                Console.WriteLine("------------------------");
            }
            else
            {
                Console.WriteLine("Mssing valid input parameters! Type: {Application (client) ID} {Directory (tenant) ID} {Client Secret} ");
            }

            // Set main API path for authentication
            authority = $"https://login.microsoftonline.com/{tenantId}";

            // Create authorization app
            try
            {
                app = ConfidentialClientApplicationBuilder
                    .Create(clientId)
                    .WithClientSecret(clientSecret)
                    .WithAuthority(new Uri(authority))
                    .Build();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Environment.Exit(1);
            }

            string[] scopes = new string[] { $"{resource}/.default" };
            AuthenticationResult result = null;

            // Authenticate and obtain permissions scope
            try
            {
                result = app.AcquireTokenForClient(scopes).ExecuteAsync().Result;
            }
            catch (MsalUiRequiredException ex)
            {
                // Insufficient permissions.
                Console.WriteLine(ex.Message);
                Environment.Exit(1);
            }
            catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
            {
                // Invalid application scope.
                Console.WriteLine(ex.Message);
                Environment.Exit(1);
            }

            // Print token
            Console.WriteLine($"App-Only Access Token:\n{result.AccessToken}\n");
            
            accesToken = result.AccessToken;
            var tokenCredentials = new TokenCredentials(result.AccessToken, "Bearer");
            
            // Test PowerBI Admin API
            Console.WriteLine("Test Power BI API (List workspaces as service principal via Read-Only Admin Api?) Type Y/N:");

            if ("y" == Console.ReadLine().ToLower())
            {
                Console.WriteLine("------------------------");
                Console.WriteLine("Connecting to Power BI API...");

                try
                {
                    // Create PowerBIClient instance
                    powerBIClient = new PowerBIClient(new Uri(ApiUrl), tokenCredentials);

                    // List workspace names with the Admin only method (GetGroupsAsAdmin)
                    var workspaceNames = powerBIClient.Groups.GetGroupsAsAdmin(100, filter: "type eq 'Workspace'").Value.Select(x => x.Name);

                    //Print output
                    Console.WriteLine("Workspaces found:");

                    foreach (string workspaceName in workspaceNames)
                    {
                        Console.WriteLine("  => " + workspaceName);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Environment.Exit(1);
                }
            }

            Console.WriteLine("Done!");

        }
    }
}

References

For additional references, I will recommend this excellent video from Marco Russo and the official Microsoft guide.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *