Talking about how he loves astronomy, some inclusion of salads, but more importantly a very important message around lifestyles & health. Also touching on how the community use technology to help with health matters.
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
Previously I’ve touched on how it’s possible to use Azure Active Directory for Dynamics 365 security. This can be of great benefit to an organisation, especially when needing to invite in external users. The details that I go into around it can be found at Dynamics 365 Security & AAD. As I point out there, it’s a very helpful feature, and can also help with onboarding new users within an organisation.
What I’ve found out about it, however, is that there can be some very interesting little quirks with how security actually works. Originally I thought it was a bug, and raised it with Microsoft Support, but it turns out not to be. Let me take you through the journey that I experienced last week…
The scenario is as follows. We had security set up in place, which was working perfectly (or so we thought). We’d gone through all of the following steps:
Create Dynamics 365 security role/s with appropriate permissions
Create AAD security group
Create Dynamics 365 AAD Security Team, and link it to the AAD security group
Assign users to the AAD security group
This was working exceptionally well (except, of course, when the external users hadn’t followed the setup instructions correctly). Users were logging in, searching for information, creating/updating records, etc. All was good…or so we thought.
Now, the users who are actually using the application don’t have a Dynamics 365 background. It’s the first time that they’re using the specific system, and as such, are going through a learning curve. We’re not expecting them to understand the advanced functionality at this point, though some of them are indeed venturing further/deeper into the capabilities that it brings.
One of these, of course, is the Advanced Find. Now, those experienced with Dynamics 365 will know all about it. There are good points, and there are not so good points. Functionality in it has expanded over time, though to be honest it’s still easier to run a SQL query/extract for more advanced information retrieval.
Users seemed to be fine with the Advanced Find. We showed them how it works, how to filter, set up columns, etc. We even showed them how to export data to Excel, and keep a live data connection back to refresh it!Brilliant – they were most pleased.
Then I got an email in from a user needing support. They reported that they weren’t able to save custom searches. This is of course very helpful, in order to avoid having to set up the same search/layout every time. This seemed puzzling to me, and I started to take a look into it.
Always download the error log file – it can be SO useful!
I was able to replicate the problem immediately with a test user, having assigned it the same security role. Opening the log file (which can be extremely helpful at times with troubleshooting), I looked to see what the issues were. I was thinking it was a problem with security permissions – if I assigned the system administrator role to my user, everything worked just fine.
In my error log, there were repeated references to ‘ObjectTypeCode”:4230’. This is the View settings in the security role. I therefore went to the security role, and ensured that it was set to allow access to Saved View across all permissions:
It’s only possible to set User-level permissions for Saved Views
Right – permissions set, all should be good. Let’s go ahead & try to save an Advanced Find as a view…but no! It’s still not working, and showing the same error message!
What I then tried to do was apply the security role directly to the user, rather than through the AAD security team. To my surprise (well, not really, actually), it worked. I was able to save Advanced Find views. I changed back to the user getting permissions through the security group (ie not directly), and again I had the issue.
OK – so I thought I had discovered a bug. As far as I was aware, I couldn’t see any reason why the user wouldn’t be able to save the Advanced Find view. After all, they’re able to create & save records within the system. There surely shouldn’t be any difference between saving records, and saving an Advanced Find view?
My next step was to raise a support ticket with Microsoft, and then carry out the obligatory ‘show & tell’ to the support agent. Ivan (the agent assigned to my case) was very helpful, understood exactly what I was trying to accomplish, and what the issue seemed to be. I left him with the support case, and focused on trying to find a workaround for the situation.
After a few days, Ivan came back to me with a resolution. It wasn’t a bug in the system (which was a shame – I was looking forward to having it attributed to me!), but rather a specific case of permissions.
See, there’s something called ‘privilege inheritance’. In a nutshell, there are two ways of giving access through a security role:
User privileges. This is when the user is given the permissions directly
Team privileges. This is when the user is given the permissions as a member of the team. If they don’t have User privileges of their own, they can only create records with the team as the owner
Users were able to read, create, update records without issues, as the team was the owner of these records
However as views need to be owned by a user (though they can be shared with a team), the user was unable to save them!
Thankfully it’s quite easy to fix – on the security role itself, you change it here:
With this then in place, everything then worked just fine. The user was still getting the role through the Security Team, but was now able to save these directly.
Quite an interesting little quirk, but one that is likely to come in useful when looking at other functionality within the system.
Have you come across this before? Have you found anything else that seems a little strange? Comment below – I’d love to hear!
Recently I’ve been doing a LOT of work with canvas apps. As I think I’ve mentioned before (at least once or twice!) my background is the traditional ‘model’ style app. As a result, it’s been quite a steep curve to skill up, but I think I’m handling it alright. I’m (slowly) getting used to the way that canvas apps work, the ability to put different controls on the screens, and reference each other.
Heck, I’m even starting to play with more advanced navigation concepts, based on some REALLY great ideas that I’ve seen (Clarissa, I can’t say how grateful I am to you for all of your assistance & guidance!).
Amongst all of this incredible & wonderous journey, I’ve also been learning some code. Yup – you heard me correctly! I’ve always said that I’m not a developer – I respect them greatly, but I don’t develop code.
True, I’ve picked up some SQL here & there, and will freely admit that running SQL queries against the Dynamics 365 database is SO much more powerful than running an Advanced Find. Of course, it’s necessary to know the joins, conditions & such. Redgate’s SQL Helper has been amazing along the way. With moving to cloud systems, things got a little more….complicated. XrmToolBox has the SQL4CDS tool which I’ve used several times, but I was really excited by the recent announcement/release of being able to (properly) run SQL commands against the CDS database from SQL Management Studio….
Anyhow, I’m digressing. So, I’ve been needing to learn canvas app style code. It’s like Excel commands, though (slightly) different at times. Things don’t always make sense (to me, at least) – I STILL haven’t figured out why some expressions need to be in a certain order. After all, according to mathematical principles it doesn’t matter if you write A>B, or B<A. Going to still need to wrap my mind around all of this.
In short, Patch allows you to set record values from places other than a form table to the data that you’re saving. It also allows you to save field values that aren’t available on the canvas form table (due to limitations). I’ve referred to this previously at https://thecrm.ninja/canvas-app-record-set-regarding-field/. The scenario that I talk about there is just one of the things that can be done in this way. Since that post, we’ve come a long way, and are doing most things with Patch statements (due to the scenario requirements).
So that’s all well & good. However, there IS actually a reason for me writing this blog post….crazy, right? And it’s not to waffle on and on about patch statements. It’s about a very specific scenario that we hadn’t come across to date, but that came up last week.
Now, obviously you’re now VERY interested in hearing all about it, and learning for your own situations. I mean, otherwise you wouldn’t have stuck with me through this article for so long. So, let me set out what happened.
As mentioned above, we’re mostly using patch statements throughout this specific app. That’s….quite a lot of patch statements (especially as we also have IF statements governing which one is being used, as it’s not possible to use IF inside a patch statement, but I’m digress…). I’d say we’re pretty familiar with this now.
However, even with being familiar with it, we suddenly had a problem. One of the forms that we’re saving down started to NOT save down. Records weren’t being saved, which obviously is a problem!
Bear in mind here that we hadn’t touched the code for this specific action for a few weeks. Nothing had changed in our code, and nothing had changed from a platform perspective (ie Microsoft hadn’t changed any of the underlying functionality.
Going into the statement, we immediately started testing it out, and saw something interesting. We were getting an error that a required field could not be NULL:
This was quite puzzling – although in a model app we can set fields as required, and users can’t save the record until they populate it, this isn’t true in a canvas app (well, when using Patch, at least). See, it’s technically possible to use a Patch statement to create/update a record, but you don’t have to pass in required field (values). It’s a sort of workaround (& can be used in some scenarios for benefit, actually). So this happening all of a sudden was quite strange to us.
It was even stranger as we hadn’t been using the field on the form at all. The field that was being referred to was being used for a totally different process, in a different team, & not surfaced into the canvas app at all. This really was causing us to scratch our heads, and try to think (more) out of the box. It didn’t seem to be the code (we could set a value in code, but didn’t want to as it wasn’t relevant), yet we weren’t able to ignore it. Really frustrating!
With all of this in mind, I decided to go back to absolute basics after a few hours of troubleshooting. The field that seemed to be causing all of these issues was a relatively new addition, so I checked all of the details around it:
Was the field type correct for what it should be? Yes
Was it set as required on the CDS field definition? No (not that I thought this would help, but still checked)
Was the field on the entity form? Yes
Was the field set as required on the entity form? No (again, I didn’t think I’d get any joy from this)
Hold on….on the form designer it’s not set as Required. But when I open the form, and put some values in, suddenly it IS required.
Aha! OK – I’m now starting to see some light shining on this. I headed over to Business Rules to check out what might be there. Lo & behold, there was a business rule that set the field as required (when certain conditions were filled). An example of this would be:
Now this field hadn’t been in place when the code was developed (as mentioned above) – it had come in since. I was very curious if a Business Rule could require canvas apps to set the value, and so did some testing.
Disabling the business rule removed the error from the patch statement. Re-enabling it caused the issue again. OK – so we’ve found what’s been causing this, and could put in an adequate solution to handle it.
So in short, if you’re setting a field as being required through a Business Rule, you’re going to need to address it in any canvas app as well (that’s saving data down to the same form that it’s appearing on). Why it actually happens, when just setting it as Required on the form doesn’t, I have NO idea.
But it’s a good concept to keep in the back of your mind, I believe. Especially if there are multiple people working on developing a single entity, as otherwise you could find yourself in exactly the same scenario that we did!
Have you come across anything like this, or a different piece of strange behaviour? Comment below – I’d love to hear about i!
Discussing Jonas’s love of sailing, boats, and growing up with them. Covering plugin recursions, the balance between a ‘perfect system’ & one that users can actually operate in, as well as the offer of a free XrmToolBox lesson for anyone who’ll build a specific tool!
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
Recently I’ve been expanding my knowledge of Power Automate, and how it works. It really is a truly amazing tool, though there can be some quirks to things! There are so many connectors to use, though I haven’t really used that many of them to date.
Truthfully, most of my work in Power Automate is around CDS & Office 365. Occasionally I’ll dip into another system, but for the most part that keeps me busy enough. It’s not to say I don’t want to explore further, but finding the time can be quite difficult!
One of the great abilities that Power Automate has is to be able to update a record. With focusing on CDS entities for the moment, we would use the inbuilt action for this:
We’d run a query to get a specific record – this would give us the record ID (or GUID, depending on your preference). With this, we’d use the Update Record action & pass in the record GUID. After all, we need to know which record we’re going to update! So for example:
What we can then do is set values for the record. So we can pass in Dynamics Content, use Expressions, etc. These can be from records that are part of our Power Automate query chain, or from elsewhere.
For example, I can say that when a contact’s postcode changes (or zip code for USA), go away, look up the new city, and update it (Note: I haven’t shown the postcode lookup part below):
So this is all really brilliant. Different fields have different behaviours, of course, and we need to respect that. Otherwise the Power Automate flow won’t run, and will error. This is, of course, the digital equivalent of not trying to force a square brick into a round hole!
What we can also do is clear a field value. If for example we’re wanting to remove a value from a field, we can use the NULL expression on the field. When the Power Automate flow runs, it’ll clear whichever value the field is currently holding:
Now, one of the the field types available within CDS is the lookup field. I’m not going to go into what this is, as we should already know this!. We can, of course, set lookup fields values to populate the field, which works as expected.
However (& thanks for bearing with me so far), what happens if we want to clear a lookup field value?
Say for example that we have a task, that’s assigned out to someone. If they reject the task, we want to be able to remove them from the task record. We wouldn’t delete the task, as we still need it (& now would need to assign it to someone else). We need a way to do this.
I can hear what you’re thinking right now – mentioned above is the use of NULL, so we’d use this! Um…well, you’d think so. You can try that, but we’ve found that doesn’t always work. Additionally, that doesn’t actually seem to remove the underlying relationship that’s been put in place.
Update: Thanks to Lin Zaw Winn, who dropped me a line to let me know further information around this. The standard CDS connector (the first one that was available) allowed this to work, but the updated CDS connector (Current Environment) doesn’t allow it. Unfortunately the different connectors aren’t at parity, which is a pity!
So, there’s another way to clear lookup field values. This involves the Unrelate action that’s also available. The steps for this are as follows:
Get the related record (lookup the record type, pass in the GUID for it)
Use the Unrelate action to remove the connection
This will then remove the relationship, which actually results in clearing the lookup field value. In practise (for our scenario), this would look like:
Let’s take a bit of a further look at the options available here:
The Relationship field is the relationship between the two entities (eg here it’s Contact & Task). Thankfully you don’t need to manually type this – it’s easily selected from a dropdown list.
The URL field is the linked record itself
Note: It’s VERY important to have the Entity Name & URL values in the right order. I’d suggest looking up the connected record first (ie what the lookup field is pointing to), and using that as the Entity Name value. You’d then select the record where the lookup is saved on as the URL value.
What I’d usually suggest as best practise is to have a condition before this takes place. As mentioned earlier, removing the lookup would happen on a record update. This is because you wouldn’t be removing a field value if you’re creating the record!
But you’re not always going to want it removed. In the scenario that I’ve been dealing with, we’re only wanting to remove the volunteer if they’ve rejected the assigned task. So our Power Automate flow is set out like this:
When Task record is updated
Filtering on the field for ‘Task Accepted’, as we could have other things being updated on the Task record that we don’t want to trigger this particular process
Condition to check the ‘Task Accepted’ field value
When it’s something other than ‘Rejected’, cancel the flow
When it’s ‘Rejected’, run the Unrelate process set out above, and stop flow
You can obviously build out other functionality within it as you so desire.
So with this in mind, how do you think you could benefit from this? Drop a comment below – I’d love to hear!
Covering his love of Brazilian JuJitsu, occasional wrestling matches with friends/colleagues, & how it can help with day to day life. Delving into a last minute RFP with a surprise inter-continental trip (such a shame that Concorde wasn’t around!), delivering a pitching session whilst carrying out discovery as well, and how the right approach can win what may seem to be an unlikely deal!
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
I come from an ‘on-premise’ background. I’ve spent years in organisations with on-premise systems such as Dynamics 365. Take me into a server room that’s alive with whirring fans, and I get quite nostalgic. Those were the days…well, in some ways, anyhow. But having recently discovered some quite helpful functionality, I thought I’d share it with others!
See, when it came to Dynamics 365 security, there was no way to automate things. Yes, users had to be created in Active Directory (and also, in a folder that the Dynamics install could refer to within AD!), but they had to be manually added to Dynamics 365. There was no way to automate this (from recollection – then again my memory grows dim with the fog of time).
So what the system administrators needed to do was to manually go to Settings/Security within the system, and there they could either add a single user at a time, or multiple users. They would then assign role/s (for multiple users, all of the users would need to have the same role/s – it wasn’t possible to modify individual users within this process).
One way to slightly speed up time in handling different security roles was to have teams, relating to the business needs. The security role/s would be created, assigned to a team, and then any user added to the team would automatically get all of the permissions that they needed.
Then came the heady world of Dynamics 365 being online! Well, nothing much changed really, at least not for a little while.
But then, things really did change, in May 2019. Functionality for security teams within Dynamics 365 was increased. Notably, there was now something called a ‘AAD Security Group Team’:
So what was this magical new item?
When we create a team, and we set the Team Type to ‘AAD Security Group’, we’re now able to set an AAD Object ID. In fact, it’s required! After we’ve created this object within Dynamics 365, we can then apply security role/s to it directly (as we could to any other team records beforehand):
Let’s take a moment to reflect & think on this. Until now, we’ve had to handle security directly within Dynamics 365. Now, we have the ability to have an Azure Active Directory (for that is what AAD stands for) group, and reference it within Dynamics 365.
Suddenly new possibilities open up. As part of the on-boarding process (for example) we can users to specific AAD security groups, which will then give them access with appropriate permissions within Dynamics 365. We’re also able to have multiple AAD groups, each inheriting a different set of Dynamics 365 roles, and thereby create a multi-layering approach to different business & security needs.
We’re also able to use tools such as PowerShell, LogicApps, Power Apps & Power Automate to carry out automation around this. There’s an Azure AD connector (https://docs.microsoft.com/en-us/connectors/azuread/) which gives the ability to set up & administer these.
We’re actually using this functionality now in some of our COVID-19 response apps. Instead of needing our own support desk to manage the (external) users, we’ve provided an interface where client IT departments can quickly log in, upload a list of users, and assign them to the relevant AAD group/s. It’s very quick, and allows the users to onboard to the Power Apps within minutes!
So with knowing this, how do you feel it might help benefit you? Comment below – I’d love to hear!
Recently we’ve been rapid producing & deploying solutions, due to the current pandemic. One of the apps that I’ve been working on required quite a few fields for data capture. Well, truthfully most apps require quite a few fields, but I thought that I’d talk about this one in particular, due to something that I discovered.
Now, we all know how to create fields in the Power Platform maker experience. It’s really quite simple – you select that you want to add a new field, put in the details/type of field, & save. Hey voila – you have yourself a nice new field! You can then go on to add it to forms, views, etc etc. We all know how it’s done:
What I’ve found myself doing recently though is not to create fields through the Maker interface (make.powerapps.com), especially when there are lots of fields to create. Instead, I’ve been using the XrmToolBox to do this. There’s a very helpful tool within it called Attribute Editor, which allows you to use an Excel spreadsheet. It takes this, and creates the relevant fields through the Dynamics 365 API.
One of the reasons for doing things this way was that it allows me to get on with other things whilst the fields are being created. Although it doesn’t happen in the blink of an eye (especially when there are a lot of fields to create), I can leave it whizzing along, and do something else. This, of course, makes me feel VERY productive!
Right – back to what I was saying. So I had a lot of fields to create, and many of them needed to be datetime fields. Actually, all I needed was the time component, but unfortunately Dynamics 365 DOESN’T allow you to just show the time. It’s either Date, or DateTime, but no option for JUST Time. A flaw, in my opinion, for what it’s worth….
So I created the Excel template, started the process, and went on to do something else. I of course made sure to specify that the field type should be ‘DateTime’.
Coming back to it when it had finished, I started to place fields on forms, and noticed something strange. All of the datetime fields that I had created through this were date ONLY. This was…puzzling! Going to check the fields themselves, they were set as Date ONLY, not DateTime!
I went back to check my upload spreadsheet, and it was set correctly there. I even tried uploading another field, but still the same issue was occurring.
Now, with the way that Dynamics 365/Power Platform works, once you’ve created a field & saved it, you can’t change the field type. When it’s created it’s saved down to the underlying database structure as the specified field type, and that’s it. No way to change it…or at least not through the front end!
With this in mind, I fired up another one of the XrmToolBox tools, namely Attribute Manager. What this handy tool does is, behind the scenes, allow you to change the field type. Well, it doesn’t ACTUALLY change it directly – it clones it, deletes the original, then clones it back. There are some caveats to it working properly (ie that the field isn’t used in a view somewhere, for instance), but it’s really helpful.
Note: It only works for custom created fields, not the default OOB fields!
Depending on the field type that you’re wanting to change it to, you can select different options. However for DateTime, there’s only one option. OK – I was going to see what happened.
Well, I ran the update, but nothing changed. It was still ‘Date’ only within the interface, which was really being incredibly annoying. It wasn’t as if I could just delete & recreate it (well, I could, of course). I had dozens & dozens of these to do, and quite frankly didn’t want to spend all of that time in doing this.
Thankfully (with the help of one of my colleagues, who’s an experienced & devoted developer – thanks Sid!), we found the solution.
See, I had been doing everything within the ‘new’ interface. This is the one that Microsoft keeps pushing everyone to, as they don’t want people to really be using the Classic Interface anymore. That’s all very well & good, but the ‘new’ interface isn’t on parity (for some things).
Reverting back to the Classic interface (note that the option below is only available when working within a solution!), we discovered some hidden behaviour
We located the entity that we needed, and the field itself, and opened it in Classic. With the screen that’s presented (I do miss this in some ways – I remember the days where I almost lived permanently in here!) we AMAZINGLY have the following option:
We can CHANGE THE TYPE!! Now, this is just with the field that we’ve selected. To be frank, I have no idea at this point about any other field types, and would need to explore that separately. But for the moment, my problem has been solved! (well, to the point that I have ‘time’ values available – I’d still like to see JUST time values being an option).
So with this in mind, I merrily waded through the dozens of fields in the Classic UI, changing them all as needed. It wasn’t just a few minutes of work, but it was definitely much less time that deleting & manually creating each one!
So, really quite helpful. The only other thoughts that I had around things were that it would be nice if the various tools within the XrmToolBox could do this as well. However, the fact that they don’t seem able to actually seems to be a limitation of the API. Having gone to check the different field types & how they’re set programmatically (https://docs.microsoft.com/en-us/powerapps/maker/common-data-service/types-of-fields), I’ve noticed the following:
There really doesn’t seem to be any way to specify the different sub-type, which is a shame!
Have you ever had a similar situation with fields? Drop a comment below- I’d love to hear about it.
Chatting with Thomas Sandsør about his celebrity status as one of the National Beach Football team, how he got there, and his experiences from the game. Also talking about starting on projects as a junior consultant, & why it’s SO important to ask questions & not just blindly follow instructions.
If you’d like to come appear on the show, please sign up at http://bit.ly/2NqP5PV – I’d love to have you on it!
Click here to take a look at the other videos that are available to watch.
Routing is used to send customer interactions to specific queues, in order to have them handled by the agents best suited. This could be based on the language that the customer is using, the query that the customer has (involving pre-chat survey questions), etc.
The way that this is done (included in the previous articles) is by selecting the details that we want to use. This could be the contact (when recognised as a record in the system), pre-chat survey responses, or several other options.
However, to date we’ve only been able to use fields/variables from the chat session itself. It’s not been possible to connect to other data that we’re holding within the system, and use that for routing. We’ve only been able to use items that are directly linked to the conversation:
Account
Case
Contact
Context Variable
Live Chat Context
So if we had identified the customer as existing in the system already, we weren’t able to query related records to them, eg accounts etc. That’s all changed now though – we are now able to do this!
Let’s see an example of this. We have a customer, and we know from within Dynamics 365 that his company is a VERY large customer of ours. They spend a great deal on our products every year, and as a result, we want to route any interactions with them to a special VIP queue. Previously we were unable to do this, unless we somehow set a flag on the contact record to display this.
What we’re now able to do is go and get values from the linked account record, and use these as the routing variables within the workstream:
We can add multiple rows here, all connecting different parts of the data.
Note: The only caveat is that the entity needs to be linked to one of the Omnichannel items (which are listed above). We can’t daisy-chain non-related entities, eg Contact-Account-Invoices
These can obviously be put together in groups, to satisfy more complicated conditions, using AND/OR conditions. With this, we can therefore address very specific scenarios, tying together conditions across multiple entities.
Even nicer, we’re not restricted by the relationship type. We therefore can select an entity that’s related to the primary Omnichannel entities as:
One to Many
Many to One
Many to Many
With this being in place, we’re now really able to ‘fine tune’ how we can route customer interactions, and set up specific places for them to be directed to. Through this, we can identify & serve identified sectors of our customers in different ways, as we feel is best appropriate.
This is also applicable to skill attachment routing, where the same level of functionality is provided.
So with this in mind, how would YOU think that you would go ahead and use this? Leave a note in the comments below!