Gotcha: Don’t Use Nested Security Group

Some time ago, I published a blog post about a tip about using Security Group in Dynamics 365 Online Deployment. And I’ve got a feedback from one of my colleagues where the security group is not allocating the users properly. So, I investigated the behaviour with my colleague and found an interesting setup.

TL;DR; version: Do not use Nested Security Group, as Dynamics 365 would not honour it.

The Long Version

So, I noticed in my colleague’s environment they have set up nested security group. To explain, I’m going to “replicate” the scenario in my environment.

I have set up my sandbox environment to use “Dynamics Sandbox” security group as follow:

Sandbox Security Group.png

And the Dynamics Sandbox security group has membership as below:

Parent_Group.png

“Dynamics Test” there is the child group that I have setup with the following members:

Child Group.png

Normally, When I have a nested group like that. I would expect Test User 2 – 5 will also be included in the Enabled Users list. However, this is the result:

Actual.png

To ensure the rest of the users are synced to Dynamics 365 the group must be flattened:

Flatten_Model.png

Then, you’ll be able to see them in Dynamics 365.

Actual-flatten.png

I have confirmed the behaviour with the Microsoft support, that nested group is not supported at this moment.

Hope this helps!

Advertisements

Dynamics 365 Online Deployment Tips: Set Your Security Group!

The feature of Security Group in the Dynamics 365 Online deployment has been there for a while. However, I often find either people do not understand it correctly or this feature is not being considered as an important “checklist item” for a smooth deployment. So, in this post I will share some reasons on why we need to plan setting up the security group.

To support the example, I’ve set up the following scenario:

In my instance I have 4 users:

Users List.png

And 2 Security Groups for Production and Sandbox

Security Group.png

Where in Production, everyone is the member of the group:

Prod Membership.png

While in Sandbox, Test User 3 should not access the environment

Sandbox Membership.png

Now, let’s begin with the reasons why we need to implement Security Group.

#1 For Authorisation Purpose

In typical Dynamics 365 implementation, there will be multiple instances, such as DEV, TEST, UAT and PROD. When the instance has been associated with the security group, only users that are member of the security group can access the environment. The traditional way to restrict access by not assigning the security role to the users is still viable, but this leads to the reason #2 below.

The difference on the error message would be as follow:

  • Not assigned with the security role

NoSecurityRole.png

  • Not part of the Security Group

Not Part of Group.png

#2 To Keep Users in the Instance Clean

On top of the first point, to prevent the users to access the environment, having security group configured for the environment will also prevent the users that are not part of the security group to be synchronised with the environment.

A thought come into my mind: it won’t harm right to have the users synced. As long as, we are not assigning the security role to them. Yes, it’s true from the authorisation perspective. However, having them in the environment that they are not supposed to be, also means they will be under the list of “Enabled User” that can be used in selection when assigning records. In multi-organisations deployment, it also means the user from different organisations are visible to the environment. These situations could cause confusion to the users.

The list from Production environment:

ProdList.png

The list from the Sandbox environment:

SandboxUserList.png

#3 To Hide Unnecessary Items at the Apps List/Instance Picker

With the “App” concept in Dynamics 365 Online, the home.dynamics.com will contain all kind of “Apps”. This includes the Apps that deployed within the instances. When a user have the privilege to access multiple instances, they also will see the “Apps” that are deployed in those instances. IMHO, it is always the best approach to hide anything that users should not see, so that they could focus on what they need to do with the system.

For example, my user that has full access to all environments, could see the following:

AppsAll.png

Meanwhile, the Test User 3, can only see 1 “App” that is associated to the instance that this user has access (controlled via the Security Group).

AppsTestUser.png

The same thing with the Instance Picker (this has been superseded by the home.dynamics.com). However, if users might have bookmarked this page.

The following is the list from my user:

MyUserInstancePicker.png

Meanwhile, this is from the view of Test User 3.

TestUserInstancePicker.png

Conclusion

Implementing Security Group for Dynamics 365 implementation should be considered in the design and planning to ensure proper and robust security and user experience.

