Sometimes you need to work with the URL of your CRM within Power Automate, for example:
to relate or unrelate two records with the Common Data Service (current environment) connector
or writing an email with a hyperlink to a record.
If you have a multi-staged environment and you build your Flow solution aware, you don’t want to update your static URLs after each transport.
‘Recycle’ the OData Id from a previous CDS action.
We need an previous CDS action that has an OData Id within its output (like shown above). If you have no action like this, consider to create a “List records” action which is limited to 1 by the “Top count” option.
Create a “Compose” action and give it the OData_Id as input.
Create an other “Compose” action and give it following expression to receive the CRM URL.
Email marketing tools automatic add query strings at the end of urls of your hyperlinks. That’s a common way to pass additional informations to the target website inside of hyperlinks. Mostly these are informations about which channel the visitor came and to which campaign the visit is related to.
The target website should validate the passed query strings and ignore them if it don’t know what to do with. But sometimes you a have target website that crash painfully with a 404 error.
Solution – Mask query strings
Instead of trying to fix the targets understanding of the query strings, you can mask the query strings when you create the hyperlink in your email marketing tool. Just put the anchor identifier “#” at the end your link url. By that way the recipients web browser interprets the query string as an anchor within the target website. As there is no anchor text with that name on the target website, it has no effect. That’s in the specification of HTML since version 4.01 from 1999 – yes that was is in the last century.
You see how important it is to test your mailing with real recipients.
At the moment, everytime you reopen the editor the above setting is unchecked and it doesn’t work in the form.
The following code will override the original code to add an additional validation. You can add other or even more freemail providers to met your requirements. Just insert it in the CodeEditor of the forms designer.
// enable or disable the filter functionality
var filterFreemail = "true";
// customize the message provided to the user when a freemail address has been entered
var clickd_MSG_FREE_EMAIL = "We accept only business email addresses.";
// customize the array of blocked freemail providers to met your requirements
var blockedFreeEmail = ["hotmail.com", "gmail.com", "yahoo.com", "aol.com"];
// default ClickDimensions function, extended with our own validation
var isValid = true,
isAllowed = true,
reqFieldList = clickd_jquery("input[name='reqField']", "#clickdimensionsForm");
for (var i = 0; i < reqFieldList.length; i++)
// default validation
isValid = ValidField(clickd_jquery(reqFieldList[i]));
// custom validation
isAllowed = AllowedField(clickd_jquery(reqFieldList[i]));
isValid = false;
// own validation, copied and modified from ClickDimensions original
var fieldType = hidden.attr("alt");
var fieldID = hidden.val();
var fieldString = "";
var field = clickd_jquery("#" + fieldID);
if (clickd_jquery("#cont_id_" + fieldID).attr("wasskipped") == "1")
var infoId = "required_info_" + fieldID;
infoId = infoId.replace("f_upload", "f");
var info = clickd_jquery("#" + infoId);
var infoText = clickd_jquery(info).text();
if (infoText != "")
if (fieldType.toLowerCase() == "email")
fieldString = clickd_jquery(field).val();
if (fieldString.length > 0)
fieldString = fieldString.replace(/\s+$/gm, '');
if (fieldType.toLowerCase() == "email" && fieldString.length > 0)
var domain = fieldString.split("@").toLowerCase();
// set field invalid for freemail provider
if (filterFreemail.toLowerCase() == "true")
for (var i = 0; i < blockedFreeEmail.length; i++)
if (domain == blockedFreeEmail[i])
SelectNotValidInput(info, field, clickd_MSG_FREE_EMAIL);
If you’ve ever had contact with a Dynamics 365 portal, you’ve probably noticed the “Azure AD” button. This enables authentication with the Azure AD of your Dynamics environment.
But we had an error when rolling out the portal, so I had to restart the process. After successful completion, the portal could be reached at “MYURL. microsoftcrmportals. com”, but the Azure AD registration failed.
I will spare you the execution of my whole Trail&Error orgy and tell you what the problem is.
During the deployment the reply addresses of the registered Azure AD APP have been missconfiguered. To find it navigate in your browser to portal.azure.com and click:
The reply addresses looked like (notice the “1” at the end of the subdomain)
At the moment I’m setting up a community portal, where it is planned that the users can register themselves.
The portal users should also be able to enter their company name. To do this, I use the field “adx_organizationname” provided by the portal because with an account lookup everyone could see our customers. The backoffice then checks whether this contact is related to an existing company or a new one. As soon as the contact is then connected to an account record, the organization name should no longer be changeable by the portal user.
What not worked
Add the field twice to the form to have one editable and one readonly and hide the the not applicable with jQuery in the portal. The same fields two times on the profile form let the portal crash.
Make the field readonly on the CRM form and enable it in the portal with jQuery did not save the data back to CRM.
I have created a separate section for the company-related fields
and make it read only when parentcustomer is not empty.
This creates following tag in the HTML structure.
The result looks like this.
Oh wait, happy times, Dynamics portals has arrived my blog for the first time!
Here it is fo you: Get isActivity from Metadata
var req = new XMLHttpRequest();
req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/" +
"EntityDefinitions(LogicalName='" + strEntityLogicalName + "')?$select=IsActivity", false);
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function ()
if (this.readyState === 4)
req.onreadystatechange = null;
if (this.status === 200)
var result = JSON.parse(this.response);
var isActivity = result.IsActivity;