Return and display picklist value (display value) in custom sql report reporting services report in Microsoft Dynamics CRM 4 entity attribute and StringMap picklist values table

Normally, you should be able to get the picklist display value and picklist item id in the filtered view of any entity. In some cases, you may need to work with StringMap table directly to get the picklist values for a specific field of a given entity. This could be the case if you are not using the filtered view for some reason or if you want to write a report based on the table or the non-filtered view, the following post is providng the query (queries) needed to do so.

To get the display value of any picklist, you need to use the StringMap table. If you are writing a custom ssrs (SQL Server Reporting Services) report for Dynamics CRM 4, you usually need to return the picklist display value not the picklist item id.

For example: in the opportunity entity, you have a picklist attribute “Rating” (attribute name opportunityratingcode). If you are writing a custom SQL report to add to CRM and you want to display the values of the attribute, you will find that the display value of the picklist is not stored in the filtered view of Opportunity (FilteredOpportunity). To get the display value of any picklist, you need to use the StringMap table.

There many ways to get the information from the StringMap table, I will mention two ways here:

1) using Inner Join (simple - one picklist only)
This way, you just simply join the two tables: your entity filteredview and the StringMap table
/* the query uses out of the box attributes, so should run successfully on all CRM organisations*/
SELECT opp.name, opp.estimatedvalue_base, opp.closeprobability, StringMap.Value
FROM Opportunity as Opp INNER JOIN
  StringMap ON Opp.opportunityratingcode = StringMap.AttributeValue
WHERE (StringMap.ObjectTypeCode = 3) AND (StringMap.AttributeName = N'opportunityratingcode')
AND (opp.accountid = 'input your accoung GUID here'

This query will return list of all Opportunities for the specified account display the picklist display value rather than the id.

2) using Temp table (my prefered way for multiple picklists)

This query is longer and uses/declares temp tables but it is the simplest way in case you have several picklists and you want to return the display value of multiple picklists. You just create several temp tables just like @TempSM, where each temp table returns the list of display values for each picklist and then join them together.

1 Picklist query:
/* the query uses out of the box attributes, so should run successfully on all CRM organisations*/
Declare @TempOpp table(OpportunityID uniqueidentifier, OpportunityName nVarchar(max),
Estimatedvalue float, Probability float, Rating nVarchar(max))
Insert into @TempOpp
select opp.opportunityid,opp.name ,
opp.estimatedvalue_base,
opp.closeprobability,
opp.OpportunityRatingCode
From Opportunity opp
where opp.accountid = '97F97A5A-2622-DF11-A1C3-005056BA6B8A'
Declare @TempSM table(AttributeValue nVarchar(max), Value nVarchar(max))
Insert into @TempSM
select AttributeValue, Value
from StringMap
WHERE (StringMap.ObjectTypeCode = 3) AND
(StringMap.AttributeName = N'opportunityratingcode' )
select t1.OpportunityName, t1.Estimatedvalue, t1.Probability, t2.Value as RatingDisplayValue
from @TempOpp as t1 left outer JOIN @TempSM as t2 ON
(t1.Rating = t2.AttributeValue)

This query will return list of all Opportunities for the specified account display the picklist display value rather than the id.

