Hide Areas & Sub Areas in the SiteMap using Security Roles in Dynamics CRM (Privilege tag)

If you need to show or hide a sub area in your SiteMap based on access control security roles, you can easily do this using the Privilege tag in the SiteMap as follows:

<SubArea Id=”crm_myentity” Entity=”crm_myentity”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
</SubArea>

Based on the above, this sub area will only be shown to users who have security roles with read privilege of the custom entity: crm_myentity.

You can add the privilege tag above to any sub area and the entity in the privilege tag can be any entity and doesn’t have to be the same one as the sub area. For example, the following is also applicable:

<SubArea Id=”contact” Entity=”contact” Title=”Contacts”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
</SubArea>

This will hide the contact sub area for users without the read privilege for the entity crm_myentity. You can mix and match as much as you want to show and hide any sub area in the sitemap based on any entity you require whether they are customisable/system or custom entities.

As for hiding and controling access to a whole area in the sitemap such as Sales, Marketing or Service (site map section), you will need to set the privilege tag to every sub area inside this area.

So for example, if you want to hide the whole of the Sales Area for specific users, you need to add the “<privilege  />” tag to every sub area in the Sales Area. What you can also do, is create a custom entity specifically for setting the security on the SiteMap. The following example will hide the Sales (or marketing or service) area for all users who do not have a security role with read access to the custom entity crm_SiteMapPrivilege:

<!–Sales Area–>

<Area Id=”SFA” ResourceId=”Area_Sales” Icon=”/_imgs/sales_24x24.gif” DescriptionResourceId=”Sales_Description”>
<Group Id=”SFA”>
<SubArea Id=”nav_leads” Entity=”lead”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
</SubArea>
<SubArea Id=”nav_oppts” Entity=”opportunity”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
</SubArea>
….
</Group>
</Area>

What you can then do is that, you make every sub area in the Sales area requiring the read privilege of SiteMapPrivilege entity, every sub area under the Marketing area can then have the Write privilege and every sub area under the Service area can have the Create privilege of the crm_SiteMapPrivilege entity. So similar to how the Sales area has read as per the previous example, the Marketing and Service areas can look like this:

<!–Marketing Area–>

<Area Id=”MA” ResourceId=”Area_Marketing” Icon=”/_imgs/marketing_24x24.gif” escriptionResourceId=”Marketing_Description”>
<Group Id=”MA”>
<SubArea Id=”nav_leads” Entity=”lead”>
<Privilege Entity=”crm_myentity” Privilege=”Write” />
</SubArea>
<SubArea Id=”nav_accts” Entity=”account”>
<Privilege Entity=”crm_myentity” Privilege=”Write” />
</SubArea>
…..

<!–Service Area–>

<Area Id=”CS” ResourceId=”Area_Service” Icon=”/_imgs/services_24x24.gif” DescriptionResourceId=”Customer_Service_Description”>
<Group Id=”CS”>
<SubArea Id=”nav_apptbook”>
<Privilege Entity=”activitypointer” Privilege=”Read” />
<Privilege Entity=”service” Privilege=”Create” />
</SubArea>
<SubArea Id=”nav_cases” Entity=”incident>
<Privilege Entity=”service” Privilege=”Create” />
</SubArea>
…..

 

Hence, based on the above 3 examples (Sales, Marketing, Service), you will need to make sure that users who should see the Sales Area has a security role with the read privilege of our custom entity (crm_SiteMapPrivilege), users who should see the Marketing area must have a security role with the Write privilege of crm_SiteMapPrivilege and Create privilege for Service.

The same applies for any additional Areas that you creates. So if you have added a new custom Area in your SiteMap, you should then use another privilege (append, appendto, etc) for every sub area under your new custom Area in the Site Map to show and hide this area based on your chosen privilege.

You can either manually amend your users security roles to add the privilege (read, write, etc..) or alternatively, a much better way of doing this is to create a new security role for each area. So what I have done is I created the following security roles: Access to Sales Area Access to Marketing Area Access to Service Area Access to MyCustom Area

In each security role, I only set the privilege for my custom entity crm_sitemapprivilege as follows:

For Security role: Access to Sales Area, set “Read” on crm_sitemapprivilege For Security role: Access to Marketing Area, set “Write” on crm_sitemapprivilege For Security role: Access to Service Area, set “Create” on crm_sitemapprivilege For Security role: Access to MyCustom Area, set “Append” on crm_sitemapprivilege

