Tip #1061: Hierarchical security rebuild

Dynamics CRM TipperWe have not done a mini truckstop for a while so it’s good to bag one at the beginning of the year.

Question

It’s a first time for Greg “Stealth MVP” Olsen to ask the MVP crowd a question.

We have Hierarchy Security setup and working well for an enterprise customer, but not sure how long it takes to apply once we have saved the settings. During our testing it doesn’t look like it’s in real time or immediate.

Can someone inform me on what it does in the background technically and how long I should expect to apply?

There is a good article available, but it doesn’t inform the reader if its instant or takes X minutes/hours etc or what it is doing behind the scenes to set up the security technically.

Answer

Adam “First!” Vero does not have his truckstop nickname for nothing, leaving others no chance to answer.

A table called SystemUserManagerMap is built to store who reports to whom and at what level. Eg it will contain a row for Charlie (as the user) and Bob (his boss as “manager”) at level 1, and a second row for Charlie (the user) and Alice (Bob’s boss) at level 2, and a row for Bob > Alice at level 1.

By pre-building this table it should make actual queries much faster (than some horrible iterative query) especially for retrieve multiple – join from current user through this SystemUserManagerMap table (filtered by depth set in configuration) to the entity table to find all records owned by users somewhere in my reporting chain. (In reality it goes SystemUserManagerMap then SystemUserPrincipal table to find all records owned by users who report to you, plus owned by any teams they are in. Likewise through those to the POA table to find records visible to your reporting chain via shares).

If for some reason that table is not built, fails, takes too long etc then queries won’t work properly. From memory, the table is built to represent all depths of reporting (via manager or position depending on settings). Then if you change depth from say 3 to 5, the records already exist and the table is not rebuilt. The table is modified if you change a user’s manager/position (depending on which is in use). Changing from manager to position approach would cause a complete rebuild, as far as I can tell.

Microsoft Scalable Security whitepaper covers more detail: https://www.microsoft.com/en-us/download/details.aspx?id=45905

Tîpp Jäår

The download, even though slightly out of date, contains other useful whitepapers – make sure to study them after closing this window.

Tip #1060: Quickly create vector/SVG images for Dynamics 365

We have had several tips about icons in Dynamics 365. As Tanguy reminds us, if you want your icon to show in the unified interface sitemap, you need to use Scalable Vector Graphics (SVG) format.

Andrew Magnotta from Microsoft shares a tip about how he quickly creates SVG images for Dynamics 365.

Method Draw – Browser based .svg editor

