Developing PCF Components inside a container

Before anyone can start developing PCF components, they have to prepare their local machine and get it ready. This usually means that a whole bunch of tools and frameworks have to be installed. As per Microsoft documentation you need these pre-requisites:

  1. Node JS
  2. .NET 4.6.2 Developer Pack
  3. Power Apps CLI
  4. Visual Studio Build Tools (for Solution packaging)

What if you could start with just VSCode without wasting time on any of this, with a bit of templating thrown in? It is possible, with one secret ingredient: Docker.

When I started this exploration around April, I tried using Linux containers. The reason being both VS Dev Containers and GitHub Codespaces only support Linux containers. But, I faced an issue straight-away during npm build.

npm build error

I tried to edit the files in node_modules and make it work but I encountered more issues, due to the fact that PCF CLI specifically targets Windows only. So, I gave up on that idea and until about a couple of weeks back.

I thought, why not use Windows containers in Docker, rather than Linux containers. The first image of my choice was nanoserver, because of the image size. But, nanoserver images does not seem to play nicely when I wanted to install VS Build Tools and chocolatey in the image, so I ended up moving to Windows Server Core.

Below are the relevant links you can look into for the Docker file and the image:

  1. Repo –
  2. Image –

Now lets us see how you can use this image to start your PCF Development.

Step 1: Install Docker Desktop from

Step 2: Once Docker is up and running, right click on the icon and choose “Switch to Windows Containers”. The screenshot below is displaying Linux Containers because I am already using Windows Containers

Docker Right Click Menu

Step 3: Choose the folder where you want your sourcecode, and create two items: a folder called src and a file called pcf.env

PCF Folder Structure

Step 4: Add the details about your PCF Component on the pcf.env file. These correspond to the commandline args in PCF CLI. Below is a sample


Step 5: Install Docker extension for VSCode, if you want to use the GUI, rather than commands for working with containers.

Step 5: Run the command below in VSCode’s PowerShell Terminal window to create the container from the image in GitHub Container Registry. I have specified the name of the container as “TestComponent” in the example below, but pick a different name based on the component name for the container.

docker run -it -v $pwd\src:c:\src –name TestComponent -p 8181:8181 –env-file pcf.env

Once you run this command, Docker will automatically pull the image from the registry and start building the local container.

It will also start running the PCF CLI commands inside the container.

Now if you check your local machine, you would see all the files generated by PCF CLI.

You can also see the container up and running.

You can also build the repo inside the container. Confirm that you are in the container’s terminal and not on your local machine’s terminal.

You can also build the solution using MSBuild inside the container.

Since the container’s port 8181 is mapped to the local machine’s port 8081, you can also run npm start and open the test harness on your local machine.

If you want to exit out of the container’s prompt into your host machine’s prompt just run “exit” command.

To see the list of all the containers, including this ones that are not running run the command below, or use the Docker extension.

docker ps -a

If the container is not running, run the command below to start the container and open the terminal. In the example below, the name of my container is “TestComponent”.

docker start -ai (docker ps –filter “name=TestComponent” -aq)

Now, you can just focus on writing your PCF Component without installing all the required pre-requisites on your local machine.

Automating PCF Build using GitHub Actions

Guido runs a great site called where there are over 200+ PCF components. The components on the site are hosted on GitHub and have solutions that can be installed on CDS. Some components have managed solution, some have unmanaged, and some have both. Since lot of the components are open-source and are hosted in GitHub, I thought it would be good to automate this using GitHub Actions and ensure every component has both managed and unmanaged solutions.

GitHub Actions is similar to Azure DevOps. If you want to know more about GitHub Actions and how it compares to Azure DevOps, listen to DevOps and GitHub Actions with Edward Thomson on Hanselminutes. I created a starter repo with a workflow yml that anyone can use in their PCF repo hosted on GitHub. You can access this repo on

In order to use this workflow on your repo do these steps:

  1. Clone this repo and copy the .github folder from the cloned repo into the root of your repo.
  2. Update the msbuildtarget environment variable on the yml to point to the folder with the “Other” folder. This folder would have been created when you ran the “pac solution init” command.PCF YAML
  3. The “Other” folder will have the xml files that will be packaged up into the solution.PCF Other
  4. Make sure that you update the value for “SolutionPackageType” on your cdsproj file to “Both”, so that the Solution Packager can build both Managed and Unmanaged Solutions.cdsproj