Once I’ve done that, I add those security roles to the users based on what they need to see. So for example: User1, need to see sales area, assign security role: Access to Sales Area. User2, need to see marketing area, assign security role: Access to Marketing Area. and so on,

you get the drill.

Last thing to mention is the possible privilege values that you can use. These can be:

All AllowQuickCampaign Append AppendTo Assign Create Delete Read Share Write

you can also use a combination of those values such as: “Read,Write” or “Read,Write,Create” and so on.

so your privilege tag will look something like this:

<Privilege Entity=”crm_sitemapprivilege” Privilege=”Read,Write” />
<!– OR –>
<Privilege Entity=”crm_sitemapprivilege” Privilege=”Read,Write,Share,Write,Append” />

The advantage of using combinations is that it will allow you to do this for as many Areas as you could ever need.

Hope this helps. Please comment below with feedback, thoughts or suggestions.

Scribe Insight cross-reference drop-down and pick-list mapping approaches (option sets in Dynamics CRM)

In your Scribe workbench dts package you usually need to map a dropdown (or picklist) to another dropdown or optionset (as in Dynamics CRM). This is a common requirement as part of data migration and data integration projects to link between drop down menus in source system to those corresponding to the target system.

For example, the source system (assume it’s a file) has Salutations values as:

id-value
1-Mr
2-Mrs
3-Ms

 

The target connection on the other hand (assume it’s Microsoft Dynamics CRM 2011 system), has option set values as follows:

Value-Label
100000000-Mr
1000000001-Mrs
1000000002-Ms

 

To achieve this mapping between the id and values of both source and target systems, there are a number of approaches and methods as listed below:

 

Method 1: Use a cross reference (Xref.ini) file for mappings. This is the standard approach (I claim) for mapping two optionsets in Scribe Insight. All you need to do is create a new file, call it anything such as XREF.INI. Within this file, build all your mappings as follows:

[Salutation_Code]
1=100000000
2=1000000001
3=1000000002

 

[Title_Code]
1=Owner
2=President
3=Manager
4=Executive Director
5=Principal

 

As you can see in the file, there are two sections. You can have as many sections as you want all in one file. Each section will map two drop down menus together. The first section, Salutation_Code, maps Mr (id=1 in source file) to Mr (id = 1000000000 in target CRM).

Once you add your mapping section in the file, you can then write a formula to cross reference the value on the target to the source. The formula for the Salutation target field can be something like in this example: FILELOOKUP(S7, “XREF.INI”, “Salutation_Code” )

The following screenshot shows a sample forumula:

What will happen is that, based on the source value (in our case s7), the corresponding salutation in the cross reference file will be inserted to the target

More details can be found on Scribe Insight Online help here: http://community.scribesoft.com/helplibrary/mergedProjects/Insight/Formulas/Functions/FILELOOKUP.htm

 

Method 2: Map and crossreference drop downs and pick lists using Scribe Work bench formulas

In this method, you either create all your option set values in the target Dynamics CRM system to have the same id as the source (for example: 1=1) or you do a formula to manually do the mapping. This could work in cases where there is two or three options but otherwise, it gets too complicated for no real benefit.

The formula can be something like this:

IF(S7=”1″,”100000000″,IF(S7=”2″,”100000001, “”))

In other words, if the source = 1 (Mr), then set the target = 100000000. Else, if source = 2 (Mrs), then set target = “100000001”. Otherwise, leave target blank.

Dynamics CRM Entity and Field Display Name, Field Schema Name and Field Logical name or Attribute name

In Dynamics CRM there is a difference between CRM Entities and Fields Display Name, Entity/Field Schema Name and Entity/Field Logical name (also known as Attribute name).

Display name is clear. It is the name shown to the CRM user and can have spaces, etc. Then you got these two:

  • SchemaName: Name that will be used to create the database column  for the field. This name can be mixed case. The casing that you use sets the name of the object generated for programming with strong types or when you use the REST endpoint. So it could be something like new_FieldSchemaName
  • LogicalName: This is the name, auto generated based on Schema name but the system sets it to all lowercase letters.

Every entity and field has a schema name (DB name – mixed case) and a logical name (all lower case).

