Tip #763: Video introduction to PowerApps

Mobile developmentIn this video we introduce PowerApps. We will look at how to create an app and working with basic controls including creating a button to invoke a flow.

YouTube player

Give us your feedback, all of it: good, bad, and ugly, I’m sure we can take it. Suggest new topics either in comments or by sending your ideas to jar@crmtipoftheday.com.

Don’t forget to subscribe to http://youtube.com/crmtipoftheday.

Tip #762: Good news for Campaign Monitor fans

VaporwareWe rarely if ever post vendors news but considering the official demise of Dynamics Marketing, this one is hard to ignore.

We’ve long been a big fan of Campaign Monitor, the (proudly Australian) vendor very much focused on helping to create beautiful and actionable emails “your customers can’t ignore”. And they just announced integration with Dynamics CRM. Focusing solely on building marketing lists and pulling customer information into Campaign Monitor itself, it does not look like a product in the same league as ClickDimensions but then, again, it’s not pretending to be.

If you have Dynamics CRM and are Campaign Monitor user/fan, this is something worth exploring and it certainly gives you a very good immediate (and inexpensive) alternative to the Dynamics 365 for Marketing that is not going to see the light of the day until Spring 2017.

Tip #761: Script error in main.aspx on line 1

FragileWhen creating fine-tuned roles for restricted access to your Dynamics CRM deployment, be very careful about privileges granted on Customization tab in role editor. Some of the privileges are easy to overlook and, if not granted, that can break the user experience.

What I learned today is that CRM is very sensitive about Process privileges. The restricted users did not need to access any processes at all so I removed all the privileges. And so it began:

  • Custom form scripts wouldn’t run
  • Navigating away from the form pops up an error message
  • Error details refer to script error in main.aspx (1,1) – i.e. line 1, column 1
  • Script debugging would stop in the file on the very first line which is, errr, blank?!

Long story short, granting read privilege in the user scope to Process fixed the issue. I think it’s related to the code that builds the ribbon and, even though users don’t need and don’t have access to any dialogs in the system, the code is not defensive enough and breaks when trying to render Start Dialog button. I suspect removing the button from the ribbon might help as well but read access to user-owned processes (and they owe none) seems harmless enough.

Tip #760: Scope your workflows

Baby activity centerAdmit it: when you create a new workflow, one of the first actions is to set the scope of the workflow to Organization. After all, when something changes, or new record is created, we want apply our business rules across the board, right?

Workflow scope

Most of the time you’d be correct. But this is an opportunity missed. Using a combination of security privileges related to the processes, activation of the real-time workflows, and execution of the workflow jobs you, as an administrator, can empower users to customize processes within the Dynamics CRM to suit their, or their business units needs.

Workflow security

For example, a user can create a private process to help them to deal with the workload; some people love email reminders – let them create as many as needed! A business unit dealing with customer support for VIP customers may use an escalation workflow to support their very important processes.

Would like to give users their own private real-time workflows but cannot trust them to get it right without blowing server to pieces? Take away Activate Real-time Processes privilege and activate the processes they create only after a thorough review.

Opportunities are limitless, just remember to plan and document the security permutations. A good introductory write-up on scoping the workflows is available, if you’d like to dig deeper.

Tip #759: Create a persistent backup of your instance

Clock is running out latteNow that you’ve mastered the backup and restore for your CRM Online organization, you may be wondering, now what?

Backups are only held for three days, that’s not very useful, is it?

Well, actually, it is. These transient backups are very useful if you perform some scary-looking update to your production instance. But more importantly, they can be restored into any sandbox instance that you have.

CRM Online deployments have a free sandbox per every 25 users, chances are that you will have an unused instance lying around. Why wouldn’t you restore your backup into that instance and set it aside? That would create a persistent backup of your CRM organization at given point in time and set it aside as a reference or emergency stash.

If you’re not up to the scale of 25+ users yet, ask yourself if persistent backup worth a price of a large weak skim organic soya vegan latte per day, because that’s what an additional sandbox instance would cost you.

Tip #758: When users are unable to save personal views

tl;dr

Private property keep outWhen no one in your organization including system administrators can create or update personal views, check that you don’t have any plugins registered on all entities to run in a context different from a calling user.

Mundane details

Symptoms: when personal views are created or updated, all users including system administrators receive the following error:

SecLib::AccessCheckEx failed… snip … ObjectTypeCode: 4230… snip … AccessRights: ReadAccess

Object 4230 is userquery entity, a.k.a. personal or saved views. But how could it be that even system administrators are denied access?!

Personal views are special – you cannot grant privileges in any scope but the user. Go ahead, open Settings > Security > Security Roles > Any role and try to change the scope for Saved Views. See how only nothing or user is available? That means that even system administrators do not have access to other users’ views.

Enter a plugin on all entities. It kicks in when users are saving the views and needs at least read access to the entity. But since security context has been changed to another user, permission is denied.

Solution is either to change the plugin to run under a calling user context or not to register the plugin on all entities. Generally speaking, registering plugins on all entities is an extreme step and should be avoided.