The support for Scalable Vector Graphic (SVG) web-resources have been introduced in D365v9 and it looks like they’re here to stay as the new default for adding custom images (logos/icons) to your D365 instance. However, support for creating custom .svg images can be tricky with the everyday image editors you maybe accustomed to (ex. Paint.NET). I did a quick search and found a nice + free browser based vector creating site called Method Draw (http://editor.method.ac/). This site allows me to import a custom logo image from an standard format (jpg, png, etc.), quickly turn it into an SVG, and save it locally to import into D365:

 

  1. Set Canvas size – Depending on the intended use of the image (up to 400x50px for Theme logos or the standard 16×16 / 32×32 for entity icons).

2.       Set Background – Can be transparent or any HEX color

  1. Import Logo Icon (jpeg, png, etc…)

  1. Drag to Resize Image (auto adjusts size… which is nice!)

  1. Save file and import into D365 as .svg web resource

  1. Add to Theme and Publish

  1. Renders nicely in both Classic and UUI interfaces

Classic:

Unified Interface:

Tip #1059: Enabling Tracking and Rating for Portal Pages

Two common requests for portal pages is enabling tracking (seeing who has gone to a page) as well as ratings for pages i.e. the ability to say if a page was useful or not. Rating can be found relatively easily under the options for a web page (log in to the portal as an Administrator, edit the page and go to options. However tracking a page (logging when a page is loaded on someone’s browser) is not as obvious.

My rule of thumb for the portal is, if in doubt, go to the record in Dynamics 365. The configuration record for a web page/entity form/web form should contain all of the possible settings (where else would they be?). Sure enough, if we browse to a web page record, we see the ability to enable these under the page options.

Rating puts a five-star rating on the page. This is most commonly used for knowledge article pages but, in principle it can be enabled anywhere on your site.

Tracking automatically adds a record to the Web Page Log entity every time an enabled page is visited. The IP address of the visitor is captured and, if they have logged onto the portal, it will also link the Web Page Log record to their Contact record.

Finally, for those looking for a bit more in-depth analysis, in the Content Snippet records, there is a Tracking Code snippet where you can add a tracking code e.g. Google Analytics and monitor your site that way.

Tip #1058: Connect to version 9 in your code

This tip is courtesy of Matt “SDK Deity” Barbour to make sure that we (developers) can stay connected to our beloved instances regardless of the version. Before copying the write-up almost verbatim, short version:

tl;dr

TLS 1.2 is now enforced so, for seamless connections to your version 9 instances, use the latest SDK tools and rebuild your projects with .NET 4.6.2+.

Matt has the mic

(Matt works at Microsoft so from this point forward “I” == Matt and “we” == Dynamics 365 team)

This is a bit long and detailed, however I believe it will be worth the read if your building for, or supporting folks that are building for, the crm\xrm platform.

With the release of the v9 platform we are now enforcing the use of the TLS ( Transport Layer Security) 1.2 + Only.

We made notice of this here and here.

Its important to note that TLS 1.2 is not a ‘new’ thing. We have been supporting TLS 1.0, 1.1 and 1.2 since v7 of the platform, the change we are making in v9 is that we will drop support for TLS 1.0 and 1.1, requiring all connections to connect to us using TLS 1.2 + only. Why we are enforcing this is covered in the blog with external links and such, so I encourage you to dig though that. The short of it is: its to improve security.

Now the rub 🙂

Our tools and platforms though v8 have been based on .net 4.5.2, which defaults to TLS 1.0 for security. What this means is that CRM and Dynamics Tools shipped up though v8 will not seamlessly connect to v9. When this shows up it always manifests as an auth failure. Looking at the logs, you will see a message that looks like this:

In 8.1 connectors :

Microsoft.Xrm.Tooling.CrmConnectControl Information: 8 : Login Status in Connect is = Validating connection to Microsoft Dynamics CRM...
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : ERROR REQUESTING Token FROM THE Authentication context
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : Source : mscorlib
Method : ThrowIfExceptional
Date : 1/19/2018
Time : 10:23:27 AM
Error : One or more errors occurred.
Stack Trace : at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.ExecuteAuthenticateServiceProcess(Uri serviceUrl, ClientCredentials clientCredentials, UserIdentifier user, String clientId, Uri redirectUri, PromptBehavior promptBehavior, String tokenCachePath, Boolean isOnPrem, String authority, Uri& targetServiceUrl, AuthenticationContext& authContext, String& resource)
======================================================================================================================
Inner Exception Level 1 :
Source : Microsoft.IdentityModel.Clients.ActiveDirectory
Method : Close
Date : 1/19/2018
Time : 10:23:27 AM
Error : Object reference not set to an instance of an object.
Stack Trace : at Microsoft.IdentityModel.Clients.ActiveDirectory.HttpWebResponseWrapper.Close()
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters.d__8.MoveNext()
======================================================================================================================

In the bits on nuget now the error looks like this:

Inner Exception Level 1 :
Source : System
Method : GetResponse
Date : 1/16/2018
Time : 4:37:46 PM
Error : The underlying connection was closed: An unexpected error occurred on a send.
Stack Trace : at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Description.MetadataExchangeClient.MetadataLocationRetriever.DownloadMetadata(TimeoutHelper timeoutHelper)
at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
======================================================================================================================
Inner Exception Level 2 :
Source : System
Method : Read
Date : 1/16/2018
Time : 4:37:46 PM
Error : Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Stack Trace : at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
======================================================================================================================
Inner Exception Level 3 :

Errors like this, in conjunction with trying to connect to a new trial or a v9 instance is a dead giveaway that it’s a TLS Problem.

How to deal with this

There are a few ways to deal with this,

For tools we ( Microsoft ) provide

the most simple and easy way to deal with it is to use the current SDK tools.. Now, in our effort to help keep folks up to date, we have made getting the SDK tools a bit more complicated but we did it for good reasons. Historically, we would post a point in time copy of all the tools and samples into a massive download, the problem is that to get all that together, it required a number of teams to work together to put a package together to post, this slowed down pushing updates. Most folks have noticed that we do not have the 9.x SDK posted that way. If you have not noticed yet … We are not using a Single download anymore 🙂

We have moved over to Nuget to provide the current SDK bits. This allows us to quickly patch and update SDK assemblies and tools.
We talked about this here. To help with the SDK Download and to keep you current, Jim Daly wrote up a handy powershell script in the documentation to help you get and keep current the SDK, its one link off the central dev page bug for reference its here. Using that script will always keep you current going forward with tools.

For Code built with our SDK

The most simple and easy way to deal with this is to recompile your code with .net 4.6.2+. if your code is already compiled with .net 4.6.2+ then your good to go. EXCEPT if you started with VS and a project that started with .4.5.2 :). There is a quirk in VS which causes it to run in 4.5.2 mode even after you have changed the build version. The simple way to deal with this is to clean your project after you change the .net version , close VS and delete the bin directory ( You need to get rid of the .vhost. files ) then restart VS and reload your project. That should kick it into using the .net 4.6.+ runtime. *note: this does not impact the binaries, only on the debug experience in VS.

For existing code that cannot be recompiled

We cover a registry setting in the blog articles that can be applied that will force .net to use TLS 1.2, I want to stress caution with this though as this is very much the sledgehammer approach as it forces all .net software on the machine to use TLS 1.2 +.

For non .net software

Check with your vendor on how to enabled TLS, for most languages it can be done with a simple config entry

One important note for .net based apps

Its really attractive to use the command: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; I cannot discourage you from using this enough… this forces the TLS 1.2 protocol all the time. While this seems great, if you ship software that lives more than a year or so, when the next security protocol appears and is adopted by the industry, your application with be at risk.

For Powershell

With regard to PowerShell scripts however, You will need to add [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 to your Powershell Script BEFORE you call Get-CrmConnection.

Tîpp Jäår

Wow, that’s one comprehensive write up, not much to add. You’ve been warned, folks!

(Our cover image – the one you see on facebook or twitter – is by Igor Ovsyannykov on Unsplash)

Tip #1057: Voice of the Customer says “Don’t change your URL”

Jerry Weinstock found out the hard way that if you change your Dynamics 365 instance URL after you install Voice of the Customer, survey responses will not synchronize with Dynamics 365. Survey responses will still be captured in Azure, but they will not appear in Dynamics 365.

  • If you want to change your URL, do it before you install Voice of the Customer
  • If you have already installed Voice of the Customer, contact Dynamics 365 support.

Tip #1056: Immersive Excel: Should I stay or should I go?

When you export to Excel Online in Dynamics 365 online, you can edit values and create new records, then click the “Save changes to Dynamics 365” button, the changes will be uploaded to Dynamics 365.

Sometimes when you hit the save changes button, you may be presented with this option:

So should you stay or leave? This is confusing, because the message reads as if the data will be lost if you hit “leave page.”

If you click “leave page,” it will look like your changes are saved to Dynamics 365, but the import file created will be empty and the changes will not be saved to Dynamics 365.

If you click “stay on page, nothing will happen, but if you click the “save changes” button again, the changes will upload to Dynamics 365.

 

Tip #1055: Dynamics 365 Service Administrators and security groups

In Tip 844 we talked about the Dynamics 365 service admin role in Office 365, which allows people who aren’t Office 365 global administrators to manage Dynamics instances, copy sandboxes, and other administrator features.

So if you give someone the Service Admin role and they don’t see the ability to do something like copy an environment, one thing to check is the security group associated with the instance.

 

  1. In Office 365 Admin Console, go to Settings>Services & Add-ins>Dynamics 365>Manage your Dynamics 365 Settings
  2. Select the instance and click “Edit”
  3. Verify if there is a security group selected in the “Security Group” field for the instance.

If there is a security group selected for the instance, the Dynamics 365 Service Administrator must be a member of the group to manage the instance.

Tip #1054: Hiding Field Service fields

Today’s tip is from Scott LeFante. Scott is the co-host of the “At Your Service” podcast, heard on the CRM Audio podcast network.

When working with Work Orders and their corresponding data, such as Service Tasks, be careful about removing or hiding fields from forms.  Field Service functionality includes many out of the box plug-ins and workflows that fire when certain actions are taken or certain values are entered on the various forms and entities.  There are many examples of when and where this occurs, some are simplistic to understand and determine while others may make you scratch your head to determine what the issue may be and how to resolve it.

For example, let’s say you hide Sales Tax Code, because you won’t be calculating tax in CRM, from the Work Order Form, but you set the Taxable field on the Work Order Type to Yes.

If you use that Work Order Type on the Work Order, you will not be able to save the work order record.

This is a simplistic example, but one that is important to understand as there are many examples of this from Work Orders to Bookable Resource Bookings, Work Order Products, Work Order Services, etc.

I recommend the following best practices when dealing with Field Service forms and functionality:

1) Make copies of all forms you plan to alter and use those forms for your users.

2) Understand the In’s and Outs of all forms and functionality you are implementing.

