<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C# &#8211; SQLpowered.com</title>
	<atom:link href="https://sqlpowered.com/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>https://sqlpowered.com</link>
	<description>SQL Server + BI</description>
	<lastBuildDate>Wed, 15 Dec 2021 12:03:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://sqlpowered.com/wp-content/uploads/2020/07/FavIcon-e1594067873682-99x100.png</url>
	<title>C# &#8211; SQLpowered.com</title>
	<link>https://sqlpowered.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Getting Tabular Object Model from Power BI XMLA Endpoint</title>
		<link>https://sqlpowered.com/getting-tabular-object-model-from-power-bi-xmla-endpoint/</link>
					<comments>https://sqlpowered.com/getting-tabular-object-model-from-power-bi-xmla-endpoint/#respond</comments>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Sun, 11 Apr 2021 11:08:50 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Power BI]]></category>
		<guid isPermaLink="false">https://sqlpowered.com/?p=5158</guid>

					<description><![CDATA[It&#8217;s very easy to get TOM (Tabular Object Model) for datasets hosted in Power BI Service and extract various metadata from it (tables, measures, etc.). We will do it just now using a simple C# console application and download TOM for one sample dataset using Power BI User credentials. Similarly,...]]></description>
										<content:encoded><![CDATA[<p>It&#8217;s very easy to get TOM (<a href="https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions" target="_blank" rel="noopener">Tabular Object Model</a>) for datasets hosted in Power BI Service and extract various metadata from it (tables, measures, etc.). We will do it just now using a simple C# console application and download TOM for one sample dataset using Power BI User credentials. Similarly, you can do that as Service Principal.</p>
<p>Let&#8217;s set up a few prerequisites first.</p>
<h3>1. Setting the Power BI Tenant</h3>
<p><strong>Note</strong>: If you don&#8217;t have a Power BI account with administrative rights then use this <a href="https://sqlpowered.com/create-a-new-power-bi-administrator/" target="_blank" rel="noopener">guide</a> to create one.</p>
<p>Login to your Power BI account with administrative privileges and in Admin Portal make sure you have enabled access to XMLA endpoints for your tenant in Power BI Admin Portal.</p>
<p><img fetchpriority="high" decoding="async" class="alignnone wp-image-5164" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002.png" alt="" width="704" height="349" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002.png 1506w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-300x149.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-1024x507.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-150x74.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-768x380.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-360x178.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-160x79.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-320x159.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-495x245.png 495w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-686x340.png 686w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-908x450.png 908w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-1009x500.png 1009w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_03-002-520x258.png 520w" sizes="(max-width: 704px) 100vw, 704px" /></p>
<p>Because we will call the XMLA endpoint as a Power BI User with Premium Per User capacity, go to the <em>Premium Per User</em> section and allow read-only access to XMLA endpoints in <em>Dataset workload settings.</em><br />
<img decoding="async" class="alignnone wp-image-5167" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04.png" alt="" width="407" height="453" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04.png 887w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-270x300.png 270w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-90x100.png 90w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-768x854.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-360x400.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-144x160.png 144w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-288x320.png 288w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-220x245.png 220w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-306x340.png 306w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-405x450.png 405w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-450x500.png 450w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_04-520x578.png 520w" sizes="(max-width: 407px) 100vw, 407px" /></p>
<p>For the Power BI Premium per Capacity settings check this <a href="https://www.youtube.com/watch?v=YEIKzeNCqGg" target="_blank" rel="noopener">video</a> from 6:48 because there it needs to be set too.</p>
<p>Then go to your workspaces and choose the one you will connect to.</p>
<p><img decoding="async" class="alignnone wp-image-5168" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06.png" alt="" width="406" height="394" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06.png 891w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-300x291.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-103x100.png 103w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-768x745.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-360x349.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-160x155.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-320x310.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-253x245.png 253w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-351x340.png 351w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-464x450.png 464w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-516x500.png 516w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_06-520x504.png 520w" sizes="(max-width: 406px) 100vw, 406px" /></p>
<p>Copy the Workspace connection because we will use it later in the C# Console app.</p>
<p><strong>Note</strong>: XMLA endpoints are supported only for workspaces hosted on <a href="https://docs.microsoft.com/en-us/power-bi/admin/service-premium-what-is" target="_blank" rel="noopener">Premium capacity</a>. If you will try to connect to a non-premium workspace you will get this exception:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">Microsoft.AnalysisServices.ConnectionException: 
Initial catalog property is required in order to connect to Power BI Pro workspaces.</pre>
<p>You can test the proper configuration using the SQL Server Management Studio.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5170" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07.png" alt="" width="381" height="251" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07.png 873w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-300x198.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-150x100.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-768x506.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-360x237.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-160x105.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-320x211.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-372x245.png 372w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-516x340.png 516w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-683x450.png 683w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-759x500.png 759w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_07-520x342.png 520w" sizes="auto, (max-width: 381px) 100vw, 381px" /></p>
<p>Fill in your Power BI User account credentials (same as for powerbi.com) once prompted. You will see a list of available databases after successful authentication.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5175" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08.png" alt="" width="638" height="55" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08.png 1091w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-300x26.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-1024x88.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-150x13.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-768x66.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-360x31.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-160x14.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-320x28.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-520x45.png 520w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-720x62.png 720w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_08-980x84.png 980w" sizes="auto, (max-width: 638px) 100vw, 638px" /></p>
<h3>2. Downloading Tabular Object Model using C# console application</h3>
<p>Because our Power BI XMLA endpoint is ready for connection now, we will test it from a simple C# console application. You can build your own or just download the solution targeting .NET.Core 5.0.</p>
<ul>
<li><a href="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIXMLA.zip">PowerBIXMLA</a></li>
</ul>
<p>Two NuGet packages are required to connect to Analysis Services running under the hood of Power BI Service.</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5161" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01.png" alt="" width="751" height="112" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01.png 1617w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-300x45.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-1024x153.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-150x22.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-768x114.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-1536x229.png 1536w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-360x54.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-160x24.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-320x48.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-520x78.png 520w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-720x107.png 720w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-980x146.png 980w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_01-1320x197.png 1320w" sizes="auto, (max-width: 751px) 100vw, 751px" /></p>
<p>The main method:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">using System;
using Microsoft.AnalysisServices;

namespace PowerBIXMLA
{
    class Program
    {
        static void Main(string[] args)
        {

            Server server = new Server();

            // Connect as Power BI User
            string workspaceConnection = "powerbi://api.powerbi.com/v1.0/myorg/YOUR_WORSPACE_NAME";
            string userId = "";
            string password = "";
            string connectStringUser = $"DataSource={workspaceConnection};User ID={userId};Password={password};";


            // Connect as Service Principal
            /*
            string workspaceConnection = "powerbi://api.powerbi.com/v1.0/myorg/YOUR_WORSPACE_NAME";
            string tenantId = "";
            string appId = "";
            string appSecret = "";
            string connectStringServicePrincipal = $"DataSource={workspaceConnection};User ID=app:{appId}@{tenantId};Password={appSecret};";
            */

            // Connect
            server.Connect(connectStringUser);

            // List Databases (Datasets - tabular models) and extract TOM (Tabular Object Model)
            foreach (Database database in server.Databases)
            {
                Console.WriteLine(database.Name);

                string tmslTable = JsonSerializer.SerializeDatabase(database);

                Console.WriteLine(tmslTable);
            }
        }
    }
}</pre>
<p>You need to modify the section with Power BI User credentials:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">string workspaceConnection = "powerbi://api.powerbi.com/v1.0/myorg/YOUR_WORSPACE_NAME"; 
string userId = ""; 
string password = "";</pre>
<ul>
<li><strong>worskspaceConnection</strong>: this is the <em>Workspace Connection</em> value we have copied above (powerbi://api.powerbi.com/v1.0/myorg/Premium WS)</li>
<li><strong>userId</strong>: Power BI User account name (username@domain.xx). The same you are using to sign in to Power BI Service.</li>
<li><strong>password</strong>: Your Power BI User password.</li>
</ul>
<p>We can list all server <em>Databases</em> once connected and use the <em>SerializeDatabase()</em> method to get the Tabular Object Model.</p>
<p>Rebuild the application and run int. In case of success you will see:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5163" src="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02.png" alt="" width="437" height="407" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02.png 816w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-300x280.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-107x100.png 107w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-768x716.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-360x336.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-160x149.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-320x298.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-263x245.png 263w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-365x340.png 365w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-483x450.png 483w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-536x500.png 536w, https://sqlpowered.com/wp-content/uploads/2021/04/Getting_TOM_from_Power_BI_XMLA_Endpoint_02-520x485.png 520w" sizes="auto, (max-width: 437px) 100vw, 437px" /></p>
<p>Because we have called the <em>SerializeDatabase()</em> method the whole Database is serialized to JSON. Database-level properties are marked with blue. The Tabular Object Model is marked with green.</p>
<p>If you would like to serialize just the Tabular Object Model you can call SerializaeObject() method inside the Tabular namespace.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">Microsoft.AnalysisServices.Tabular.JsonSerializer.SerializeObject(database.Model);</pre>
<p>To do more with the main Tabular Object Model just reference the Tabular namespace and process the object like any other strong-typed objects.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">using Microsoft.AnalysisServices.Tabular;
...

Model model = database.Model;

foreach (Table t in model.Tables)
{
    Console.WriteLine(t.Name);
}
</pre>
<p>Finally, it&#8217;s important to understand that datasets uploaded to Power BI Service from Power BI *.pbix files are in fact hosted as standard Analysis Service Tabular Models in the Power BI Service. That means that you can use the same approach when connecting to the on-prem Tabular Analysis Services instance. Only the authentication process will be different. The XMLA itself is fully compatible.</p>
<h4>References</h4>
<ul>
<li><a href="https://docs.microsoft.com/en-us/power-bi/admin/service-premium-connect-tools" target="_blank" rel="noopener">Dataset connectivity with the XMLA endpoint</a></li>
<li><a href="https://docs.microsoft.com/en-us/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions" target="_blank" rel="noopener">Tabular Object Model (TOM)</a></li>
<li><a href="https://powerbidevcamp.powerappsportals.com/sessions/session04/" target="_blank" rel="noopener">Programing Datasets using the Tabular Object Model</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlpowered.com/getting-tabular-object-model-from-power-bi-xmla-endpoint/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Power BI API Connector (sample application)</title>
		<link>https://sqlpowered.com/power-bi-api-connector-sample-application/</link>
					<comments>https://sqlpowered.com/power-bi-api-connector-sample-application/#respond</comments>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Sat, 03 Apr 2021 08:50:48 +0000</pubDate>
				<category><![CDATA[Azure]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Power BI]]></category>
		<guid isPermaLink="false">https://sqlpowered.com/?p=5076</guid>

					<description><![CDATA[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: PowerBIApiConnector_Executable...]]></description>
										<content:encoded><![CDATA[<p>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.</p>
<p>Application is created in .NET.Core 5.0 and you can download it as:</p>
<ul>
<li><a href="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Executable.zip">PowerBIApiConnector_Executable</a> &#8211; executable files in *.zip package for direct use</li>
<li><a href="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution.zip">PowerBIApiConnector_Solution</a> &#8211; Visual Studio 2019 Project</li>
</ul>
<h3>How to use it?</h3>
<p>Extract the executable package files to a directory. You have two options how to launch the application:</p>
<p>A) Setup parameters at the application launch:</p>
<p><code class="EnlighterJSRAW" data-enlighter-language="generic">PowerBIApiConnector.exe {Application (client) ID} {Directory (tenant) ID} {Client Secret}</code></p>
<p>B) Execute it without parameters. Then you will be prompted for input values:</p>
<p lang="cs" style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><img loading="lazy" decoding="async" class="alignnone wp-image-5080" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt.png" alt="" width="322" height="104" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt.png 604w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-300x97.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-150x48.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-360x116.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-160x52.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-320x103.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_InputParametersPrompt-520x168.png 520w" sizes="auto, (max-width: 322px) 100vw, 322px" /></p>
<p lang="cs">Input parameters are:</p>
<ul>
<li lang="cs"><strong>Application (client) ID</strong>: This is an Azure Application ID</li>
<li lang="cs"><strong>Directory (tenant) ID</strong>: Your organization (tenant) ID</li>
<li lang="cs"><strong>Client Secret: </strong>Application secret value<strong><br />
</strong></li>
</ul>
<p>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:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5081" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs.png" alt="" width="503" height="196" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs.png 1165w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-300x117.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-1024x399.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-150x58.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-768x299.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-360x140.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-160x62.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-320x125.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-520x203.png 520w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-720x281.png 720w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParametrs-980x382.png 980w" sizes="auto, (max-width: 503px) 100vw, 503px" /></p>
<p>For the Client Secret navigate as in the image below and copy the Value or create a new secret:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5082" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2.png" alt="" width="763" height="407" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2.png 2237w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-300x160.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-1024x547.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-150x80.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-768x410.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-1536x820.png 1536w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-2048x1093.png 2048w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-360x192.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-160x85.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-320x171.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-459x245.png 459w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-637x340.png 637w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-843x450.png 843w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-937x500.png 937w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ApplicationParameters_2-520x278.png 520w" sizes="auto, (max-width: 763px) 100vw, 763px" /></p>
<p>When you launch the application and authentication to Azure AD will succeed, you will see an authentication token printed to the console window:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5085" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution.png" alt="" width="571" height="204" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution.png 1199w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-300x107.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-1024x366.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-150x54.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-768x274.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-360x129.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-160x57.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-320x114.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-520x186.png 520w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-720x257.png 720w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Execution-980x350.png 980w" sizes="auto, (max-width: 571px) 100vw, 571px" /></p>
<p>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.</p>
<p>If you will input &#8220;Y&#8221; 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:</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5086" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces.png" alt="" width="576" height="112" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces.png 1188w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-300x58.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-1024x199.png 1024w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-150x29.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-768x149.png 768w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-360x70.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-160x31.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-320x62.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-520x101.png 520w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-720x140.png 720w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_ListWorkspaces-980x191.png 980w" sizes="auto, (max-width: 576px) 100vw, 576px" /></p>
<h3>Solution content</h3>
<p>Two dependency packages are required (will be automatically downloaded via NuGet packages manager):</p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-5088" src="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution.png" alt="" width="299" height="184" srcset="https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution.png 493w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-300x185.png 300w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-150x92.png 150w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-360x222.png 360w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-160x99.png 160w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-320x197.png 320w, https://sqlpowered.com/wp-content/uploads/2021/04/PowerBIApiConnector_Solution-397x245.png 397w" sizes="auto, (max-width: 299px) 100vw, 299px" /></p>
<p>Main method code:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">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 =&gt; x.Name);

                    //Print output
                    Console.WriteLine("Workspaces found:");

                    foreach (string workspaceName in workspaceNames)
                    {
                        Console.WriteLine("  =&gt; " + workspaceName);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Environment.Exit(1);
                }
            }

            Console.WriteLine("Done!");

        }
    }
}</pre>
<h3>References</h3>
<p>For additional references, I will recommend this excellent <a href="https://www.sqlbi.com/articles/creating-a-service-principal-account-for-power-bi-api/" target="_blank" rel="noopener">video</a> from Marco Russo and the official Microsoft <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app" target="_blank" rel="noopener">guide</a>.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlpowered.com/power-bi-api-connector-sample-application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