Hope this helps!

 

References

https://blogs.msdn.microsoft.com/crm/2017/03/30/my-apps-on-home-dynamics-com/

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/admin/add-instance-subscription#BKMK_man_sec_group

FetchXML Trick – Cross Entity Criteria in a Group Filter

Recently, I had a tricky question: Can you create a view that is displaying records that are either owned by a team or the users that are a member of that particular team.

EDIT: Jonas Rapp provides a feedback to get more efficient with his tool 😉

The TL;DR; Answer

Use “Alias” + FetchXML editing using XrmToolBox (View Designer + FetchXML Builder – this is the one stop shop!).

 

The Longer Answer

The typical answer to the above scenario would be querying the record with the criteria as “Owner ID = the team OR related Owner (user) is a team member of the team”. Using the Advanced Find query, typically this is the query…

Typical_Adv_Find_Query.png

However, it seems we can’t group the “main” criteria and the Linked-Entity criteria. Looks like we are stuck here… Worry not, there is a trick for that. So, before I go to the solution here are some setups to set the background.

I have 3 users in my instance:

UserList.png

And I’ve set 2 teams for the testing purpose:

Team A with myself and Test User 1 as the member.

Team_A.png

And Team B with Test User 2 as the member.

Team_B.png

Now I have some records for testing purpose:

Sample_Data.png

So, when based on the query to see the Team A records, I would expect to see 3 records there. Using the initial query (above) will return no result, as it is treated as ‘AND’ operation.

To get the FetchXML correctly, I need to edit the FetchXML, my go-to tools for this would be XrmToolBox‘s FetchXML Builder.

To start with, I’ll export the FetchXML out of my initial query, it will look like this:

Base_FetchXML.png

Now the trick is to use the “alias” of the related team entity to form the FetchXML like this:

ModifiedXml.png

As you can see above, we are able to set the condition in the “main” filter and set the operator to OR. Below is the result of the fetch… it works as expected 🙂

TestResult.png

Now, I want to put the query to the view, how to do that?

I’ll use XrmToolBox’s Fetch XML Builder to modify the FetchXML of the view. In my case, I’ve setup a Test Query view. Click on Open View….

OpenView.png

And then select the corresponding view:

Select_View.png

Copy & Paste the FetchXML that we had tested previously into the FetchXML window, if you wish, you could test execute the query. Then click on the “OK” button down there and then click on the “Save As” button up there and save it back to the view.

Save As.png

 

And here’s the result:

FinalResult.png

 

HTH!

Dynamics 365 Portal – When the Custom CSS won’t load.

Recently, I’m working on a demo that I need to skin the Dynamics 365 portal to have a look and feel based on the client’s theme. One of the pages is the dashboard/landing page that showing some charts.

Let say the URL of the page is called “Dashboard”.dashboard.png

It’s showing up the chart nicely. However, I would like to hide the out of the box chart title, as it seems always giving me a static name (based on the chart name in Dynamics 365, where sometimes I would like to label it to something else).

Header.png

My approach is to hide this using CSS (display:none;). So, the usual way I change this is by opening up the Web Page record and add the CSS under the Custom CSS part of the web page.Web_Page_Custom_CSS.png

However, it doesn’t change the layout and even after I reset the cache from the “/_services/about” page of the portal.

My problem was solved by editing the web page via the portal itself. So, I navigated to the page, click on Edit and under the Options tab, I add the CSS there.

Options_Custom_CSS.png

Once I’ve used this part to set the CSS, now the undesired element is gone.

Gone.png

 

HTH!

 

 

Just Some Tips Working with Virtual Entities

Recently I spent some time working on Virtual Entities, one of the new features in Dynamics 365 v9.0. To learn more about Virtual Entities, you can read the official documentation here and how to set it up here. In this post, I would like to share my tips and findings working with Virtual Entities and connecting it to a custom oData v4.0 Web API.

During my attempt setting up Virtual Entity, I encountered a very generic error: “Entity could not be retrieved from data source.” for different problems.

Error.PNG

