I think that Microsoft Dataverse for Teams (old name Project Oakdale) is the most important Power Platform announcement of the year, especially you are coming from a canvas apps background like myself. Teams are starting to be more and more of a platform for the business than a replacement for Skype. Now, with Microsoft Dataverse, users will have a real data capability and a route to future upgrades by transferring their application on top of Common Data Service if needed. Teams and Microsoft Dataverse for Teams apps offer the needed simplicity to build those small or even large everyday business apps that truly matter for the users.
There are multiple posts and how-to guides to learn Microsoft Dataverse for Teams and canvas apps development, so there is no need to go deeper. One thing that got my attention during the Ignite was the announcement of using Azure API Management with Dataverse for Teams solution through the existing Teams licensing!
This means that your professional developers can create API services to process data and connect to almost any enterprise service. Then the citizen or IT pro developers can leverage those functionalities on their application. These functions will be technically published as custom connectors to the Power Platform environment related to the Dataverse in Teams.
Earlier, this meant that you needed an extra license because a custom connector is a premium level connector, but now that is not needed with Dataverse for Teams environments. Let us see how to use this in real action. Again, we can use something easy for even non-developers and create an Azure Function with PnP PowerShell (I did write about this earlier).


This post is a long one, so here are quick links to different sections:
Create Azure Function
Let us keep things simple and create an application that asks for some data from a user and then creates a new News page to SharePoint. We will also fetch some additional information from an “enterprise” service with a rest call during the creation process. The idea is to ask the title and the body from the user and then fetch some data from the Bacon Ipsum service and add it to the news page.
The source code of the function can be found from my GitHub. It is a lot easier to read the code from there, but I will cover the most important parts here: PowerShellCore / CreateBaconPage.
When I am creating PowerShell scripts, I have a habit of using the following type of structure. I think this helps to read and maintain the code.
- Start by reading the Azure Function request parameters if developing a function.
- Set the main internal parameters, like connection related, used in the function.
- Read the possible modules if needed.
- Then inside the first try-catch, open the necessary connection, for example, to SharePoint.
- Then check that all mandatory parameters are available. I have a parameter called $haveMainParameter that I update while checking the other parameters.
- If we have everything available and connections are open, we can start to run the main section of the program.
- In the last section, I am closing all the connections.
- If developing a function, I am pushing the return details so that the callers can continue their process.
- Create a new Azure Function with Visual Studio Code.
- We need to fetch three parameters from the request.
- News title
- Body of the news
- Paragraph amount (int value) to be used in our service call to Bacon Ipsum
$newsTitle = $Request.Query.newsTitle
$newsBody = $Request.Query.newsBody
$meatParas = $Request.Query.meatParas
- Next, add the necessary parameters used to connect to SharePoint.
- This time we will need to authenticate against SharePoint with users’ credentials because you cannot create pages with an app-only connection.
- Make sure to save the credentials securely. I did use the application settings in this example, but Azure KeyVault is a better option.
- Now you can make a connection to SharePoint.
- As a best practice, it is recommended to return the connection to a parameter and use every PnP function call.
- This helps you overcome a possible mixing of the connection context that can happen when executing the parallel function. You will see ‘The object is used in the context different from the one associated with the object.’ error message when mixing happens.
$spConn = Connect-PnPOnline -Url $siteURL -Credentials $credential -ReturnConnection
- Now it is time to check that we have all the necessary parameters and connections available.
#Check the parameters necessary for the application
Write-Host " "
Write-Host "*Check the parameters necessary for the application"
If($spConn -and $newsTitle -and $newsBody -and $meatParas){
#Parameters are available
$haveMainParameters = $true
}
else {
#Missign some parameters
$haveMainParameters = $false
}
- If the parameters are OK, we can continue building the logic.
- First, let us create a basic page with a title and content.
- As you can see, I like to write messages to the PowerShell host console a lot. I think this helps you with debugging and testing.
Write-Host " "
Write-Host "*Create the new page"
#Create basic section
Write-Host "..create basic section"
$newsPage = Add-PnPClientSidePage -Name $newsTitle -PromoteAs NewsArticle -Connection $spConn
Add-PnPClientSideText -Page $newsPage -Text $newsBody -Connection $spConn
#Connect to enterpise service
$baconText = GiveMeBacon -meatParas $meatParas #Save for later -meatType $meatType
- At this point, remember to save the function and test the logic by hitting F5.
- You will see the URL for the local test service when the build is done.
- Remember to add the necessary parameters to your call: http://YOUR_LOCALHOST/api/CreateBaconPage?newsTitle=TestTitle&newsBody=Hello World&meatParas=2&meatType=all-meat
- If the function works correctly, you will see new news on the SharePoint site.
Connecting to Enterprise Service
Now, let’s look at an example where we fetch some data from an enterprise service outside of Office 365 scope. As a test, let’s get some random text from the Bacon Ipsum service. We will do this by adding a custom module with the necessary logic into our Azure Function.
- I like to add a folder for my custom folder.
- Add CustomModules -folders and EnterpiseAPI.psm1 file into it.
- Inside the module, we only need to add one function that is then exported to function logic.
function GiveMeBacon{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, HelpMessage="Amount of meat")]
[string] $meatParas
)
#**Give me bacon from - baconipsum.com
Write-Host "#*#Give me bacon from - baconipsum.com"
$response = ""
try {
$queryURL = ("https://baconipsum.com/api/?type=all-meat¶s={0}&start-with-lorem=1&format=text" -f $meatParas)
$response = Invoke-RestMethod -Uri $queryURL -ContentType "application/json; charset=utf-8" -Method Post -UseBasicParsing
}
catch {
$ErrorMessage = $_.Exception.Message
Write-Host "**ERROR: #*#Give me bacon"
Write-Error $ErrorMessage
}
return $response
}
Export-ModuleMember -Function GiveMeBacon
- Here is a quick overview of the function:
- First, read the parameters for the paragraph and text type.
- We need to construct the URL that we are calling and make a rest call against that URL.
- As a response, we will get a random text set that we then return to the caller.
- Of course, in real life, an enterprise service connecting is most likely a lot complex, but this gives you an idea of building one.
- Next, let’s use this new logic in our original function. The first thing to do is to add a reference to the module.
- Add the following text line at the beginning of your Azure function somewhere after the Input binding section.
#Get custom modules
$SP_ModulePath = $PSScriptRoot + "\CustomModules"
Import-Module "$SP_ModulePath\EnterpiseAPI.psm1" -Force
- Now we can extend the page creation by calling the enterprise function and adding the returned text into a separate section on the page. Add the following logic after the initial page creation section.
#Connect to enterpise service
$baconText = GiveMeBacon -meatParas $meatParas #Save for later -meatType $meatType
#Add related section
Write-Host "..add related section"
Add-PnPClientSidePageSection -Page $newsPage -SectionTemplate OneColumn -ZoneEmphasis 2 -Connection $spConn
Add-PnPClientSideText -Page $newsPage -Column 1 -Section 2 -Text "<h3>Related Info</h3>" -Connection $spConn
Add-PnPClientSideText -Page $newsPage -Column 1 -Section 2 -Text $baconText -Connection $spConn
#Add related section
Write-Host "..publish the page"
Set-PnPClientSidePage -Identity $newsPage -Publish -Connection $spConn
Again, you can test the function to make sure a correct type of page gets created to the SharePoint. When everything is working correctly, you can publish the function in Azure.
Microsoft Dataverse for Teams Application
Now let us go teams open the Power App application so that we can create and Dataverse application. The application is simple, with some data fields and a button. You can see the structure from the image below.

