Tuesday, 18 June 2013

Dynamics CRM 2011 scalling multi-tenants across multiple SQL servers

Recently I've seen a few questions in the forums around placing new tenants on different SQL servers.
This is possible if you using an enterprise license, the option is available when you create a new tenant. You are not necessarily stuck to the SQL server where the MSCRM_CONFIG database is deployed, you could specify a different SQL server. You will need the same permissions as per the deployment guide.

However distributing tenants across multiple servers increases management, complexity and SQL licensing costs. Keep it simple, it's easier and cheaper to upgrade the hardware of one SQL server rather than having those resources distributed across multiple servers.

Creating New Organization
Open deployment manager click New Organization when it gets to the SQL server step specify a different SQL server

Click Next and specify the ReportServer as well

Note: you need local admin permissions on the SQL server and database permissions as per deployment guide.

The below diagram illustrates 4 Organizations distributed across multiple SQL servers and 2 of those with their own SQL Reporting Server.

You can distribute tenants across multiple SQL servers including the SQL reporting services. A number of things can influence the decision to place tenants on different SQL servers:

  • Legal Reasons
  • Shared Resources
  • Size of databases with impact of backups 
  • Performance
  • Development and Testing

Friday, 7 June 2013

Dynamics CRM 2011 printing IFRAME

In the past I wrote an article on how to make iframes printable using the CRM print function, I was asked how to apply the same approach to CRM 2011, I had a look and CRM 2011 wraps the text inside another set of HTML elements, so we just need to make sure we return only text document.getElementById.textContent

This change is not supported as it changes directly an ASPX file, the file you have to change is custformprint.aspx located:

C:\Program Files\Microsoft Dynamics CRM\CRMWeb\_forms\print

For example if you have a SRS report loading in an IFRAME you just need  to set SRC="" url of the FRAME_ID:

document.getElementById('IFRAME_GoogleMap').src= "http://srsserver/reportserver?etc.....";
document.getElementById('IFRAME_GoogleMap').style.height = "400px";
document.getElementById('IFRAME_GoogleMap').style.width = "900px";

An example for Google Maps would be:

//does an initial check if the ID for the google map is set. (assuming you've used GoogleMap for the iframe)
if (document.getElementById('IFRAME_GoogleMap')) {
var url = "";
if (document.getElementById('address1_country_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_city_d').textContent;
if (document.getElementById('address1_city_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_city_d').textContent;
if (document.getElementById('address1_postalcode_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_postalcode_d').textContent;
if (document.getElementById('address1_line1_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_line1_d').textContent;
if (document.getElementById('address1_line2_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_line2_d').textContent;
if (document.getElementById('address1_line3_d') != null)
  url += (url == "" ? "" : ", ") + document.getElementById('address1_line3_d').textContent;

if (url != "")
  document.getElementById('IFRAME_GoogleMap').src= "http://maps.google.com/?q=" + url;
  document.getElementById('IFRAME_GoogleMap').style.height = "400px";
  document.getElementById('IFRAME_GoogleMap').style.width = "900px";
} else {
// If no data to pass to url, defaults to text only "No Results"
document.getElementById('IFRAME_GoogleMap_d').innerHTML= "No results";

Tuesday, 4 June 2013

dynamics CRM 2011 Data driven security Part II - Teams

This is part II of my previous post on data driven security where I mainly focus on Security Roles and Business Units architecture, you can read it here:

On part II I will focus on Teams and it's concept around data sharing based on the same pyramid model used on Part I. I'm also covering how can teams leverage User management. In general Teams are great for:
  1. User Access Management and Security roles
  2. Sharing Data across Business Units
  3. Enhance collaboration

User Management Simplified with Teams
User management in CRM can become as complex as you want. The management side has been designed to be very basic, adding a user and assign a security role, this is what it takes to give a user access to CRM. However with multiple business units and multiple security roles and the lack of a built-in tool to check 'effective permissions' across the hierarchy of records and Business Units this could become very time consuming to manage and troubleshoot permission issues.

You could add users multiple security roles at the same time, however you can't remove them at the same time, if you assign 300 users the wrong security role, you will need to remove one by one the same security role or develop a tool to do this.

However we are lucky because we have teams which can be used like AD groups or sort of OU with GPOs. How would this work for User Management? When we create a Business Unit, CRM will automatically create a team with the same name as the Business Unit you just created and link it with the same Business Unit. On Part I, I've used a pyramid type graph to illustrate permissions, the below screenshot is the same graph but I'v added highlighted in yellow the corresponding teams. 

On the above graph, all the default teams in yellow belong to their own BU, also all users moved to that BU will also be automatically added to the BU default team, this is great!! However the default teams are not assigned a security role, even better! :)

At this stage what you need to do is assign a security role to the default teams, the appropriate security role with permissions only for those Business Units. 

Now that all your default teams have a security role, if you didn't have users in the system, here is how it would work:
  1. Add one or multiple users to CRM and simply select the business unit you want to place the user on, don't assign security roles
  2. The user will inherit the Teams security role and it's permissions
  3. For those familiar with AD, this concept is similar to OU GPOs, every object you place on an OU is bound to the OU GPO's
You populated all users across all Business Units, now you have 50 Junior Engineers to move to the Global Engineers OU, this is how it would work:
  1. Select The users you want to move, and click 'Change Business Unit'
  2. Users will be automatically assigned the Global Engineers Security role because they are automatically added to the GlobalEngineers default team.
  3. Also users will be automatically removed from the JuniorEngineers team so they will also loose the JuniorEngineers Security role
  4. Conclusion: you didn't have to remove or add security roles

Assigning Users Business Unit

Sharing Data
On the pyramid model the idea is to isolate data from other departments and teams, only specific permissions would grant the Junior staff tier access data on the upper Business Units, the only permission setting that allows this to happen is the 'Organisation' level and this would open access to all BUs and not just the BU directly above, we don't want this to happen because it would break the pyramid model so we have to use teams to share data with groups of users or the entire BU.

Facts about teams:
  • Teams can only include users
  • Teams can include users of any Business Unit
  • You can share records with Teams from any Business Unit

To use teams to share records you create custom teams on the various business units, to be used as:
  1. Using Security roles to provide single BU access
  2. Object Access (record only)
Using Security roles
This method is familiar to us, we covered the concept on simplifying user management above. The team is assigned a security role so any user added to this team will also inherit the same security role, this is a great approach to give specific users in the junior tier, access to an external BU in this case the global engineers Business Unit.

Object Access
Instead of providing external BU access you may just want to share 1 or a few records with a number of users and teams, to do this you share data directly at the object-level (opportunity, account, etc).
  1. Create custom teams to group users
  2. On the record itself select Share and select the team you want to share the record with.
  3. This means any team from any BU could be added, and the record accessed by multiple users from multiple Business Units
  4. This avoided giving BU-wide permissions just to share one or a few records

The above diagram illustrates the concept of sharing records with Teams, team1 On the Junior Tier has been given share permissions on:
  • One Record on the Global Engineers BU
  • One Record on the Global Exports BU
A team from the Global Engineers BU has been also given access to a record on the Global Sales BU. I haven't illustrated the BU single acces because this is covered on the above diagram.
All users members of these teams are now able to view the records and if edit permissions were given able to write and collaborate.

I hope this was useful, please leave your feedback or any questions you may have.