The error message is not that descriptive and doesn’t provide further information for me to troubleshoot. I’ve submitted a feedback for this, if you also encounter the similar issue: https://ideas.dynamics.com/ideas/dynamics-crm/ID0003358

The tips in this post hopefully can be helpful to fix the above issue 🙂

Background

So, to set the context, in my sample scenario I have a custom oData data source with metadata as below:

VE-Casesensitive.PNG

Tip #1 – Make sure the path is in the correct case (Upper/Lower)

 

I was under an assumption: oData seems to be just an URL, so if I throw in the path as all lower case it should be fine…

Well, one of the reason the error being thrown is because oData seems to expect case sensitive path. I entered “movies” instead of “Movies” and in the field mapping I put “rating” instead of “Rating”. So, make sure the mapping and path is the same as the metadata.

VE-Case.png

Tip #2 – Missing Field Mapping

In my experiment, I created a few extra fields that doesn’t match the metadata definition. Well, this should not create any harm right, just like other custom entity…

Apparently, when there is a missing field in the mapping, the virtual entity is showing the above error.

So, make sure you have the all fields to be mapped correctly and do not create any field that is not in the oData definition. Luckily, you can still omit fields that you don’t like (e.g: when I don’t have “ReleasedYear” field, the VE still works fine).

VE-Mapping.png

Tip #3 – Setting Field Requirement(s)

If you noticed my oData definition for Rating field, it is mentioned there: Nullable=”false”. If the oData set up the field to be mandatory, the corresponding field in the VE also need to be set “Business Required”VE-Field Requirement.PNG

Tip #4 – Be Careful with the “Numbers”

In my oData definition, I have the Rating field, which is a decimal field. But how about in Dynamics 365 we want it to be stored as a different field type, whole number or float instead? Well, VE doesn’t support that, so we need to ensure the field data type is the same from the data source to the VE’s field.

VE-Data type.png

That’s all for today. Hope this helps!

Dynamics 365 v9.0 Hidden Gems – #2 Configurations for a better UX

I’m continuing the hidden gems series of the Dynamics 365 v9.0. Today’s topic is about the UI/UX Configuration that is introduced in the Dynamics 365 v9.0. This is not about the “Hub” features that you can use the custom control, that would be a separate topic on the unified client. The configuration options that I’m going to share here is about the refreshed web UI.

Configuration Option #1: Multi-Select Option Set

It’s been a long waiting ask from the Dynamics Community to have multi-select option sets. In the past, workarounds for this are either using Many-to-Many relationship or flatten the selection within the entity. With this new enhancement to the platform, we can tailor the UX of the data entry to be simpler. The old workaround using Many-to-Many relationship requires the user to click the (+) button at the subgrid and it will pop-up the lookup window to select (lots of clicks here)

Many-To-Many-Workarounds

Compared to the new Multi-Select Option Set, where we can capture the data in a single location and less clicks.

Multi-Select.png

Findings on the multi-select option sets:

  • Behind the scene, it is stored similar to the regular option set (a pair of value and label), which is good for reporting, it is not stored as just plain text, separated by comma or a specific character that makes it harder to report.
  • We are not able to update existing option sets to be multi-select option sets.

Configuration Option #2: Colour-coded Sub Grids

Another UX enhancement that we can apply with the v9.0 is around the Panel header color for Subgrids. In my example, I’m colour-coding case subgrids under account entity to be able to see open cases with the account by glancing the colour coded cases by priority.

Subgrid1

The end result is:

Subgrid2

Configuration Option #3: Allow Text Wrapping

In the past, it is another common feedback when we are configuring fields on the form, some of the fields are a bit more descriptive than the other. When it’s longer than the pre-defined label width within the section, the text will be truncated. The almost immediate feedback from the end users would be: I want them to be visible!

With the update of v9.0, the Web UI addressed this feedback to a certain degree. There is an option under the System Settings to allow text wrapping in form fields labels and value.

Allow Text Wrapping.PNG

So, I gave it a go and see a long text label for a single-field text. And it wrapped up to a few lines, which addresses the common feedback. yay!