3) If you do not require certain fields within forms within the Field Service area, and they aren’t required fields (either conditional or non-conditional), think about putting them in a separate tab and hiding the tab/fields.

Photo by Don Agnello on Unsplash

Tip #1053: Convert emails to knowledge articles

The biggest challenge to knowledge management is content creation–somebody has to create the knowledge base articles. Emails can be a good source of knowledge base content. You are emailing your contacts and answering their questions, giving users a good way to quickly create knowledge articles from emails can be a good idea.

There isn’t a standard “convert to knowledge article” option for Dynamics 365 email records. Also, once an email is tracked, you can’t edit it, so adding a button to the form is not an option.

But that is why we have workflows.

  1. Create an on-demand workflow on email entity to create knowledge article. Map the subject to the Title field and the email description to the content field. Scroll down on the Knowledge Article form to populate required fields for major version and minor version.

2. From email, run on demand workflow

3. Draft KB article is created in Dynamics 365, ready to be revised and published. The content field renders the HTML from the email.

Tip #1052: Recurring tasks in Dynamics 365

How can I do recurring tasks in Dynamics 365?

While Dynamics 365 does not include an official “recurring” task like it does with appointments, it can still be done. Here is one approach to creating a weekly recurring task:

  1. Create an entity called “Task Schedule.” Include the relevant fields like owner/assigned to, next scheduled, subject, description, end date. Populate next scheduled with the first task instance due date, and end date with when the series should end.
  2. Create a workflow that runs on create of task schedule and on update of the next scheduled date:
    1. Wait condition timeout 1 minute after next scheduled.
    2. Check condition is workflow execution time less than end date.
    3. If so, create task setting due date to 1 week from next scheduled date and mapping the fields from the task schedule record.
    4. Update task schedule “next scheduled” with the due date from the task created in step 3.

So yes, it can be done. The above approach could be expanded to handle different types of frequencies (monthly, semi-annually, etc).

But should it be done? Personally, I am not a fan of recurring tasks, and the standard warnings about over-use of wait conditions applies.

Photo by Ambitious Creative Co. – Rick Barrett on Unsplash