Schema name retains the casing but logical name will always be lowercase.

When writing code to call/use fields, we always use schema names (DB names) not logical/attribute name.

As you can see from the following screenshot, you decide the display and schema name during creation while the attribute name will be generated by Dynamics CRM exactly as the schema name but all lower case.

 

Schema-vs-Logical-Name

 

Once your field is created, you can see in the following screenshot the Name (logical name), the schema name (DB name – mix case) and the Display name (the one the customer sees).

 

Schema-vs-Logical-Name

 

The same applies to entities.

This post may sound like it is targeting only those who are starting to work with Dynamics CRM for the first time, but in reality I have met a number of Dynamics CRM developers who didn’t know this information. Hence, I hope this is useful. Please comment with your views below.

 

Add or Import Marketing List members contacts accounts or leads to a Dynamics CRM Marketing List using Scribe

There are multiple ways to import marketing list members such as contacts, accounts and leads to a marketing list. A common way of doing this is by creating a custom entity that links your contact (or lead or account) record to the marketing list. A plugin then fires every time a new record in this custom entity is created to add the contact to the marketing list. This is detailed in the following Dynamics Community post: https://community.dynamics.com/product/crm/crmtechnical/b/hardworkdays/archive/2012/05/21/ms-crm-2011-import-of-marketing-list-members-using-standard-import-with-small-extensions.aspx

Another simpler way of importing Marketing List members such as contacts to a Dynamics CRM Marketing List is using Scribe Insight. Scribe allows you to access the many to many entity that links contacts, leads and accounts to a marketing list. This entity is called listmember which is in effect a table in the CRM database. Using Scribe, you can read directly from any source such as a text file, CSV file, XML or any other type and then Scribe can insert directly into the list member table in CRM. Once these records are created with type listmember, this will mean they are now members in the marketing list.

To explain more, assume you got a csv file with 2 contact records as follows:

first name, contact unique number, marketing list name, entity type code

Darren,1234,ML1,2

Eva,2345,ML1,2

* Create a new Scribe workbench dts package and select the CSV file above as your source.

* Connect to your Dynamics CRM organisation using your Scribe Dynamics CRM adaptor. Connect to the listmember table object in your Dyanamics CRM database.

*Next thing to do is to write a formulat that uses the marketing list name and contact unique number to lookup the GUID of the marketing list and the GUID of the contact record.

Your Scribe formulas will need to be applied to the target fields as follows:

ListMember Table, field listid = DBLOOKUP( S3, “CRMOrgConnectn”, “list”, “listname”, “listid” )

ListMember Table, field entityid = DBLOOKUP( S2, “CRMOrgConnectn”, “contact”, “crm_contactuniqueid”, “contactid” )

ListMember Table, field entityidtypecode = S4

Please note that the  field crm_contactuniqueid is a custom field that is used as a unique identifier for your contact records to use for looking up contacts. Any other similar field can be used.

Some Scribe screenshots to help you visualise what needs to happen:

 

Add Members to Marketing list using Scribe
Add Members to Marketing list using Scribe – Click to enlarge

.

Dynamics CRM automated deployment using dynamics crm developer toolkit from the SDK

Microsoft Dynamcis CRM developer toolkit that comes with the CRM SDK provides a wide variety of useful features. If you have created a Dynamics CRM Solution in Visual Studio using the Developer toolkit add-on that gets installed onto your Visual Studio, you can easily deploy your Dynamics CRM code directly by right clicking on the CRMPackage project of the solution and clicking deploy. This Deploy command will build and deploy all your plugins, custom workflows, web resources, etc.

In a previous post, I wrote about automated deployment of Dynamcis CRM using MSBuild from Visual Studio to your Dynamics CRM Server. In this post though, I will cover how to use the deploy command of the developer toolkit to automate your deployment of Dynamics CRM Visual Studio solutions onto your Dynamics CRM organisation.

The deploy command can be easily accessed from the Visual Studio Command prompt. You can then call the deploy command in the command shell. To make it easier, you can create a batch file that calls Visual Studio command prompt, navigates to where your CRMPackage project is and then finally calls the deploy command. This batch file can then be scheduled to run using a Windows Scheduled Task to automate the deployment of your Solution at pre-scheduled times.