2 Picklists query:
------------------
/* the query uses out of the box attributes, so should run successfully on all CRM organisations*/
Declare @TempOpp1 table(OpportunityID uniqueidentifier, OpportunityName nVarchar(max),
Estimatedvalue float, Probability float, Rating nVarchar(max), Priority nVarchar(max))
Insert into @TempOpp1
select opp.opportunityid,opp.name ,
opp.estimatedvalue_base,
opp.closeprobability,
opp.OpportunityRatingCode,
opp.PriorityCode
From Opportunity opp
where opp.accountid = '97F97A5A-2622-DF11-A1C3-005056BA6B8A'
/* Now we have @TempOpp1 with list of all opportunities for the specified account but with ID for picklist value not display names*/
/*Then we declare a temp table for Rating picklist*/
Declare @TempSM table(AttributeValue nVarchar(max), Value nVarchar(max))
Insert into @TempSM
select AttributeValue, Value
from StringMap
WHERE (StringMap.ObjectTypeCode = 3) AND
(StringMap.AttributeName = N'opportunityratingcode' )
Declare @TempOpp2 table(OpportunityID uniqueidentifier, OpportunityName nVarchar(max),
Estimatedvalue float, Probability float, Rating nVarchar(max), Priority nVarchar(max))
Insert into @TempOpp2
select t1.OpportunityID, t1.OpportunityName, t1.Estimatedvalue, t1.Probability,
t2.Value as RatingDisplayValue,t1.Priority as Priority
from @TempOpp1 as t1 left outer JOIN @TempSM as t2 ON
(t1.Rating = t2.AttributeValue)
/*tempopp2 now has opportunities with the rating display value*/
/*Now creating a temp table for Priority picklist*/
Declare @TempSM1 table(AttributeValue nVarchar(max), Value nVarchar(max))
Insert into @TempSM1
select AttributeValue, Value
from StringMap
WHERE (StringMap.ObjectTypeCode = 3) AND
(StringMap.AttributeName = N'PriorityCode' )
select t1.OpportunityID, t1.OpportunityName, t1.Estimatedvalue, t1.Probability,
t1.Rating as RatingDisplayValue,t2.Value as Priority
from @TempOpp2 as t1 left outer JOIN @TempSM1 as t2 ON
(t1.Rating = t2.AttributeValue)

--------------------------------------------

and so on. You create temp table for each picklist, join it with opportunity temp table and then carry on.

Note: This is one way of doing this. There are obviously many other shorter ways of doing this. I personally prefer temp tables a lot because although longer, they are simpler and easier to use. They also bypass any issues with null values in the right table of the join.

Not related Note: Always use filtered views when writing custom SQL reports on SSRS for CRM as they comply with CRM security.

Hide, Display, Resize and Rename left navigation links, CRM fields and attributes using Javascript for Microsoft Dyanmics CRM 4.

Scripts for Resizing, Hiding and renaming left navigation links, fields and attributes in Microsoft Dynamics CRM 4 using Javascript. This post is just a collection of some Javascript code for various common scripts that is frequently used in CRM form events, CRM entity events, etc. These script blocks can be used in OnLoad, OnSave events for CRM forms and OnChange events for CRM fields.

