Using PowerShell to run Power BI DAX queries and extract data to CSV
In this blog post I am going to show you how to use PowerShell to run a DAX query from my dataset, and then store the results in a CSV file.
I will also include the PowerShell code!
I really liked the awesome blog post by Kay on the Power BI Team which you can find here: Announcing the public preview of Power BI REST API support for DAX Queries
Before I start with the PowerShell code I had completed the following requirements
- Allow XMLA endpoints and Analyze in Excel with on-premises datasets
- The required users were either Admins or Members of the App Workspace. Or the user had build permissions on the underlying dataset.
- The App Workspace was using the Modern or V2 of the App workspaces.
In my example below I am going to be using a Service Principal to get the data, this allows me to be able to run the PowerShell code with some automation.
NOTE: This also means that underlying user in my Service Principal group must have a PPU license to be able to read the data.
Finding the dataset GUID
One of the requirements for the PowerShell script is that I need to put in the dataset GUID, in the steps below I show you how to find this.
My dataset is linked to my Power BI Report. I go into the Power BI App Workspace where my dataset is stored.
NOTE: If you are using Power BI reports that use a dataset from another App Workspace you have to go and find which dataset that workspace lives in. You can do this by right clicking on your report and selecting View Lineage
Now to get the dataset GUID, I go into my App Workspace, right click on my dataset and click on settings as shown below.
What I then need to do is to look in the URL and make a note of the GUID after /datasets/ as highlighted below in RED
In my example above my dataset GUID is: 0f2fc89a-cc2a-490a-9bc9-99e5900e77a7
Getting the DAX Query
The first that I needed to do was to get the DAX query for the data that I wanted to extract into my CSV file.
I like to do this using Power BI Desktop and using the Performance Analyzer, to me this is a little hack that makes it quick and easy for me to get the DAX syntax without having to write it myself!
I went into my PBIX report, clicked on Performance Analyzer
I already had my table ready, I clicked on Start Recording and then refreshed the visual, which then gave me the option to copy the query as shown below.
This is what my DAX query looked like below
// DAX Query DEFINE VAR __DS0Core = SUMMARIZECOLUMNS( ROLLUPADDISSUBTOTAL('Date'[Date], "IsGrandTotalRowTotal"), "Sales_Amount", 'Sales'[Sales Amount], "v_Sales_Amount_FormatString", IGNORE('Sales'[_Sales Amount FormatString]) ) VAR __DS0PrimaryWindowed = TOPN(502, __DS0Core, [IsGrandTotalRowTotal], 0, 'Date'[Date], 1) EVALUATE __DS0PrimaryWindowed
Now that I have my DAX query onto the next steps to run this in PowerShell
Running the DAX query using PowerShell
Below is the script that I used to run the DAX query, and I comment all the details of what I needed to do to get this working in the script.
# Reference: https://powerbi.microsoft.com/en-ca/blog/announcing-the-public-preview-of-power-bi-rest-api-support-for-dax-queries/ # I have found using PowerShell on my PC this is needed to work. [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # User Account Details # This could be a user account or a service account $username = "fourmooisawesome@fourmoo.com" $password = "IsThisReallyMyPassword!" | ConvertTo-SecureString -asPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($username, $password) # Logging in with above credentials Connect-PowerBIServiceAccount -Credential $credential # Getting the DAX Query URL to pass through # I had to get the dataset GUID from Settings -> Datasets in the Power BI Service $requestUrl = "datasets/0f2fc89a-cc2a-490a-9bc9-99e5900e77a7/executeQueries" # DAX Query - This is what I got from using Power BI Desktop # NOTE: The double quote is a reserved character and it has to be escaped with a backslash. # EG: If this is "My Text" it needs to be written as \"My Text\" $requestBody = @" { "queries": [ {"query": "DEFINE VAR __DS0Core = SUMMARIZECOLUMNS( ROLLUPADDISSUBTOTAL('Date'[Date], \"IsGrandTotalRowTotal\"), \"Sales_Amount\", 'Sales'[Sales Amount]) VAR __DS0PrimaryWindowed = TOPN(502, __DS0Core, [IsGrandTotalRowTotal], 0, 'Date'[Date], 1) EVALUATE __DS0PrimaryWindowed " } ], "serializerSettings": {"includeNulls": false} } "@ # Creating the Result Variable by passing through the DAX Query to the Power BI PowerShell Module $result = Invoke-PowerBIRestMethod -Method POST -Url $requestUrl -Body $requestBody # I take the results and convert it from JSON $parsed = $result | ConvertFrom-Json # This is where I take the results and export it to CSV $parsed.results[0].tables[0].rows | Export-Csv D:\Myresults2.csv
I then went to my D: Drive and opened the file, which was shown below has got the results in a CSV format
Summary
In this blog post I have shown how you can use the Power BI PowerShell module to run a DAX query and then store the results in a CSV file.
If there are any comments or questions, please let me know.
Thanks for reading and have an awesome day!
Very informative and interesting!
[…] Gilbert Quevauvilliers writes some Powershell: […]
Thank you itit is very useful.
I have a question.
If i don’t want to export to csv but just have the query result How do I do this?
For example I your case I just want to have a Date.
Hi Amandine,
What you would then need to do, is to alter your DAX query to return what you need. If your example is just the date, then change the DAX query to use the date.
You can use my blog post here to get Power BI Desktop to write the DAX query for you: Get Power BI Desktop to write the DAX for you
Quick question – this code has worked perfectly until I try to parse it – the $result is actually HTML code! I know the DAX works because I ran it in DAX studio. Have you encountered this before?
Hi Drew,
Thanks for the question
I have updated my blog post so it should be good to copy the DAX code now.
Hi Gilbert,
I am so happy seeing your code as this is almost what I am looking for except the source connection part! I would like to get all data including measures for two of the table from SSAS Tabular cube and send it to datalake. SSAS model also located into Azure server.
So I have Analysis server into Azure with server name, subscription etc. Using the connection string I need to get all data say Evaluate (‘Products’). I believe sending part should be the same as your code says. I am not good at power Shell so not sure how to establish connection to connect SSAS server with dataset.
Can you please help me. Thanks in advance!
Hi Kim
The script I created in my blog post only works for Power BI, because it has got the APIs created to then return the data.
If you are looking to do this with Azure Analysis Services I would suggest looking at DAX studio to do this if it is a once off.
Otherwise I am sure that there might be another way to extract the data via an API or XMLA end point.
Hi,
I tried to run the code but I get an error on line 49 “$ parsed = $ result | ConvertFrom-Json”. The error is:
Invalid JSON primitives
+ $ parsed = $ result | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo: NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId: System.ArgumentException, Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Do you have some advice?
Thanks, Giacomo
Hi Giacomo
It would appears that there might be a syntax error happening. If you could check using PowerShell ISE to see if it finds any errors?
Hi Gilbert,
Is there a way your code can return values for Data[Date] only ,
Hi Eric,
I would create the table in Power BI Desktop, then capture the query and use that in your query.
Hi Gilbert,
Your code really helped me to get somwhere
Below is my final OutPut on Json, Is there a way I can pull just values only e.g. Accounting, Finance, HR, Admin. I will need to pass them as a paramter filter at somepoint on my other script.
[
{
“AzureADUserProperties[Department]”: “Accounting”
},
{
“AzureADUserProperties[Department]”: “Finance”
},
{
“AzureADUserProperties[Department]”: “HR”
},
{
“AzureADUserProperties[Department]”: “Admin”
},
]
Be aware that Powerbi inserts a TOPN of 502 rows into the query. You need to amend that to get all the records when you run powershell.
Hi Robert
Yes, thanks that is great to point out!