Sample code for the deployment automation batch file to deploy the CRMPackage project is below:

call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
cd C:\Users\YourUser\Documents\Visual Studio 2010\Projects\CRM-Solution-Folder
devenv crm-solution.sln /deploy "debug"  /project CrmPackage

Enjoy! Tried and Tested.

Microsoft Dynamics CRM Deployment Automation and Scheduling Automated Deployments using MSBuild scripts, batch files and other tools

Automated Deployment during the development of Dynamics CRM projects implementation is a time, effort and cost saving approach. A combination of MSBuild (MS Build) scripts, batch files and custom built console applications can provide a fully automated Dynamics CRM deployment and development life cycle.

Additionally, Microsoft Developer Toolkit which is released as a free tool part of the Dynamics CRM SDK provides an excellent deployment functionality (amongst many other useful features) but this is the subject of another post about automated deployment using Dynamics CRM SDK developer toolkit : http://www.mohamedibrahim.net/blog/2012/08/09/dynamics-crm-automated-deployment-using-dynamics-crm-developer-toolkit-from-the-sdk/ .

Examples of the most common deployment automation requirements in Dynamics CRM development projects:

1) Automated Deployment by getting the latest code from Visual Studio (via TFS – Team Foundaion Server) and deploying into a Dynamics CRM organisation on a server (local VM or a development/test server).

2) Export of Dynamics CRM default solution or a specific CRM solution package and importing the solution into another environment or Dynamics CRM server (or organisation). This is also known as Promotion: Promoting a CRM solution from one environemnt (such as Development environemtn) to another environment (such as test).

3) Export a CRM Solution from a CRM Server and then check in this exported solution file (the solution zip file) into TFS for backup or reusage.

These are the most commmon automated deployments used in projects but there could be many more based on projects requirements.

To achieve each on of these deployment automation setup there are a number of approaches and methods. I’ll try now to give some samples on how to do these automated deployments mentioned before:

You will need to create a batch file that calls an MSBuild file which in turn can do the operaton. The reason for using a batch file is that you can then setup a windows scheduled task to run the batch file at your chosen time for running the build. You can also add an auto numbering to the batch file if you want to increment the build number after every build. In this case, you will need to store the last build number in a separate text file.

The minimum that you will need in the batch file:

:: Check if Visual Studio command line is available. If not, then go to missing and end of file

if not exist “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat” goto missing

:: Otherwise, call the Visual Studion Command shell.

call “C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat”

:: Call the msbuild file

msbuild myprojectbuild.msbuild /property:BuildVersion=%ver% /property:BuildDate=%builddate%>log\log_%builddate%_%ver%.txt

goto :eof

:missing

echo Visual Studio command prompt is missing

pause

goto :eof

 

Your MSBuild file that will get the latest code Visual Studio code from TFS can be too long but I’ll try to give you below the main commands that you will need to perform:

 <?xml version=”1.0″ encoding=”utf-8″ ?>

<!– All rights reserved for Mohamed Ibrahim Mostafa. www.mohamedibrahim.net Please leave this copyright notice if you use this file. –>

<Project xmlns=”http://schemas.microsoft.com/developer/msbuild/2003” InitialTargets=”Release”>

<PropertyGroup>

<!– Build version – alternatively these vallues can be passed from the batch file–>

<BuildVersion>1.1.0.0</BuildVersion>

<BuildDate>20120101</BuildDate>

<TFSUser>mytfsusername</TFSUser>

<TFSPassword>mytfspassword</TFSPassword>

<BuildConfiguration>Release</BuildConfiguration>

</PropertyGroup>

<Target Name=”Get”>

<!– get latest source code from tfs –>

<Exec Command=”tf get Clinet.Name/MySolutionName /force /recursive /noprompt /login:$(TFSUser),$(TFSPassword)” />

</Target>

<!– Build my visual studio CRM solution output binaries

<Target Name=”Build” DependsOnTargets=”Clean”>

<Message Text=”Building CRM solution code…” />

<!– Build all CRM-related outputs including plugins, scheduled tasks and user interface components –>

<MSBuild Projects=”Clinet.Name\MySolutionName\MyVisualStudio.sln” Properties=”Configuration=$(BuildConfiguration)”/>

</Target>

<!– now you have the visual studio solution built. use a console application to deploy it into CRM server as follows –>