//------- Resize CRM form in the onload event
window.resizeTo(screen.availWidth * 0.85, screen.availHeight * 0.85);
//-------Rename left menu link / Left Navigation. Example: Contacts
var navItem = document.getElementById(’navContacts’);
navItem.innerHTML = navItem.innerHTML.replace(’>Contacts’,'>Students’);
//------Hide left menu link / Navigation. Example: Workflow
var navLeftItem = document.getElementById(’navAsyncOperations’);
navLeftItem.style.display = ‚Äėnone‚Äô;
//-----Hide Left navigation menu item link of a CRM form based on
// a value in a picklist on the same form.
//Get contacts left navigation menu item element.
var navLeftItem = document.getElementById(’navContacts’);
//if picklist (customer type code) value is equal to 1 (1st item in picklist) then
//hide left menu item (contacts link is used as an example), otherwise, show it.
if(crmForm.all.customertypecode.DataValue == 1)
{
¬†navLeftItem.style.display = ‚Äėnone‚Äô;
}
else
{
¬†navLeftItem.style.display = ‚Äėinline‚Äô;
}
 //-----Hide a CRM field on a form. example: the "name" field.
crmForm.all.name_c.style.display = 'inline';
crmForm.all.name_d.style.display = 'inline';
//-----Hide a CRM field on a form (example: the "name" field)
//based on the selected value in a picklist
if(crmForm.all.customertypecode.DataValue == 1)
{
         crmForm.all.name_c.style.display = 'inline';
         crmForm.all.name_d.style.display = 'inline';
}
else
{
         crmForm.all.name_c.style.display = 'none';
         crmForm.all.name_d.style.display = 'none';
}  ////Add this code to the OnLoad event of the form and
////to the on change event of the picklist attribute (field) as well
//---------Function to hide CRM field in a form. 
//Function accept fieldname as a parameter and
//boolean parameter to remove (hide) entire row on form
HideField('name'); //replace "name" with your field/attribute name
 
function HideField( fieldName, removeEntireRow )
{
 // Always hide the elements, even if we will be hiding the whole row.
 // This allows us to show another field in this row later without this
 // one showing up.
 var elem = crmForm.all[fieldName + "_c"];
 if( elem != null ) elem.style.display = "none";
 elem = crmForm.all[fieldName + "_d"];
 if( elem != null ) elem.style.display = "none";     
 
 if (removeEntireRow)
 {
  var elem = crmForm.all[fieldName + "_d"];
  if( elem != null ) elem.parentElement.style.display = "none";
 }
}

 This post was written quickly from memory and some code blocks here and there, so you might find some minor spelling mistakes. Please comment below if you find any issues with the script blocks or if you want me to extend this post to include additional script.

Script to Hide Add Existing Record button and Add New Record button using Javascript in Microsoft Dyanmics CRM

If you want to hide the two top left  buttons in the assicated view of any entity,  Add Existing Record and Add New Record Buttons, you can use the following javascript code i the onLoad Event of the Microsofty Dyanmics CRM 4 Form.  This post relies on and is an extension to the existing useful post by Dave Hawes.

 //This javascript should be added to the onLoad event for the form of the entity where you want to hide buttons for the associated views of other entities

//-------Hide Add Existing Record Button Only----Method 1----
HideAssociatedViewButton('new_account_new_project', 'Add existing Project to this record');
function HideAssociatedViewButton(loadAreaId, buttonTitle)
{
    var navElement = document.getElementById('nav_' + loadAreaId);
    if (navElement != null)
    {
        navElement.onclick = function LoadAreaOverride()
        {
            // Call the original method to launch the navigation link
            loadArea(loadAreaId);
            var associatedViewIFrame = document.getElementById(loadAreaId + 'Frame');
            if (associatedViewIFrame != null)
            {
                associatedViewIFrame.onreadystatechange = function HideTitledButton()
                {
                    if (associatedViewIFrame.readyState == 'complete')
                    {
                        var iFrame = frames[window.event.srcElement.id];
                        var liElements = iFrame.document.getElementsByTagName('li');
                        for (var i = 0; i < liElements.length; i++)
                        {
                            if (liElements[i].getAttribute('title') == buttonTitle)
                            {
                                liElements[i].style.display = 'none'; //this will hide and align properly
                                liElements[i].style.visibility = 'hidden'; // this is needed when re-sizing cause button to re-appear.
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}

//—End of Hide Add existing button Only

//——————Hide Add New Record Button and Add Existing Button ———

//Hide Both Buttons-----------
HideAssociatedViewButtons('new_account_new_project', ['Add existing Project to this record', 'Add a new Project to this record']); //Where "Project" is a custom entity.
//OR Hide Add Existing Button Only-----Method 2-------
HideAssociatedViewButtons('new_account_new_project', ['Add existing Project to this record']);  //Where "Project" is a custom entity.

function HideAssociatedViewButtons(loadAreaId, buttonTitles){
    var navElement = document.getElementById('nav_' + loadAreaId);
   if (navElement != null)    {
        navElement.onclick = function LoadAreaOverride()        {
            // Call the original CRM method to launch the navigation link and create area iFrame
            loadArea(loadAreaId);
            HideViewButtons(document.getElementById(loadAreaId + 'Frame'), buttonTitles);
        }
    }
}

function HideViewButtons(Iframe, buttonTitles) {
    if (Iframe != null ) {
        Iframe.onreadystatechange = function HideTitledButtons() {
            if (Iframe.readyState == 'complete') {
                var iFrame = frames[window.event.srcElement.id];
                var liElements = iFrame.document.getElementsByTagName('li');

                for (var j = 0; j < buttonTitles.length; j++) {
                    for (var i = 0; i < liElements.length; i++) {
                        if (liElements[i].getAttribute('title') == buttonTitles[j]) {
                             liElements[i].style.display = 'none'; //this will hide and align properly
                             liElements[i].style.visibility = 'hidden'; // this is needed when re-sizing cause button to re-appear.
                            break;
                        }
                    }
                }
            }
        }
    }
} 

Credit goes to Dave Hawes Blog post mentioned above.

 

Introduction and Notes about WCF, Silverlight and Creating a Silverlight application that consumes – invokes a WCF service via async (asynchronous) web service call

This post is an introduction and a collection of some useful information, notes and facts about WCF in genreal, Silverlight and running a silverlight web application that uses a WCF service via asynchronous web service call.

– The first fact that you need to know is that:

The only option for web service calling in Silverlight is asynchronous and Silverlight framework does not provide any API for synchronous call. Saying that, there are few work arounds for synchronous web service calls from silverlight to a WCF service. Personally, I haven’t tried or need to use any of these. If you are interested, you can look at one of these posts:
 * http://weblogs.asp.net/razan/archive/2010/01/14/emulating-synchronous-web-service-call-in-silverlight.aspx
 * http://marcgravell.blogspot.com/2009/02/async-without-pain.html
 * http://petesbloggerama.blogspot.com/2008/07/omg-silverlight-asynchronous-is-evil.html
– The greatest advantage of calling methods asynchronously is because it enables the application to continue doing useful work while the method call runs. If there is any delay from the WCF service in sending back the required data, Async calls ensures that your client application is not hanging there freezing and doing nothing until the Windows Communication Foundation (WCF) services returns the requried data. WCF and clients can participate in asynchronous operation calls at two distinct and different levels of the application. This makes WCF applications flexibile to maximize throughput balanced against interactivity.

– Visual Studio .NET 2008 gives you two project templates to create a WCF project:
¬†1- “WCF Service Application” and
¬†2- “WCF Service Library.”

WCF Service Application is the conventional web service application similar to ASP.NET web service but in this case built on Windows Communication Foudnation technology.

WCF Service Library project is different. The output of this project is a compiled dll file(s) along with a dll.config configuration file. The produced output can then be added to a client service application or project, deployed as a separated secure web service or as part of a larger hosted web service.

– When creating a WCF service for a silverlight application, you can simply add the WCF service to the test Web project which is added by default by Visual Studio when you create a new Silverlight 3 project. You can do this by right clicking on the silverlight web project (test project usually called .Web) and then click on add new item. In the new item window, always choose in this case silverlight enabled WCF service as this adds one line to your web.config. On the other hand, you can add the WCF service as another project to the same solution or even a separate solution which is the more practical approach as normally the web service is separate and hosted independantly from its client(s).

– If the WCF client application is not silverlight, opt to use the asynchronous approach in your operation implementation especially in the case when the service implementation makes a blocking call, such as doing Input/Output IO work.

Generally, even if you have a choice to choose between a synchronous and asynchronous call, always try to opt for the asynchronous one.

MSDN (and Microsoft) specifies the essential cases that you need to use Asynchornous calls to WCF as follows:

* If it is a silverlight application (the only option you have really!).

* If you are invoking operations from a middle-tier application.

* If you are invoking operations within an ASP.NET page, use asynchronous pages.

*- If you are invoking operations from any application that is single threaded, such as Windows Forms or Windows Presentation Foundation (WPF).

In all these cases, always try to opt to Async calls rather than synchronous if this is an option.
– WCF is Microsoft’s attempt of unifying web and distributed services. WCF services can work with a variety of client applications including php, ruby, etc. and any client that can use basicHTTP binding.

– WCF is regarded as the successor to conventional Microsoft web services and communication technologies such as: DDL, DCOM, Remoting, Web Services, WSE, etc.. This is especially because WCF is built with the aim to provide “SOA” or Service Oriented Architecture for distributed applications.

– WCF can have messages sent in a variety of channels including HTTP, TCP, MSMQ, Named pipe, etc.

– WCF runtime resides under the System.ServiceModel namespace.

– In most cases WCF has a much better and faster performance ranging between 25%-50% in some cases. Refer to this MSDN article for some comparisons: http://msdn.microsoft.com/en-us/library/bb310550.aspx

– The throughput of WCF is inherently scalable from a single processor to a quad processor.

– The WCF model unifies the feature wealth of ASMX, WSE, Enterprise Services, MSMQ, and Remoting. This way, developers only have to master a single programming model.

– WCF can be hosted in IIS Servers, Windows services and standalone apps like windows forms, console apps.

– WCF provides a DataContractSerializer which allows complex data types and private attributes to be serialized and sent. Being Serializable means, the object can be hydrated, dehydradted from a stream/bunch of bytes, into a living class instance.

Configure Microsoft SQL Server to allow remote connection and remote SQL Management Studio access

To get straight to the point. I have been trying to setup Microsoft SQL Server 2008 to allow remote connection and specifically I wanted the SQL server to allow SQL Server Management Studio on a different computer completely outside the network to be able to access this remote SQL Server and manage it fully without having to login on the remote Dedicated standalone SQL server. I also wanted to be able to access this server remotely from visual studio .net on the client machine. Please be aware that I am trying the extreme settings here of getting client (management studio or visual studio) to connect to the host server (SQL Server) where the client is on a completely different network from the host. i.e. This is a 100% Internet only remote connection not within the same network, lan, or even trusted domains, forests, etc..

There are a lot of setup steps that you need to do but remember there are two main parts of this setup:

  1. configure SQL Server to accept remote connection and,
  2. Setup and Configure the firewall running on this server machine to allow inbound incoming connections.

Step 1 is straightforward and there are a lot of MSDN and Technet articles that explain it. But anyway, to make this post informative here are the main steps:

  • Go to Programs -> SQL Server -> SQL Server Configuration tools -> SQL Server Configuration Manager.
  • Make sure that the SQL Server Browser service is running under (SQL Server Services).
  • Go to SQL Server Network Configuration, open the SQL Server instance that you want to use. Make sure that the TCP IP Protocol is enabled.
  • right click on this TCP/IP protocol node and click properties. Go to IP Addresses tab. Make sure that the server IP Address is: 1) on the list of IPs, 2) is Active, 3) is enabled.
  • You can either:¬†a)¬†let your SQL server to listen on all server ports for any incoming SQL server connection OR b) you can specify which exact port to¬†listen to. For a) set TCP dynamic Port¬†to “0” and leave the TCP port value blank. To achieve b) set dynamic value to blank and the TCP port to the port number that you want the server to listen to.
  • Restart the SQL Server instance service from SQL server Services node (All this configuration is still done from within the SQL Server Configuration Manager).
  • Go to the SQL server instant in management studio ->right click -> properties ->¬†connections -> Allow remote connections to this server.
  • Also, Go to the SQL server instant in management studio ->right click -> properties ->¬†Security -> Allow SQL Server and Windows authentication mode.
  • Look at this article for more details: http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/ec77d275-99c7-4cc0-b60d-707bde6f8c67/

Step 2 is the step I struggled with. Basically, I was unable to connect and didn’t know whether it is a Firewall problem or a problem with my configuration of the SQL server (step 1). Best way to troubleshoot that, allow ALL incoming inbound connections on your firewall. Try to connect remotely to the server (using the SQL Server management studio or Visual Studio .NET), if it works, then your issue was the Firewall. If it doesn’t, then it is an issue with SQL server configuration. PLEASE REMEMBER to disallow incoming inbound connections after you did this test!!!

For step 2, you need to do the following to setup and configure your windows server Firewall to accept and allow incoming connections to the host server on which you got SQL Server. So, Host Server Firewall configuration is as follows:

  • Allow incoming TCP port number 1433
  • Allow incoming UDP port number 1433
  • Allow incoming UDP port number 1434
  • Allow incoming TCP port number 135
  • Add the program sqlservr.exe to the exceptions list. By default, sqlservr.exe is installed in C:\Program Files\Microsoft SQL Server\MSSQL10.InstanceName\MSSQL\Binn, where InstanceName is MSSQLSERVER for the default instance, and the instance name for any named instance.

Once I have added all these ports to my exception list, i.e. opening all these ports for incoming traffic allowing access to my server, once I have done that, all my problems were solved and I managed to connect to the SQL server remotely via the Internet (not an internal network) where the client and host have no direct connections what so ever.

Some articles and useful resources related to step 2 (Firewall setup):

One final note:  The format to input the server name in the SQL Management Studio connect to server object box is as follows:

<IP>,<port>\InstanceName

for example: 92.37.54.28,2345\InstanceName

If you selected the all ports option. i.e. dynamic port = 0 and TCP Port is blank (as in step 1 above), then the format will be something like that:

server name box should have: 92.37.54.28\InstanceName or¬†just the IP address for the default instance (haven’t tried to setup a default instance though.. I have used named instances for added security.

That’s all for now. Hope this helps. Please write a comment if you have anything to add, correct me or if you have any related question.¬†Please let me know if you need any help or support on this.

Thanks,

Mohamed Mostafa

Hiding Left Navigation Menu Items in an Entity Form using Javascript in Microsoft CRM 4

This is just a follow on from my previous post (http://www.mohamedibrahim.net/blog/2009/07/30/renaming-left-menu-items-leftnav-entity-microsoft-dynamics-crm-4/). In this post, I explained how to rename left menu items in an entity form using javascript.

These links are created when a new N:1 relationship is created between two entities. The primary entity in this relationship will get a new left navigation link everytime a new N:1 relationship is created.

We have discussed in the previous post that the code to rename left menu navigation items (links to other N:1 entities) is:

var navItem = document.getElementById(’leftNavMenuItemID’);
navItem.innerHTML = navItem.innerHTML.replace(‚Äô>CurrentLinkValue‚Äô,’>NewLinkValue‚Äô);

So for example:

var navLeftItem = document.getElementById(’navContactsMenuItem’); // this will look for the element contact in the left menu of an account form
navLeftItem .innerHTML = navItem.innerHTML.replace(‚Äô>Contacts‚Äô,’>Employees‚Äô); //This will rename Contacts to Employees in the Account form

Now, to Hide specific links in the left menu, you can use the following script:

// Hide left menu navigation links on an entity form
var navLeftItem = document.getElementById(’navContactsMenuItem’);
navLeftItem .style.display = ‘none’;

This script will be in the OnLoad event of the form of the entity that you want to hide links created on the left handside of this entity form.

Renaming Left Navigation Menu items (leftnav) of an Entity in Microsoft Dynamics CRM 4

I will try to make this as simple and straight to the point as possible.

This post is to explain how to¬†to change the name and rename one or more¬†of¬†the left menu items – leftnav –¬†items of an Entity, for example the Account entity or the Contact entity or any other Custom entity. In summary, this should be done using a script in the onload event of the entity form and apparently can NOT be done using the Isv.Config file.

So for example, when you open an account record, on the left hand side of the Account form you will have the left navigation list of entities which are: Activites, History, Sub-Accounts, Contacts, Relationshiips, Workflows, Opportunities, Leads, Quotes, Orders, Invoices, cases, contracts, marketing lists and campaigns.

To rename any of these entities or any other custom entity has a 1:N relationship with the Account entity, you will need to put some javascript code (or script really) in the OnLoad event of the Account Form. This code will look for the name of the left navigation item (link to an entity) and rename it to whatever you want. You can not do this in ISV.CONFIG as you can only add new links to ISV.CONFIG but you can not edit already existing left menu items in this file as they don’t exist and are not displayed.

So, in the OnLoad event of the entity that you want to rename its left navigation menu items, you will need to put the fulling code (or something like it):

var navItem = document.getElementById(‘leftNavMenuItemID’);
navItem.innerHTML = navItem.innerHTML.replace(‘>CurrentLinkValue’,’>NewLinkValue’);

This code will look for the menu item that has an id (‘leftNavMenuItemID’) in your chosen entity form and replace its current link name to a new link name.

So for example:

var navItem = document.getElementById(‘navContactsMenuItem’);
navItem.innerHTML = navItem.innerHTML.replace(‘>Contacts’,’>Employees’);

If you input this code in the OnLoad event of the Account entity Form, this code will look for the “Contact” entity link in the left navigation and rename it from Contacts to Employees.

You can apply the same to any other entity either it is a customisable (system) or custom entity. You will need to use a HTML tool such as Microsoft’s Internet Explorer Developer Toolbar to find out the ID of the navigation item that you want to rename (‘navContactsMenuItem’).

Please let me know if you have a question or if you want me to clarify more.

Thanks,

Mohamed Ibrahim

Setting up Microsoft CRM Internet Facing Deployment IFD with Multiple organisations

You can always setup Microsoft Dynamics CRM with Internet Facing deployment IFD either using the IFD tool by Microsoft or using the manual hard coding in the config files. I have recently used the IFD tool to do so and after I managed to get everything sorted, an important question came to mind which is: How can we setup Microsoft Dynamics CRM with Internet Facing deployment and at the same time allowing the external (Internet) access to all the CRM server organisations. So for example, if you have 3 CRM organisations (organizations) and you expose your Dynamics CRM server to external access via the Internet, you will usually have one domain name and one IP address for this server. So www.yourcrmserverdomain.com points to an IP address of 91.91.91.91 and this IP address is the real IP address of your Microsoft Dynamics CRM server. How can you make this point to different organisations all setup on the same server and the same CRM server.

I did search quite a lot on google, I have to say to find the answer as I was away from my server to try it myself one and I could not find a post or an article discussing it. This is probably because it is¬†either too simple for everyone (although it didn’t seem that simple to me) or may be because¬†I¬†am useless in searching using the right keywords.

Anyway, the answer I found was very simple, although it might seem to some people (like me) as a potential issue because you have one server in IIS and you don’t have clear folder categorisation for each organisation to allow you to point different domains to different folders in the same CRM IIS node. Simply all you need to do is to direct the user to the server URL and then follow this with the organisation name.

So to point your external CRM users to organsiation 1, point these external users to go to www.yourcrmserverdomain.com/organisation1. And for example, for Organisation 2, www.yourcrmserverdomain.com/organisation2, and so on.. The default organisation can be accessed directly by using your CRM server URL (for ex: www.yourcrmserverdomain.com) or by the url www.yourcrmserverdomain.com/organisation1 (in case the default organisation is called organisation1). Both will work

Substitute the domain name, organisation 1 and organisation 2 with your actual domain and organisation names.

Please feel free to contact me if you have any questions.

Thanks,

Mohamed

Microsoft CRM 4.0 IFD Internet Facing Deployment (IFD) Internal Network address and subnet mask list of IP addresses.

Hi,

I have been working on setting up a test Microsoft dynamics CRM server on a server at home with Internet facing deployment. I wanted to try to see how CRM hosted will work. I have been through few issues that thankfully I managed to resolve them all. I will write another post specifically focusing on the deployment and IFD but for now, I want to focus on a quick issue that I had.

After the Microsoft Dynamics CRM was setup fine, I used the IFD tool (available free on Microsoft downloads website) to allow the Internet facing feature for the CRM server. On the IFD tool there is a list of machines that you can tell the IFD tool about. This is called “IFD Internal Network Address and Subnet Mask”. ¬†The first thing that came to mind on seeing this is that it is for the internal computers that are allowed access to the server. Reading through the IFD documentation, I found out that it is actually the opposite. This list of machines IPs is the list of¬†IPs for computers¬†which are not allowed access to the Dynamics CRM server from the Internet (IFD). i.e. Any computer with an IP in this list, it will only be allowed to connect to the CRM server internally but if you attempt to access CRM Server externally from this machine, it will not even get to the authentication form.

So assume you added to this list in the IFD tool a computer with IP 192.168.1.88.

If you attempt to connect with this machine to the Dynamics CRM server using the internal address for example: http://localhost/CRM/, this will work find.

But if you attempt to connect from this machine to the CRM server using the external address: http://www.yourcrmserverdomainname.com/ then this will NOT work.

I would refer to this list as the internal addresses banned from accessing the dynamics CRM server externally.

I had this issue and I was trying to access the CRM server externally with another machine at home but I wasn’t able to and then I found out that I should actually remove this machine’s IP address from the list in order to be able to access it.

Hope this will ever help someone!

Mohamed Ibrahim