- I added a variable called EnableSendBtn to the OnStart setting of the App. We will use this parameter to enable and disable the Send button to send the form details only when all the necessary details are given.
- I added the following elements to the screen.
- A one-line text box for the title of the news page.
- A multiline text box for the body.
- A number field used to give the number of paragraphs fetch from our enterprise service.
- Here are a few important things to notice from my example:
- Remember to give a unique name for each element on the screens. This will help you to build and maintain the logic.
- First, we set the EnableSendBtn as false to disable the button for the API call time.
- The last two sections will enable the button again after the call and resets the form controls.
- The DisplayMode setting of the Send button has the following logic:
If(
EnableSendBtn And Not(IsBlank(txtNewsTitle.Value)) And Not(IsBlank(txtNewsBody.Value)) And Not(IsBlank(txtDetailsParagraph.Value)),
DisplayMode.Edit,
DisplayMode.Disabled
)
But how to call the Azure Function we made earlier?
Configuring and Using Azure API Management
If you have not used or created API Management before, you can start exploring the service with this simple documentation: Quickstart – Create an Azure API Management instance | Microsoft Docs. I will cover the Project Oakdale related basic settings in the next steps. I assume that you have Azure Function that you want to publish an Azure API Management instance created.
- The documentation link above also has details on how to add your first API to the management instance.
- In this example, you need to add an Azure Function.
- You will see a form that you can use to find the necessary API details.
- Click Browse from the form.