<!– Use plugin registeration developer console application (available in SDK) to deploy plugins and workflows –>

<!– or alternatively use the deploy command of the microsoft dynamics crm developer toolkit (from the SDK) to deploy the whole solution into your CRM server organisation–>

<!– using the deploy command of the developer toolkit will be covered in a separate post –>

<!– The following command uses a custom console application that I have built to export Dynamics CRM solutions –>

<Target Name=”Package” DependsOnTargets=”Build”>

<Exec Command=”MyCustomDeploymentTool.exe export solution=Default outputdir=myfolder\CRM discoveryurl=$(DiscoveryUrl) orgname=$(OrganizationName)” />

<!– parameteres discovery url and organisation name are parameters in the property group –>

</Target>

<!–Now check in TFS and label your code using MSBuild commands –>

<Target Name=”Versioning” DependsOnTargets=”Package”>

<Exec Command=”tf add  /login:$(TFSUser),$(TFSPassword)” />

<Exec Command=”tf checkin MyProjectName\CRM_SolutionName_$(BuildDate)_$(BuildVersion).zip /login:$(TFSUser),$(TFSPassword)” />

<!– label TFS with the build number –>

<Exec Command=”tf label $(BuildVersion) MyProjectName/* /recursive /comment:&quot;Automatically labelled by Mohamed Mostafa build script.&quot; /login:$(TFSUser),$(TFSPassword)” />

</Target>

<Target Name=”Release” DependsOnTargets=”Versioning”>

<Message Text=”Completed..”/>    </Target>

</Project>

<!– All rights reserved for Mohamed Ibrahim Mostafa: www.mohamedibrahim.net –>

The console application that you can use to import or export a CRM solution will be the subject of another post. I think this post is too long already and I have spent good few hours writing it.

I hope this helps. If you have any questions, ideas or feedback please write them in a comment below.

If you want the various MSBuild files, batch files, etc then please comment below and I’ll email them to you (I tend to collect requests and send the files to a whole group in bulk).

Introduction & basic facts about Microsoft Dynamics CRM Activities, Activity Party, Activity Pointer and Entities: Phone call, Email, Appointment, Letter & Fax

This post is an attempt to collect all basic information and facts about Microsoft Dynamics CRM Activity related entities including: Activity Party, Activity Pointer, Phone call, Email, Appointment, Letter and Fax.

The following Diagram shows the relationship between these various Activity related entities and how the Activity Entities relationships work:

Activity Entity Relationships Diagram
Activity Entity Relationships

 

Let’s now start explain the Activity Pointer Entity:

  • The activity pointer (activity) entity represents any activity or task that is performed, or to      be performed by a user.
  • An activity is any action for which an entry can be made on a calendar.
  • Whenever you create an  activity record, a corresponding activity pointer record is created.
  • i.e. The activity record and the corresponding activity pointer record have the same value for the ActivityId attribute.
  • For example, if you create an Email record, the attribute values of Email.ActivityId and the corresponding ActivityPointer.ActivityId will be the same.
  • The ActivityPointer.ActivityTypeCode attribute defines the type of the activity.

 

On the other hand, the Activity Party Entity is:

  • An activity party represents a person or group associated with an activity.
  • An activity can have multiple activity parties.
  • Not all activity party types are available for each activity in Microsoft Dynamics      CRM, except for a custom activity.
  • There are 12 types of activity party in Microsoft Dynamics CRM. The activity party type is stored as an integer value in the ActivityParty.ParticipationTypeMask attribute.
  • The following is the list of all 12 types of Activity Party:
    Activity party type        Value          Description  
Sender 1 Specifies   the sender.
ToRecipient 2 Specifies   the recipient in the To field.
CCRecipient 3 Specifies   the recipient in the Cc field.
BccRecipient 4 Specifies the recipient in the Bcc field.
RequiredAttendee 5 Specifies   a required attendee.
OptionalAttendee 6 Specifies   an optional attendee.
Organizer 7 Specifies   the activity organizer.
Regarding 8 Specifies   the regarding item.
Owner 9 Specifies   the activity owner.
Resource 10 Specifies   a resource.
Customer 11 Specifies   a customer.
Partner 12 Specifies   a partner.

 

 

Some facts about the Email Activity Entity:

  • CRM includes the E-mail Router software that manages the routing of email to or from Microsoft Dynamics CRM.
  • The email activity is delivered using email protocols.
  • E-mail Router supports the following email protocols: Exchange Web services, POP3, SMTP, and WebDav
  • In addition to the E-mail Router software, the email activity can also be delivered by using Microsoft Dynamics CRM for Microsoft Office Outlook.

 

Hope this helps. Please comment below if you have something to add, any corrections to the post or if you have any questions

Thanks

Mohamed Mostafa

Notes and Introduction to Microsoft Dynamics CRM Organization, Business Units, CRM Users & Teams

This post is a collection of some notes, facts and basic information about Dynamics CRM Organisation, Business Units, Users and Teams entities and business data model. This can be used as a quick introduction to these specific entities:

• An organization is the top level of Dynamics CRM hierarchy. This entity cannot be customised.
• Announcements are alerts sent to all users in an organisation.
• Announcements are represented by the BusinessUnitNewsArticle entity.
• Business unit is a unit of the top-level organization and can be parents of other business units (child business units).
• First business unit created for an organization is called the root business unit and cannot be deleted.
• Other business units can be deleted in Microsoft Dynamics CRM 2011 (was not possible in CRM 4.0).
• An entity can be owned by organisation, business unit owned, user owned, team owned or No ownership by any other entity.
• An entity is normally owned by user or team owned as this allows individual and teams ownership and allow applying Security roles onto it.
• Ownership for an entity is defined in the metadata property OwnershipType.
• Each user corresponds to a user in the Active Directory for that organization
• Users can be disabled but they cannot be deleted.
• Each user must be associated with only one business unit
• You must assign the user to at least one security role. Even if the user is part of a team that has assigned
• Teams can be deleted in Microsoft Dynamics CRM 2011.
• Each team must be associated with only one business unit.
• A team can include users from any business unit, not only the business unit with which the team is associated.
• Non-Interactive user access the system only through the Web service.
• Non-interactive users are often used when writing service-to-service code because they do not use up a license
• CRM Online allows for five free non-interactive users
• Administrative users has access to the Settings area but does not have access to the Sales, Marketing, and Service areas
• Support User is created by the Dynamics support team
• Access Modes (AccessMode): Administrative, Non-Interactive, Read, Read-Write and Support.
• CalType (License Type): Administrative, Device Full, Device Limited, Full, Limited.
• Access is based on the roles assigned to the user plus the roles assigned to the team that a user is a member of.
• Users and teams can own records if the OwnershipType is set to OwnershipTypes.UserOwned
• Use of teams is optional in Microsoft Dynamics CRM.
• To disable a non-interactive user, update the user record changing the accessmode value to any other value. The user will be disabled automatically.
• Each user set of privileges is a union of all privileges from the user’s roles and privileges from all teams’ roles in which the user is a member.
• You can use a team to efficiently share business objects with a group of users.
• Disable a user if they leave an organisation to keep their records for further use.
• Disable users on vacation to remove them from workflow processes (good practice).
• Disabled users do not use licenses.
• You can call the WhoAmIRequest message to find out the organization or business unit for the currently logged on or impersonated user.

Read-Optimized (Read Optimised) Forms in Rolup 7

Microsoft Dynamics CRM 2011 Rollup 7 has been released with a new feature called: Read-optimized forms. These forms are a new way to display CRM information as read only to those CRM users who do not need to edit informat. It also helps CRM users to load information on forms much quicker. The idea is simply a form that doesn’t display the ribbon, form navigation, does not execute scripts on the form and doesn’t display embedded web resources in the form.

This way read optimised forms can load up much faster than current Dynamics CRM standard forms allowing much quicker access to read only data. The form has an “Edit” button that switches the form to a normal editable CRM 2011 form.

Read-optimized forms are disabled by default in CRM Rollup 7. You have to turn it on to the whole organisation from the Settings –> Administration –> System Settings –> Customization tab. You can also allow or deny individual CRM users to select the read-optimised mode for viewing forms or not for themselves. You can also select a number of CRM users and allow read-optimized mode only for them (from the Users section in settings –> Administration).

This article on the Microsoft Dynamics CRM Blog explains this new feature in detail:

http://blogs.msdn.com/b/crm/archive/2012/03/22/read-optimized-forms.aspx

Mohamed