Execute Power Apps CLI in Azure DevOps
A few months ago I wrote a post about how to “Unpack Canvas Apps in a Pipeline“. The first function of the Power Apps CLI (PAC) was around PCF creation. Since then a lot was added to it and there is still more to come I do assume. Since a few weeks the Power Apps Solution Packager (PASopa) is included in the PAC, which means the approach I explained in the other post is not needed anylonger. In this Post you will learn how to execute Power Apps CLI in Azure DevOps.
Shout out to Natraj and Mike for giving me some hints on how to do it.
You can find a yaml file that includes the complete example in one of my GitHub repos.
To make the explanation more visual and easier to understand I will, as always, not use yaml in this blog post.
Situation
Unfortunately, neither the PAC nor the PASopa is currently included in the Power Platform Build Tools which are available for Azure DevOps. This means we have to run it in some other way.
The solution is to install the NuGet of the PAC manually in our pipeline. After that, we need to find the path to it so that we can use it in our script.
Implementation
Let’s see how to implement it. There are different things to do.
Pipeline steps
We will start by adding the necessary steps to the pipeline.
Use NuGet
First, we have to install the NuGet tooling to the Build Agent. This step can be used with the standard configuration.

NuGet
The second step we need is called “NuGet”. As a command we use “custom” and add the following line to install the PAC and define pac as the output folder.
install Microsoft.PowerApps.CLI -OutputDirectory pac
PowerShell – Find pac folder
After we have installed PACs NuGet we need to find the path to the exe file so we can execute it later.
To do so we use a “PowerShell” step with the following script.
The script will first get the children of the pac folder and then selects the one which contains “Microsoft.PowerApps.CLI.”
The second step is to add “\tools” to it.
The last step is then to output the generated path back to the pipeline so it can be used in the following steps.
$pacNugetFolder = Get-ChildItem "pac" | Where-Object {$_.Name -match "Microsoft.PowerApps.CLI."} $pacPath = $pacNugetFolder.FullName + "\tools" echo "##vso[task.setvariable variable=pacPath]$pacPath"
PowerShell – Execute PAC
This step will actually execute the PAC. Insert a second “PowerShell” step and add the following script to it.
First, we will add the outputted path of the previous step to the path environment variable.
Then we execute the pac to unpack a canvas app, which is our demo scenario.
$env:PATH = $env:PATH + ";" + "$(pacPath)" pac canvas unpack --msapp $(Build.SourcesDirectory)\Solutions\$(SolutionName)\CanvasApps\bebe_almdemoapp_41ec7_DocumentUri.msapp --sources D:\a\1\s\Solutions\$(SolutionName)\CanvasApps\bebe_almdemoapp_41ec7_DocumentUri_src
We could have done the last PowerShell scripts in one step. I tried to show an approach you could execute the pac several times. You only have to add it to the PATH variable in every step.
If you try to run a command of the Power Apps CLI which will request Dataverse you have to create a connection first. To do so you can run the “auth add” command to establish a connection. If you would like to create it with an App Registration the command looks something like this:
pac auth create -t <your tenantID> -id <AppReg ID> -cs <ClientSecred> -n <Name> -u <URL>
You can find more information about the command in the MS docs.
Change .gitignore
Since the install NuGet step installs the pac in a certain folder this would be added to the repository. So we have to add the folder to our .gitignore file. To achieve this we add “pac/” to our .gitignore file.
Conclusion
The approach explained in this post could be used in different ways. For example to unpack/pack a Canvas app as demonstrated in this post. But there are other areas, for example, administer environments (backups, deletion, reset, copy or restore), push a pcf, download or upload portal content or many more.
Now you know how to execute the Power Apps CLI in Azure DevOps. To find the path one needs some lines of code, but once the path is found it can easily be reused in the pipeline.
I hope this post helped you. Feel free to contact me if you have any questions or suggestions.
You can also subscribe and get new blog posts emailed to you directly.
Excellent tutorial Benedikt. I got stuck on the last PowerShell section where we unpack the canvas app and received this error message. Any ideas why?
“Error: PA3012: Bad parameter: Must provide path to either empty directory or a directory where the app was previously unpacked.”
Glad I could help with the article.
I tested my pipeline once more and got the same error.
I had to add the output folder with –source. I have updated the post accordingly.
It works now. Thanks for the quick reply Benedikt. This is SO COOL!
Hi Benedict,
This is a great article!
I’m building a pipeline to export power portal using pac (similar to power apps, but anoither command) and stumbled on the pac command execution as it says “Error: No profiles were found on this computer. Please run ‘pac auth create’ to create one.”
I’m not sure how did you do authentication for pac? I added steps for power platform installer and can do “Who I am” task confirming my connection to DAavaerse is OK, but it seems not what pac expects.
Any tips?
Hej Andrew, -id -cs -n -u
Thanks for your comment. The part I am using does not need any authentication since it only does an unpack locally in the pipeline without requesting anything from Dataverse.
What I would suggest is to run the pac auth create command before your actually pac command. You can find the documentation of it at ms docs. An example using an app registration would be the following:
pac auth create -t
I will test it myself and add id to the blog post. Thanks for bringing that up.
Thanks, Benedikt!
I did try and it worked:
pac auth create –name … –url … –applicationId … –clientSecret … –tenant …
Obviously, a service principal had to be created in the Azure AD of the tenant organisation AND this application user to be added to the environment as described here: https://docs.microsoft.com/en-us/powerapps/developer/data-platform/use-single-tenant-server-server-authentication#azure-application-registration
Great to hear. I’m glad I could help.
Thanks for taking the effort to post.
I have used it in an AzDO pipeline after unpacking an unmanaged solution and putting in repository. This extra picks up the canvas app. I soon sussed your example, tad confused with –source and –sources, one in your screenshot, the other in the code copy. I made the app name a variable so probably each pipeline will have to be tailored to each solution to cater for N apps. I do a ‘Git add –all’ at the end to get it all in the Repo, maybe someday I’ll work out how to ignore saving the pac folder. All the best, cheers, Richard
Hej Richard,
glad my post could help you and thanks for the feedback. I have updated the post to bring the code snippet and screenshot in sync. Both do now read “–sources”.
In response to your concern about the pac folder in the repo: Have you seen the last paragraph of my post? There I write what you have to add to your .gitignore file to ignore this folder. Please let me know if you have any issues with that, I would be glad to assist you.
Thank you for this article, it’s been super useful to help achieve an outcome where I’m looking to generate a deployment settings file for automating deployment.
Hi Benedikt,
Is it possible to create a docker image that includes the Power apps CLI?
I never tried that, but spontaneously I would say it should be possible.
What would be your use case for that?
Hi Benedikt,
We’re using Gitlab CICD and need to use Power Apps CLI via shell script as part of pipeline. I have the docker image but it wouldnt recognized the “pac” cli command in the shell script.
Hi Benedikt,
I am facing this error with the latest Update version of power apps CLI 1.13.4. Here is the error,
pac : The term ‘pac’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\a\_temp\b410d2be-6ba4-4be6-afe7-308650b3cb7c.ps1:4 char:1
Can you able to provide any Suggestions/Solution.
I had the same problem when the VS Code Dataverse extension was active. Do you have it installed? Are you trying to update the pac from within Visual Studio Code?
Thanks a lot for the article Benedikt, this info was very useful for me.
Hi Benedikt,
Thank you so much for the article. The pipeline is running successfully for my but I don’t see any change in my repository branch. I tried with both pack and unpack commands but no new files are being added. Can you please help me in figuring out what might be the issue?
Thank you
Two things I would check:
– Is the pipeline working on the same branch as you?
– Is the unpack command unpacking the App to the correct folder? It might unpack it to some local folder which isn’t associated with the repository.
What is the use of generating the deployment file, and in what scenarios would you do so?
Kind regards 🙂
Najtreg
Which deployment file do you mean?
Just replaced the NuGet etc explained in this article with the «process canvas app» setting in the build tools unpack solution step. Works lile a a charm!
Hej Lars,
thanks for the input. This is true. the unpack solution step can handle this now, which was not the case when I wrote the article.