- Next, click the “Function App.”
- You will see a list of available Azure Function Applications.
- Select the one that holds the function you want to publish.

- A list of available functions is shown, and you can select those you want to publish.
- Select the correct one and click Select.
- You will see the details of the function in a form.
- I recommend giving a meaningful name for the details of the details because it will help you find and use the API in Project Oakdale.
- Sure, these settings can be updated later also.
- Finally, click create.
- An important thing to notice here is that every Azure API Management API is protected with a subscription key by default. This key needs to be added to the API call, or otherwise, the user is getting access denied error.
- It is possible to turn the key usage off, but then the whole API would be public and don’t want that.
- You can find the keys from the Azure API Management portal under Subscriptions.
- Copy the necessary key, like the build-in primary key, because we will need that in the Power Apps side.

- In our function, there were three attributes that we need from the users. Those won’t be asked automatically unless we update the schema of OpenAPI details of the function and tell what we need.

- Select the post-call of our API and then click the edit link of the frontend section.
- We want to add new Query parameters to the function.
- You could write the JSON settings manually, but using the editor makes your life a lot easier.
- Create parameters for all the necessary ones used in your function. In my case, I only needed a string or integer type of attributes.
- Also, create one extra parameter for the subscription key called ‘subscription-key,’ type ‘String.’
- Remember to save the changes.

- Now we can export the function. In the export, there is an option for Power Apps and Power Automate available.
- In the export form, you see a dropdown box to select the Power Platform environment were to publish the connector.
- Ensure that you have at least one Power App created in Teams because otherwise, you will not see the environment in the list. Also, makes sure to select the correct environment (been there, done that).
- Give the connect a meaningful name and click export.
- It will take a few minutes to publish the API fully, but at this point, you can go to Teams and open the Project Oakdale application.
- In case the App is open, I recommend hitting refresh for the browser.

- In the App, you need to add a new Data Connection.
- Select Data from the left menu and click Add data.
- Find the API with the name you gave during the publishing time and click it from the list.
- A right popup menu will open, and you can click the Connect button from the form.
- At least for the current preview version for Project Oakdale, you will see a warning about the Premium connection. Based on Microsoft documentation, there is no need to take any extra action based on that.

- Now we are ready to use the API. Go to the OnSelect setting of the button in our App and start to add a line after the CALL AZURE API MANAGEMENT comment in our example.
- Remember to select the post-call of your function.
- Then you need to give the custom parameters and associate the values to the form elements.
- The final parameter, called ‘subscription-key,’ is the subscription key copied earlier. Without this key in the query, your API call will not be processed.
- My final logic of OnSelect of the Send button looks like this:
Set(
EnableSendBtn,
false
);
//CALL AZURE API MANAGEMENT
GiveMeBaconAPI.postcreatebaconpage(
{
newsTitle: txtNewsTitle.Value,
newsBody: txtNewsBody.Value,
meatParas: Value(txtDetailsParagraph.Value),
'subscription-key': "YOUR_KEY_GOES_HERE"
}
);
Set(
EnableSendBtn,
true
);
Reset(txtNewsTitle);
Reset(txtNewsBody);
Reset(txtDetailsParagraph);
PS. When writing this post, I have seen a couple of different setting options for the subscription key during the past week. This might because Project Oakdale is still in preview. Here I used one of the current working methods, but I will keep watching the progress and update my post if necessary.
- Now, we can save the application and make a test in the preview window.
When everything goes as planned, a new page is created to SharePoint with some enterprise service data. You can now continue to future develop the Project Oakdale app and publish it to the users. In case something goes wrong, you can check the possible errors in the Power App side after closing the preview windows. You can also debug the Azure Function by opening the monitoring and making a test call from the Power App. At this point, you will thank your-self for writing enough comments to the host inside your code.
