Skip to main content

Notifications

Community site session details

Community site session details

Session Id : O0egRQceG0yGzn9kgZ1EpY
Power Apps - Microsoft Dataverse
Answered

Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

Like (0) ShareShare
ReportReport
Posted on 27 Jun 2024 13:57:19 by 36

Hi all,

I want to streamline my deployments, and have therefore created a PowerShell script that deploys an ARM template to Azure, and then have some output parameters that I would like to use to do the following:

 

  1. Create a ServiceEndpoint
  2. Create Steps:
    1. Listen on Update of entity Contact, on fields firstname and lastname

My problem is the final step - When creating Steps - An error is returned.

 

First off, here is my PowerShell script - I'll explain my steps afterwards:

 

 

# Perform deployment
$deploymentOutput = az deployment group create --name $deploymentName --resource-group $resourceGroup --template-file ".\$deploymentFolder\azuredeploy.json" --parameters ".\$deploymentFolder\azuredeploy.parameters.$environmentName.json" --output json | ConvertFrom-Json

# Check deployment output structure
if ($deploymentOutput -and $deploymentOutput.properties -and $deploymentOutput.properties.outputs -and $deploymentOutput.properties.outputs.'ServiceBus-PrimaryKey' -and $deploymentOutput.properties.outputs.'ServiceBus-PrimaryKey'.value) {
 $confirmation = Read-Host "Do you want to register a webhook within Dataverse? (yes/no)"
 if ($confirmation -ne "yes") {
 Write-Host "`nDeployment complete - Webhook skipped."
 exit
 }

 # Extract necessary values
 $primaryKey = $deploymentOutput.properties.outputs.'ServiceBus-PrimaryKey'.value
 $serviceBusName = $deploymentOutput.properties.outputs.'ServiceBus-Name'.value
 $keyVaultName = $deploymentOutput.properties.outputs.keyvaultName.value

 # Retrieve secrets from Key Vault
 Write-Output "`nRetrieving secrets..."
 $secrets = @{}
 @('CRM-ClientId', 'CRM-Secret', 'CRM-TenantId', 'CRM-Endpoint') | ForEach-Object {
 Write-Host -NoNewline "."
 $secrets[$_] = (az keyvault secret show --vault-name $keyVaultName --name $_ --query "value" -o tsv)
 }

 $clientId = $secrets['CRM-ClientId']
 $clientSecret = $secrets['CRM-Secret']
 $tenantId = $secrets['CRM-TenantId']
 $dataverseUrl = $secrets['CRM-Endpoint']

 # Define Dataverse environment URL and authentication profile name
 $envName = "PAC-$environmentName"

 # Authenticate to Dataverse using PAC CLI
 #Write-Output "`nAuthenticating PAC"
 #pac auth create --environment $dataverseUrl --tenant $tenantId --applicationid $clientId --clientSecret $clientSecret --name $envName

 # Get access token using Azure AD App details
 $tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body @{
 client_id = $clientId
 client_secret = $clientSecret
 scope = "$dataverseUrl/.default"
 grant_type = "client_credentials"
 }

 $accessToken = $tokenResponse.access_token
 $webhookName = "Integration-ServiceBUS"
 $serviceBusUrl = "sb://$serviceBusName.servicebus.windows.net"

 # Check if the webhook already exists
 $existingWebhook = Invoke-RestMethod -Method Get -Uri "$dataverseUrl/api/data/v9.2/serviceendpoints?`$filter=name eq '$webhookName'" -Headers @{
 Authorization = "Bearer $accessToken"
 }

 # Define the payload for the webhook registration
 $webhookPayload = @{
 messageformat = 2
 name = $webhookName
 contract = 6
 authtype = 2
 saskeyname = "DataverseSender"
 saskey = $primaryKey
 namespaceaddress = $serviceBusUrl
 solutionnamespace= $serviceBusName
 description = "Service Endpoint for ServiceBUS"
 path = "crm-contact-changed"
 namespaceformat = 2
 } | ConvertTo-Json -Depth 10

 # Either PATCH existing or POST new
 if ($existingWebhook.value.Count -gt 0) {
 Write-Output "Service Endpoint already exists - Patching"
 $serviceEndpointId = $existingWebhook.value[0].serviceendpointid
 Invoke-RestMethod -Method Patch -Uri "$dataverseUrl/api/data/v9.2/serviceendpoints($serviceEndpointId)" -Headers @{
 Authorization = "Bearer $accessToken"
 "Content-Type" = "application/json"
 "If-Match" = "*"
 } -Body $webhookPayload
 Write-Output "Webhook updated successfully."
 } else {
 Write-Output "Service Endpoint was not found - Creating new"
 Invoke-RestMethod -Method Post -Uri "$dataverseUrl/api/data/v9.2/serviceendpoints" -Headers @{
 Authorization = "Bearer $accessToken"
 "Content-Type" = "application/json"
 } -Body $webhookPayload
 Write-Output "Webhook created successfully."
 }

} else {
 Write-Output $deploymentOutput
 Write-Output "`nThe expected output structure is not present. Please check the deployment output."
}

 

 

 

My ARM template creates a ServiceBus, a Key Vault and other resources. After creation I get some output parameters, among those is the ServiceBus endpoint, ServiceBus name and Key Vault name. And that is used by the PowerShell script to create the ServiceEndpoint.

 

Using Plugin Registration Tool (PAC Tool PRT) I am able to see my ServiceEndpoint:

Ruprect_0-1719495387211.png

However when I try to create the SdkMessageProcessingSteps I have the following PayLoad:

 