Wrapped.PNG

Conclusion

From my perspective, these configuration options to the UI are giving some improvements to the usability and UX aspect of the application. With simple change and minimum effort, as well as doing it in a supported way, we can improve the UX of the system.

HTH!

Dynamics 365 v9.0 Hidden Gems – #1 Autonumber

The Dynamics 365 v9.0 for the online deployment has become available since a few days ago. I believe we are all excited with this new release. There are major improvements in a lot of areas such as the unified client (a.k.a refreshed UI and great potential ahead), platform enhancements (Virtual Entities, Microsoft Flow integration directly from Dynamics 365), Hubs – this was the Interactive Service Hubs, being extended for other modules (Sales, Service, Project Service, Field Service) and many more.

Yet, there are few hidden gems that can be uncovered from the v9.0 update that could be a life saver in the Dynamics 365 projects. I’m starting the v9.0 Hidden Gems series to run through the hidden gems. I’m going to start with the first one: Autonumber. And no, this is not the same Autonumber that is available for some of the out of the box entities like case, invoice, order, etc

not the autonumber.png

This feature was announced by Matt Barbour at Microsoft Ignite Conference, the recording is available at this Youtube video. At this moment, this feature is available from the API only and there is no explicit documentation available yet.

At high level, this Autonumber features could generate the number with below features:

  • Date format
    • Syntax: {DATETIMEUTC:[format]}
  • Sequential Numbers
    • Syntax: {SEQNUM:size}
  • Random String
    • Syntax: {RANDSTRING:6}
  • Static string
    • Any string component that is not using the above syntax will be treated as static string.

Sample code snippet from Matt’s presentation:

Autonumber code snippet.png

Given at this moment the documentation is not available yet and it is only available via the API, this is a bit tricky for Admins/System Customisers to work on this feature. Luckily, the Dynamics 365 community is really reactive to this and there are few helper tools available.

Option 1: AutoNumManager – XrmToolBox Plugin by Jonas Rapp

ANM-screen.jpg

You can read the instruction on how to use it at: http://anm.xrmtoolbox.com/ and download the plugin from GitHub: https://github.com/rappen/AutoNumManager/releases

Option 2: Easy AutoNumber by Dimitri Chevkov

Another option if you would like to configure the Autonumber from the Dynamics 365 itself. This solution is provided as Dynamics 365 managed solution: https://dynamics365heroes.com/2017/10/02/easy-autonumber-utility-dynamics-365-july-2017-update-v9/

easyautoscreen.png

Findings

So, I’ve tried the Autonumber features and would like to share some of my findings here:

  1. This autonumber attributes apparently more robust from the Workflow/Plugins workarounds that some people might have developed. It could handle a good degree of parallelism. My PoC was using KingswaySoft to load 5k contact records with bulk operation enabled and using balanced data distributor to do 2 parallel runs. I cannot find any duplicate number with this testing. While the other Workflow/Plugins workarounds produced duplicate records on Dynamics 365 Online environment.
  2. A common question that often been asked by customers: can we specify the starting number? The answer is yes. I looked at Jonas’ XrmToolBox plugin and there is a field to fill in called “Seed”. Here you can specify the starting number for the sequence. Note: from Jonas’ blog post, modifying Seed could potentially generate duplicate numbers.
  3. Multiple Number Sequence within a single Autonumber field is not possible. It seems it is using the same “counter”.
  4. It could not refer to other values within the entity or related entity, where some of autonumber requirements asked for the number to be sequential based on the parent entity. E.g: Custom Case numbering with parent child case, where the child case should use the parent case number as prefix and add the sequence at the end).
  5. At this moment there is no known way to update existing “bespoke” autonumber fields to use this autonumber feature. I read Jonas’ experiment and it seems there are some placeholders within the entity metadata where the autonumber definition is stored. And it seems a bit risky to re-engineer the existing field with something new. If organisations would like to leverage this new autonumber feature, they might consider using a new field, which might impact existing reporting/integration.

HTH!