One of the popular ISV solutions, Adxstudio portals (version 7 and below), actually has the cache invalidation plugin registered on all entities and the recommendation would be to re-register this plugin only for entities that you care about in the portal.

Thanks to the awesome investigative work of Matt “Europäischen Wurzeln” Wittemann and Shan “Smoke ’em” McArthur.

Tip #757: Passing enumerated values to Web API

Passing valuesShiny Dynamics CRM Web API has a number of useful functions that you can call using simple GET. Like ubiquitous WhoAmI: https://notarealorg.api.crm.dynamics.com/
api/data/v8.1/WhoAmI
,
nifty RetrieveOrganizationResources: https://stillnotarealorg.api.crm.dynamics.com
/api/data/v8.1/RetrieveOrganizationResources
,
or canny RetrieveDataEncryptionKey: https://yesthisisarealorg.api.crm.dynamics.com/
api/data/v8.1/RetrieveDataEncryptionKey
.

Some of these functions require parameters and documentation how to pass parameters is available. Except that the documentation does not explain how to deal with enumerated types required by some of the functions, e.g. RetrieveCurrentOrganization that needs AccessMode of EndpointAccessType enumerated type.

Web API implements OData version 4, and sample from the OData team to the rescue. General pattern is Namespace.Type’Value’. For example, if I want to retrieve org details external access type then URL will be https://noitwasnot.api.crm.dynamics.com/api/data/v8.1/
RetrieveCurrentOrganization(
AccessType=Microsoft.Dynamics.CRM.EndpointAccessType’Internet’)
with the output similar to:

{
  "@odata.context":"https://really.api.crm.dynamics.com/
     api/data/v8.1/$metadata#Microsoft.Dynamics.CRM
	 .RetrieveCurrentOrganizationResponse",
  "Detail":{
    "OrganizationId":"02745e7c-dead-beef-9058-bbe5bd989627",
    "FriendlyName":"Contoso",
    "OrganizationVersion":"8.1.0.452",
    "UrlName":"notagain",
    "UniqueName":"org12345678",
    "Endpoints":{
        "Count":3,
        "IsReadOnly":false,
        "Keys":[
			"WebApplication",
			"OrganizationService",
			"OrganizationDataService"
        ],
        "Values":[	  
            "https://foo.crm6.dynamics.com/",
            "https://bar.api.crm.dynamics.com/XRMServices/2011/Organization.svc",
            "https://baz.api.crm.dynamics.com/XRMServices/2011/OrganizationData.svc"
        ]
    },
    "State":"Enabled"
  }
}

Tip #756: Friendly Name Mismatch between Browser and Outlook

MismatchIf you go into the Dynamics CRM Portal and change the Friendly name for your CRM organization that changes it for everyone when they access CRM via the browser. But it doesn’t change the name in the Outlook client. Each user will have to change it manually. Lets see how this works.

CRM Admin Center

Select the Name field and replace it with the new friendly name.

Outlook Client Friendly Name

But the change in the admin center doesn’t change the Outlook Client

CRM Outlook Client Configuration Wizard

Launch the Configuration Wizard, select Rename and then enter the revised Friendly name, Click Okay and you are done.

Tip #755: Logs grow rapidly if audit is enabled on mailbox entity

Wafer thin mintBe careful when enabling auditing on the Mailbox entity. As Jukka “Kalsarikännit” Niiranen has discovered after analyzing why one of the instance consumed disproportional storage:

“It all looked fine at first, but looks like at some point the sync process had started to update the exchangesyncstatexml field with new data every few minutes. [This] field … is hidden from the UI, and also a field for which I cannot selectively disable the audit for, since the Mailbox entity fields are not editable. Oh well, time to delete our entire CRM audit log history and move on…”

In the cases where the audit contains valuable business data, deleting the audit log history as a cleanup measure is a tricky business, especially for CRM Online.

Tip #754: How to secure your views

Private viewCRM is very good at securing data but there is no way to control visibility of the system views for the end-users. There are good reasons why would anyone want that:

  1. Systems grow over the time and it’s hard to control retirement process for old views, especially for large implementations. As a result, list of available system views tend to grow out of control.
  2. If record is required on multiple customized sub-grids, chances are each sub-grid will potentially require yet another system view.
  3. Remove views that are broken for a user/team. Your view may include fields from a parent entity users do not have access to. They will see “You do not have permissions…” error plastered all over the grid.
  4. Simplify UI and provide better experience for the end-users. Tailor their experience by role and only show views that are applicable for their role.
  5. When users ask for a new “report”, quite frequently they mean “give me the list of records satisfying certain criteria”. A.k.a. view.

Lucky for us, views can be shared:

  • Create a handful of universal views that make sense for everyone, e.g. “My accounts”, “Overdue invoices”, and implement them as system views
  • If you would like to restrict view to a specific user/team, create a personal view and then share “read” access to it with the user/team.

The only drawback of this approach is that users will see these “private” views under “My Views” subheading. Oh, and you won’t be able to use these views in system charts/dashboards, or subgrids.