{
 "supporteddeployment": 0,
 "stage": 40,
 "statuscode": 1,
 "customizationlevel": 1,
 "description": "Integration-ServiceBUS: Update of contact",
 "statecode": 0,
 "rank": 1,
 "asyncautodelete": true,
 "name": "Integration-ServiceBUS: Update of contact",
 "solutionid": "fd140aae-4df4-11dd-bd17-0019b9312238",
 "ismanaged": false,
 "versionnumber": 332817509,
 "mode": 1,
 "introducedversion": "1.0",
 "canbebypassed": false,
 "filteringattributes": "firstname,lastname",
 "enablepluginprofiler": false,
 "componentstate": 0,
 "canusereadonlyconnection": false,
 "eventexpander": null,
 "configuration": null,
 "category": null,
 "plugintypeid@odata.bind": "/plugintypes(ef521e63-cd2b-4170-99f6-447466a7161e)",
 "sdkmessageid@odata.bind": "/sdkmessages(20bebb1b-ea3e-db11-86a7-000a3a5473e8)"
}

 

The PluginTypeId is Microsoft.Crm.ServiceBus.ServiceBusPlugin (found by querying 

"https://xxxxx.api.crm4.dynamics.com/api/data/v9.2/plugintypes" and searching for the name:
Ruprect_1-1719495685384.png

And SdkMessageId is "Update":

Ruprect_2-1719495775966.png

However the error I get is this:

 

{
 "error": {
 "code": "0x80040256",
 "message": "Action failed for assembly 'Microsoft.Crm.ServiceBus, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35': No publisher is found, assembly must be registered in isolation."
 }
}

 

 

So if anyone has created the Steps through API - Any help would be appreciated.

 

I am able to create the step in Plugin Registration Tool (not through XRM toolkit):

Ruprect_3-1719495984293.png

But not by REST Api

 

Categories:
  • Verified answer
    Ruprect Profile Picture
    36 on 29 Jun 2024 at 23:31:04
    Re: Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

    @parvezghumra 

    I finally found my missing parameter, on the following article: https://devblogs.microsoft.com/ise/registering-plugins-in-dataverse/ there was a description of fields necessary.

     

    And my missing parameters was :

     

    "eventhandler_serviceendpoint@odata.bind":"/serviceendpoints(a1842d7d-6e36-ef11-8409-7c1e521fb863)",
    "sdkmessagefilterid@odata.bind": "/sdkmessagefilters(83c9bb1b-ea3e-db11-86a7-000a3a5473e8)",

     

     

    The EventHandler is the ServiceBus reference, and the SDK message filter Id is the Entity I wish to subscribe to - In this case "Contact".

     

    So my final payload to register the Step is:

     

    {
     "name": "Integration-ServiceBUS: Update of contact",
     "description": "Integration-ServiceBUS: Update of contact",
     "eventhandler_serviceendpoint@odata.bind":"/serviceendpoints(512414c1-7434-ef11-8409-000d3ab2c00a)",
     "sdkmessageid@odata.bind": "/sdkmessages(20bebb1b-ea3e-db11-86a7-000a3a5473e8)",
     "plugintypeid@odata.bind": "/plugintypes(ef521e63-cd2b-4170-99f6-447466a7161e)",
     "sdkmessagefilterid@odata.bind": "/sdkmessagefilters(83c9bb1b-ea3e-db11-86a7-000a3a5473e8)",
     "supporteddeployment": 0,
     "asyncautodelete": true,
     "filteringattributes": "firstname,lastname",
     "rank": 1,
     "stage": 40,
     "statuscode": 1,
     "mode": 1
    }

     

    And this creates my much wanted Processing Step on my ServiceEndpoint

  • Ruprect Profile Picture
    36 on 29 Jun 2024 at 21:16:33
    Re: Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

    @parvezghumra 

     

    The final deployment will be part of a managed solution.

     

    However, I would like to create the ServiceEndpoint - And Plugin Steps through API to do it at the same time as my ARM template is deployed. After creation it will be added to the solution, which will then be deployed onto production as managed.

  • Parvez Ghumra Profile Picture
    1,579 Super User 2025 Season 1 on 28 Jun 2024 at 17:42:58
    Re: Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

    @Ruprect If you are trying to do this for deployment reasons via the Web API, I would recommend deploying the ServiceEndpoint and SDK Message Processing Step as part of a managed solution deployment instead. This way the objects will be in a managed state.

  • Ruprect Profile Picture
    36 on 27 Jun 2024 at 18:08:40
    Re: Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

    @parvezghumra Originally I used a licenced user in Plugin Registration Tool, and an App Registration in Postman, but I have also tried with the same licensed user in Postman - To no avail.

     

    It might be some part of the payload I've missed, but if I remove the plugintypeid@odata.bind or the sdkmessageid@odata.bind I get a missing parameter error:

     

    {
     "error": {
     "code": "0x80040200",
     "message": "plugintypeid is missing."
     }
    }
  • Parvez Ghumra Profile Picture
    1,579 Super User 2025 Season 1 on 27 Jun 2024 at 15:45:06
    Re: Create ServiceEndpoint and SdkMessageProcessingSteps after deployment of ARM template

    @Ruprect Are you using the same user account to register the SDK Message Processing Step via the Web API as you do when you're doing it using the Plugin Registration Tool? Does that user have System Administrator privileges?

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Understanding Microsoft Agents - Introductory Session

Confused about how agents work across the Microsoft ecosystem? Register today!

Markus Franz – Community Spotlight

We are honored to recognize Markus Franz as our April 2025 Community…

Kudos to the March Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard

#1
WarrenBelz Profile Picture

WarrenBelz 146,670 Most Valuable Professional

#2
RandyHayes Profile Picture

RandyHayes 76,287 Super User 2024 Season 1

#3
Pstork1 Profile Picture

Pstork1 66,011 Most Valuable Professional

Leaderboard

Featured topics