Once you make these changes commit the changes to your repo. The build command will run everytime you commit something to the repo. You can download the managed and unmanaged solutions from the artifact area on the build.

PCF Build

Once you are ready to release the solutions, tag the commit using “git tag”. If the tag is in this format: v* e.g. v1.0, v.1.0.0 etc., the workflow will run the Release steps, which will create a new release and add both the managed and unmanaged solutions to the release.

PCF Release

PCF Release TagPCF Releases

Both the Solution Name and the Solution Version will be picked up from the Solution.xml file, so as you release new versions, make sure you update this information on the file.

I hope this makes it little easier to automate your PCF builds and releases on GitHub.



Opening Lookups in Main Form Dialog

Main Form Dialog is a new feature in model-driven Power Apps. It was officially released this month (Feb 2020). Along with this, I also noticed today that Microsoft has also quietly added a new event that plays nice with MFD.

The new event is called OnLookupTagClick. This event handler can be used in scenarios where the user clicks on the lookup. Normally, this would redirect the page to the lookup record, but you can block this navigation on OnLookupTagClick, and rather show the lookup record on a modal popup using navigateTo. Below is the sample code on how to do this. Since I ran the code from DevTools console, I am using the deprecated Xrm.Page. If you are running this from a form, you should use the formContext.

Xrm.Page.getControl('parentcustomerid').addOnLookupTagClick(context => {
	const tagValue = context.getEventArgs().getTagValue();

        pageType: "entityrecord",
        entityName: tagValue.entityType,
        formType: 2,
    }, {
        target: 2,
        position: 1,
        width: {
            value: 80,
            unit: "%"

Have a look at the GIF below to understand the UX of this approach.


Using PowerShell to generate Earlybound classes

Early Bound generator is a great XrmToolBox tool developed by fellow MVP Daryl LaBar. It helps you to generate the strongly-typed classes that can be used in your custom code development projects e.g. plugins, workflows, console app etc.  If your are committing the early bound classes into source control, you also should committing the configuration that is used to generate the classes and also make it easy for the next developer joining the team to generate these classes, without jumping into XrmToolBox and clicking it manually. In this post, I will present my approach into streamlining this process.

  1. Generate the files once from XrmToolBox with the settings that are optimal for your requirements EBG Settings
  2. Locate the the path where all XrmToolBox tools are installed. You can see this by clicking Configuration -> Settings. On the settings page, click on the “Paths” tab and then the “Open XrmToolBox storage folder” link.XTB Path
  3. Navigate to Plugins -> DLaB.EarlyBoundGeneratorEBG Folder
  4. Copy the crmsvcutil.exe.config file into a folder. You would need this for checking in into source control. This file won’t have any passwords, so it is safe to check in.
  5. Below is the PowerShell script to run. You also should committing this script into source control. The PowerShell script should be run on the same location where you copied the crmsvcutil.exe.config file in the previous step. The generated early bound classes will be in the folder specified in the “$outputPath” variable, which is “EarlyBoundClasses” in this script. You can change this match your solution folder structure.
    Write-Output "Start"
    $sourceNugetExe = ""
    $targetNugetExe = ".\nuget.exe"
    Remove-Item .\Tools -Force -Recurse -ErrorAction Ignore
    Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe
    Set-Alias nuget $targetNugetExe -Scope Global -Verbose
    $connString = "AuthType=OAuth;Username=[LOGINNAME];Integrated Security=true;Url=https://[INSTANCENAME].[INSTANCEREGION];AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97;TokenCacheStorePath=.\MyTokenCache;LoginPrompt=Auto"
    $outputPath = ".\EarlyBoundClasses"
    $namespace = "Xrm.Entities"
    ##Download EBG
    ./nuget install DLaB.Xrm.EarlyBoundGenerator.Api
    move .\DLaB.Xrm.*\content\bin\DLaB.*\* .\EBG -Force
    copy .\crmsvcutil.exe.config .\EBG -Force
    Remove-Item .\DLaB.Xrm.EarlyBoundGenerator.Api* -Force -Recurse
    .\EBG\CrmSvcUtil.exe /connstr:$connString /generateActions /out:"$outputPath\Actions.cs" /namespace:"$namespace" /codecustomization:"DLaB.CrmSvcUtilExtensions.Action.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions" /codegenerationservice:"DLaB.CrmSvcUtilExtensions.Action.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions" /codewriterfilter:"DLaB.CrmSvcUtilExtensions.Action.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions" /metadataproviderservice:"DLaB.CrmSvcUtilExtensions.BaseMetadataProviderService,DLaB.CrmSvcUtilExtensions"
    .\EBG\CrmSvcUtil.exe /connstr:$connString /out:"$outputPath\CrmServiceContext.cs" /namespace:"$namespace" /servicecontextname:"CrmServiceContext" /codecustomization:"DLaB.CrmSvcUtilExtensions.Entity.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions" /codegenerationservice:"DLaB.CrmSvcUtilExtensions.Entity.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions" /codewriterfilter:"DLaB.CrmSvcUtilExtensions.Entity.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions" /namingservice:"DLaB.CrmSvcUtilExtensions.NamingService,DLaB.CrmSvcUtilExtensions" /metadataproviderservice:"DLaB.CrmSvcUtilExtensions.Entity.MetadataProviderService,DLaB.CrmSvcUtilExtensions"
    .\EBG\CrmSvcUtil.exe /connstr:$connString /out:"$outputPath\OptionSets.cs" /namespace:"$namespace" /codecustomization:"DLaB.CrmSvcUtilExtensions.OptionSet.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions" /codegenerationservice:"DLaB.CrmSvcUtilExtensions.OptionSet.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions" /codewriterfilter:"DLaB.CrmSvcUtilExtensions.OptionSet.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions" /namingservice:"DLaB.CrmSvcUtilExtensions.NamingService,DLaB.CrmSvcUtilExtensions" /metadataproviderservice:"DLaB.CrmSvcUtilExtensions.BaseMetadataProviderService,DLaB.CrmSvcUtilExtensions"
    Remove-Item nuget.exe
    Remove-Item .\EBG -Force -Recurse
    Write-Output "Complete"

You can see that I use OAuth for authentication. OAuth is one of the mechanism you can use to authenticate in the connection string. You can refer page for additional information. If you don’t like entering your credentials during script execution, you can also use “ClientSecret”, but this needs to be first configured on Azure AD.  You can refer Nishant’s post about this

Microsoft also has created a AppId and RedirectUri that you can use on you development or test instance. Below is the disclaimer on the docs page about these.

When using the OAuth AuthType\AuthenticationType
For development and prototyping purposes we have provided the following AppId or ClientId and Redirect URI for use in OAuth Flows.

For production use, you should create an AppId or ClientId that is specific to your tenant in the Azure Management portal.

Sample AppId or ClientId = 51f81489-12ee-4a9e-aaae-a2591f45987d
Sample RedirectUri = app://58145B91-0C36-4500-8554-080854F2AC97


Hope this helps.

Using PCF to display contact cards

What is PCF?

If you are building Model Driven Apps, you would have realised by now that Unified Interface is the future. Microsoft has made huge investments in this area to ensure that you have an optimal experience regardless of the device or form factor. Unified Interface is composed of several components/controls that help you to visualise and interact with the data.

If you wanted to swap out the control or build a new one that is better than what comes out this box, the only way you could do this earlier was to build a custom webresource and embed it into an IFrame. Using IFrame is clunky, and you had to handle all the complexities of building a responsive interface. IFrame also cannot be displayed on a view, only on a form.

But with the arrival of PowerApps Component Framework, you can build custom components/controls that can be used in fields or view fairly quickly. PCF entered public preview around April, 2019. The are three things that you will be using while developing a custom components/control: PCF, the framework that can be used to build the components, a CLI (similar to yeoman, if you are from node world) that is used to scaffold, build & deploy the control and a test harness to assist you during development.

What do you need to know to build components/controls using PCF

  1. TypeScript (preferable) or JavaScript
  2. NodeJS
  3. Ability to run commands from commandline
    • If you don’t like to live in the commandline, download XrmToolBox tool called PCF Custom Control Builder by Danish
  4. React (preferable)
  5. Office UI Fabric  (preferable)
  6. Edge Dev Tools or Chrome Dev Tools (while build/debug)
  7. Fiddler (while build/debug)

Where do I go to get inspired or assess the capabilities

There are couple of places:

  1. Community Content on PCF Forum
  2. PCF Gallery

In this post I will share a control that I built using PCF that displays the view as a set of cards. Here is how it looks on the contact grid when you choose the Full layout.

Full Layout

You can also display the result in the compact layout.

Compact Layout.png

Clicking on the card takes you to the record, and you can load more records, by clicking on the “Load more” button on the command bar.

In order to install the control, you would first need to install the managed solution by downloading from

After you have downloaded and installed the managed solution, you can add the PCF component/control to an existing view or new view.

View Properties

As you can see above, I am configuring the view to show the results using “Cards” control, and not “Read only Grid” control. After this you need to configure each property to the correct field on the entity, that you would like be shown on the card.

Card Layout

Card Props

Each property on this control maps to the card as below


How do you get the image to display on the custom control?

If you don’t need image on the card, you can skip this step. This is the tricky bit. There is a field on each entity that is capable of storing a image. The name of the field is entityimage. This screenshot should jot your memory.

Upload Image.png

You cannot however, add the entityimage field to a view, as this field is not visible in the View Builder: both classic experience and maker experience. But, entityimage is a valid field, so you can add this field using the awesome tool called “View Designer” in XrmToolBox.

View Designer.png

This allows you to modify both the FetchXML and LayoutXML of the view. Using this tool you can add the “entityimage” field.

Edit View.png

Once you do this, you can see the entityimage field on the view in the classic designer. If you try to open the same view in the modern designer it will fail.

PCF View

After save and publish, you should now be able to use the custom control on the view that it is bound to. You can also use a custom control to display results on the Quick Find as well, using similar update to FetchXML and LayoutXML, but Quick Find does not seem to be supporting entityimage attribute at the moment.

I hope this is an useful control that everyone can use.

Further reading:

  1. Using TypeScript with modern React (YouTube)
  2. Office UI Fabric Controls
  3. Office UI Fabric CodeSandBox
  4. What are custom components (
  5. PCF Forum

People to Follow for PCF

  1. Andrew Butenko
  2. Andrew Ly
  3. Aung Khaing
  4. Greg Hurlman
  5. Jose Aguilera
  6. Oleksandr Olashyn
  7. Vignesh

Embedded Canvas App: User Settings Utility

User Settings utility is a popular XrmToolBox tool that helps administrators update the user specific settings in bulk, without asking individual users to update them. Here is how it looks:

User Settings Utility.png

I attempted to do this using embedded canvas apps. Here is how it looks:

Business Unit Form

As you can see the canvas app is embedded inside the “Business Unit” form called “Business Unit – Users”. It initially displays a list of users in the Gallery. You can then click on an user record to edit the user’s settings.

Edit Settings

The canvas app currently uses the ModelDrivenFormIntegration datasource, that is the default for embedded canvas app. But, you could very well tweak this app to make it a regular canvas app, and then you would be able to edit the user settings from your phone on the go, which could be quite useful for an administrator.

You can download the managed solution from!AvzjERKFC6gOxDDJp_ZoVc2Pqw7x?e=sNq5Gq. The solution contains the following components:

  1. New view – “Enabled Users for UserSettings” on System User entity
  2. New form – “Business Unit – Users” on Business Unit entity
  3. Canvas app – “User Settings Utility”

User Settings Utility Solution.png

Hope this is a useful tool for admins.



Getting entity record counts

There are couple of ways to gets entity record counts: you could use XrmToolBox’s Record Counter Tool, or write the FetchXml to count the records as you navigate from one page to the next. But, if you just want to use the SDK here is a simple method: a new message called RetrieveTotalRecordCountRequest. Here is how to use it in C#:

var r = new RetrieveTotalRecordCountRequest();
r.EntityNames = new[] {
"contact", "account"
var m = ((RetrieveTotalRecordCountResponse)this.Execute(r)).EntityRecordCountCollection;

Retrieve Record Count

Here is the same call in JavaScript:

var entities = ['contact','account'];
fetch(`${Xrm.Utility.getGlobalContext().getClientUrl()}/api/data/v9.1/RetrieveTotalRecordCount(EntityNames=@EntityNames)?@EntityNames=${encodeURIComponent(JSON.stringify(entities))}`, {
	credentials: 'include',
	headers: {
		'accept': 'application/json',
		'content-type': 'application/json; charset=utf-8',
		'odata-maxversion': '4.0',
		'odata-version': '4.0',
	method: 'GET',
	mode: 'cors'
.then(x => x.json())
.then(r => console.log(r.EntityRecordCountCollection.Keys.forEach((k, i) => console.log(`${k}: ${r.EntityRecordCountCollection.Values[i]}`))));

Retrieve Record Count JS

Hope this is useful.


Triggering Flow from NFC cards

I recently came back from Sydney and I now have 4 new Opal cards. Opal card is used in public transport across Sydney and these cards use NFC technology. Since I no longer have any use for these cards in Melbourne, I wanted to do some thing productive with these cards. I also wanted to try a low cost alternative for triggering Flow from a hardware that is not flic (Opal cards are free).

Reading NFC card is not a native functionality of Flow, so I decide to use something that is capable of reading NFC card and also can call a HTTP endpoint. Since I am using Android, there is an app that meets this need perfectly. It is called Automate. This app has been around for a while, and you can develop Automate Flows that can use native hardware capability of Android.

Here is how my Flow looks in Automate.

Automate Flow

The are start important blocks to get this Automate Flow working:

  1. Read NFC Tag
  2. HTTP Request
  3. Flow Start

Read NFC block is used to read the NFC card. I map the NFC tag id to the variable called “TagId”. You can use the “Read tag” button in this to identify the NFC tagid and then use it in the switch/case statements in Microsoft Flow.

Read NFC


The next step in the one where I call Microsoft Flow, which is triggered by HTTP Request.

HTTP Request

The same Automate Flow has to be triggered again after Microsoft Flow is called using HTTP Request, so that a new fiber is started to continue reading the NFC card.

Start Flow

This is the Microsoft Flow that is triggered by HTTP request.


The HTTP trigger accepts the tagId in the URL parameter of the HTTP Request.

HTTP Trigger

Based on what tag has been scanned, I can then perform the appropriate action. I use the switch statement for this purpose.

Flow Switch.png

Here is a quick demo of Automate and Flow working together in harmony.

Automate Flow.gif

Here are somethings that are now possible with the NFC capability:

  1. Deploy solution from DEV to TEST, using Azure Function, PowerShell and Xrm.Data.PowerShell module. I experimented with this and it works nicely even though PowerShell support in Azure Function is only experimental
  2. Call a RunBook in Azure Automate using HTTP Webhook

I hope this is useful in scenarios where you need alternate ways to trigger Microsoft Flow.



Quick Tip: CDS Base URL in Flow

I have a Flow that sends out email at 8 a.m everyday that lists the solutions that were imported in the past 24 hours. In the initial version of the Flow, the email was missing an link to the actual solution. But, after making some changes, the email now includes a clickable link to the solution that was imported.

Flow Email.png

As you can see there is a link in the last column. This link is not hardcoded. The base URL changes, based on the CDS environment the Flow is deployed to. The trick is to grab this URL from the “List records” action which includes the full URL to each record in the result. You just need the first record in the result set to use in the expression in the next step.


As you can see the key contains the full URL to the record, from which you just need the base URL. Once you grab the base URL, you can easily compose the full URLs to the areas that you want the link to navigate to e.g. open the record, open solution, new record, open list etc.

Below is the expression that I use to get the base URL only.

If you use this expression and assign it to a variable, you can set the variable with the base URL.
This technique is quite useful if you are sending emails with clickable links that navigate to a CDS record or area.


Excel to JSON using Flow

I was reading through Scott’s recent post -> and I was thinking that this could be done in a codeless way using Microsoft Flow. So, I tried to do this in Flow, and it was really easy to do this – under 15mins, as all the plumbing is already there. This is my Flow.

Excel to JSON Flow.png

The Flow is triggered by a HTTP GET and reads from an Excel file stored in OneDrive.

Trigger and Source.png

The output is already a JSON, but not a valid one probably one, as it has spaces and special characters in the key names, which map to the column names of the table.

Excel JSON.png

So, we can simply re-shape the data using Select, and dump the JSON response.

Select and Response.png

Now, when I call my trigger URL, the Flow executes and returns me the JSON.

Response JSON.png

With Flow add-on for Excel, you could run the same Flow from Excel itself, if you want to.

Hope you find this useful.