2009/09/23
CRM 4.0 Software prerequisites
In addition to the software prerequisites below,
the Main Admin Account (which will be the Main Service account in CRM) to be used in the CRM 4.0 Install
must be a local administrator on the CRM Application Server, and possibly on the SQL Server as well.
Also the Main Admin Account must have full+extended privileges on the specified Organizational Unit (OU) in Active Directory (AD)...
For the CRM Server (IIS Server), the following must be installed:
1. Windows Server 2003 (Standard or Enterprise Edition, preferably Enterprise Edition on Production) with Service Pack 2
2. IIS 6 (with all options installed)
3. Also Windows Indexing Service
Please note that the following services must then be running on the CRM Server (IIS Server):
- Indexing Service
- World Wide Web Publishing
- IIS Admin Service
Then the actual CRM install will go and install the rest of the software listed below (from Microsoft_Dynamics_CRM_IG_Installing.doc, Section 2-8, Page 15):
(Please note that Microsoft .Net Framework 2 and Microsoft .Net Framework 3 can and be installed before this)
• SQL Server 2005 Reporting Services Report Viewer control
• Microsoft SQL Server Native Client
• Microsoft Application Error Reporting tool
• Microsoft Visual C++ Runtime Library
• MSXML 6
• Microsoft .NET Framework 3.0, which includes the following components:
o .NET Framework 2.0 (required by Microsoft Dynamics CRM Server)
o Windows® Workflow Foundation (required by Microsoft Dynamics CRM Server)
o Windows Presentation Foundation
o Windows Communication Foundation
And the SQL Server 2005 Server must have SQL Server 2005 (Standard or Enterprise Edition, preferably Enterprise Edition on Production)
with the following SQL Server components installed with Service Pack 2 applied on them:
1. SQL Server 2005 Database Engine with SP2
2. SQL Server 2005 Agent with SP2
3. SQL Server 2005 Reporting Services with SP2
4. SQL Server 2005 Full Text Search with SP2
I think that about covers it, but If I missed anything, perhaps the other guys can spot it…
2009/09/02
Some useful CRMform jscripts
function isFormInCreateMode()
function isFormInUpdateMode()
isFormActive = function()
hideNavBarItemById = function(navBarItemId)
setNavBarItemVisibilityByName = function(sectionName, itemName, visible)
hideNavBarItemByName = function(sectionName, itemName)
showNavBarItemByName = function(sectionName, itemName)
setFormEnabled = function(enabled)
hideTabById = function(tabId)
hideTabByName = function(tabName)
setControlEnabled = function(fieldObject, enabled)
setFieldRequired = function(fieldObject)
setFieldRecommended = function(fieldObject)
setFieldNotRequired = function(fieldObject)
refParam = function()
getLastKnownGood = function(fieldObject)
setLastKnownGood = function(fieldObject, value)
captureLastKnownGood = function(fieldObject)
restoreLastKnownGood = function(fieldObject)
hookValidationOnChange = function(fieldObject)
hookValidationOnBlur = function(fieldObject)
hookValidation = function(fieldObject, functionPointer, optionalFocusFieldObject)
performValidation = function()
function guidString4()
createGuid = function()
hideActionMenuItem = function(itemName)
HideAssociatedViewButtons = function(loadAreaId, buttonTitles)
*/
<strong>// Check if form in CREATE mode</strong>
isFormInCreateMode = function()
{
if (crmForm.FormType == 1)
return true;
else
return false;
}
<strong>// Check if form in UPDATE mode
</strong>isFormInUpdateMode = function()
{
if (crmForm.FormType == 2)
return true;
else
return false;
}
isFormActive = function()
{
var active = true;
if (crmForm.all.statecode != null && crmForm.all.statecode.DataValue != null )
active = (crmForm.all.statecode.DataValue == 0);
if( active )
active = (crmForm.FormType <> 4); // not readonly or disabled
return active;
}
/************************************************************************************************************************/
<strong>/* Navigation Map Functions</strong>
/************************************************************************************************************************/
/* hide a navigation bar item */
hideNavBarItemById = function(navBarItemId)
{
var navBar = document.getElementById(navBarItemId)
if (navBar != null)
{
navBar.style.display = "none";
}
}
<strong>/* hide a tab using the tab name as reference */</strong>
setNavBarSectionVisibilityByName = function( sectionName, visible )
{
var groups = document.getElementById("crmNavBar").childNodes;
if( groups != null )
{
for( var i = 0; i < groups.length; i++ )
{
var groupName = groups[i].childNodes[0];
if( groupName.innerText.trim() == sectionName )
{
groupName.style.display = visible ? "block" : "none";
groups[i].childNodes[1].style.display = visible ? "block" : "none";
}
}
}
}
<strong>/* hide a tab using the tab name as reference */</strong>
setNavBarItemVisibilityByName = function( sectionName, itemName, visible )
{
var groups = document.getElementById("crmNavBar").childNodes;
if( groups != null )
{
for( var i = 0; i < groups.length; i++ )
{
var groupName = groups[i].childNodes[0];
if( groupName.innerText.trim() == sectionName )
{
var items = groups[i].childNodes[1].childNodes;
for( var n = 0; n < items.length; n++ )
{
var item = items[n];
if( item.innerText.trim() == itemName )
item.style.display = visible ? "inline" : "none";
}
}
}
}
}
<strong>/* hide a tab using the tab name as reference */</strong>
hideNavBarItemByName = function( sectionName, itemName )
{
setNavBarItemVisibilityByName(sectionName, itemName, false);
}
/* hide a tab using the tab name as reference */
showNavBarItemByName = function( sectionName, itemName )
{
setNavBarItemVisibilityByName(sectionName, itemName, true);
}
/************************************************************************************************************************/
<strong>/* Form Functions</strong>
/************************************************************************************************************************/
setFormEnabled = function(enabled)
{
var iLen = crmForm.all.length;
for (i = 0; i < iLen; i++)
{
crmForm.all[i].Disabled = !enabled;
}
}
<strong>// gets the ordinal position of a tab</strong>
getTabNumber = function( tabName ) {
var tabs = document.getElementById("crmTabBar").childNodes;
if( tabs != null ) {
for (var i = 0; i < tabs.length; i++) {
var tab = tabs[i];
if (tab.innerText == tabName) {
return i;
}
}
}
return -1;
}
<strong>// returns a tab by name</strong>
getTabByName = function( tabName ) {
var tabs = document.getElementById("crmTabBar").childNodes;
if (tabs != null) {
var num = getTabNumber(tabName);
if( num >= 0 ) {
return tabs[num];
}
}
return null;
}
<strong>/* disable or enable tab using the tab name as reference */</strong>
setTabEnabledByName = function(tabName, enabled)
{
var tab = getTabByName(tabName);
if( tab != null ) {
tab.disabled = !enabled;
}
}
<strong>/* hide a tab using the tab id as reference */</strong>
hideTabById = function(tabId)
{
var tab = document.getElementById(tabId);
if( tab != null ) {
tab.style.display = "none";
}
}
<strong>/* hide a tab using the tab name as reference */</strong>
hideTabByName = function(tabName)
{
var tab = getTabByName(tabName);
if( tab != null ) {
//alert(tab.style.display);
tab.style.display = "none";
}
}
<strong>/* show a tab using the tab name as reference */
</strong>showTabByName = function(tabName)
{
var tab = getTabByName(tabName);
if( tab != null ) {
tab.style.display = "block";
}
}
<strong>/* Enabled/disable a control by setting the disabled property and toggling "ms-crm-ReadOnly" on the classname */</strong>
setControlEnabled = function(fieldObject, enabled)
{
fieldObject.disabled = !enabled;
if (!enabled && fieldObject.className.indexOf("ms-crm-Text") >= 0) {
// append readonly property to className if not already there
if (fieldObject.className.indexOf("ms-crm-ReadOnly") < 0)
fieldObject.className += " ms-crm-ReadOnly";
}
else
fieldObject.className = fieldObject.className.replace(/ ms-crm-ReadOnly/gi, "");
}
setFieldRequired = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 2);
}
setFieldRecommended = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 1);
}
setFieldNotRequired = function(fieldObject)
{
crmForm.SetFieldReqLevel(fieldObject.id, 0);
}
/************************************************************************************************************************/
<strong>/* Validation base functions</strong>
/************************************************************************************************************************/
/* represents a parameter object to be passed by reference
* use param.setValue from a function to set the return value of the parameter
* use param.getValue to read the returned value
*/
refParam = function()
{
this.array = new Array(1);
this.setValue = function(v) { this.array[0] = v; }
this.getValue = function() { return this.array[0]; }
}
/* gets/captures/restores the value of the field as the last known good value */
getLastKnownGood = function(fieldObject)
{
return fieldObject.getAttribute("lastKnownGood");
}
setLastKnownGood = function(fieldObject, value)
{
fieldObject.setAttribute("lastKnownGood", value);
}
captureLastKnownGood = function(fieldObject)
{
setLastKnownGood(fieldObject, fieldObject.DataValue);
}
restoreLastKnownGood = function(fieldObject)
{
fieldObject.DataValue = getLastKnownGood(fieldObject);
}
/*
* captures last known good value (captureLastKnownGood)
* hooks validation of the field onto the "onchange" event
*/
hookValidationOnChange = function(fieldObject)
{
fieldObject.setAttribute("onblur", null);
fieldObject.setAttribute("onchange", performValidation);
}
hookValidationOnBlur = function(fieldObject)
{
fieldObject.setAttribute("onchange", null);
fieldObject.setAttribute("onblur", performValidation);
}
hookValidation = function(fieldObject, functionPointer, optionalFocusFieldObject)
{
captureLastKnownGood(fieldObject);
fieldObject.setAttribute("validationFunction", functionPointer);
if( optionalFocusFieldObject != null )
fieldObject.setAttribute("focusFieldObject", optionalFocusFieldObject);
fieldObject.setAttribute("onchange", performValidation);
}
performValidation = function()
{
var fieldObject = event.srcElement;
if( fieldObject.DataValue != getLastKnownGood(fieldObject) )
{
var functionPointer = fieldObject.getAttribute("validationFunction");
var message = new refParam();
var valid = functionPointer(fieldObject, message);
if( !valid )
{
var msg = message.getValue() + "rnnWould you like to correct the value?";
if( confirm(msg) )
{
var focusObject = fieldObject.getAttribute("focusFieldObject");
if( focusObject == null )
focusObject = fieldObject;
else
{
captureLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
setLastKnownGood(focusObject, null);
}
focusObject.SetFocus();
event.returnValue = false;
hookValidationOnBlur(focusObject);
}
else
{
restoreLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
}
}
else
{
captureLastKnownGood(fieldObject);
hookValidationOnChange(fieldObject);
}
}
else
hookValidationOnChange(fieldObject);
}
guidString4 = function()
{
return (((1 + Math.random()) * 0x10000) 0).toString(16).substring(1);
}
createGuid = function()
{
return (guidString4() + guidString4() + "-" + guidString4() + "-" + guidString4() + "-" + guidString4() + "-" + guidString4() + guidString4() + guidString4()).toUpperCase();
}
<strong>/* hide action menu item */</strong>
hideActionMenuItem = function(itemName)
{
var element = document.getElementById(itemName)
if (element != null) {
element.style.display = "none";
}
}
hideActionMenuDeleteButton = function()
{
hideActionMenuItem("_MIonActionMenuClickdelete" + crmForm.ObjectTypeCode);
}
hideActionMenuDeactivateButton = function()
{
hideActionMenuItem("_MIchangeStatedeactivate" + crmForm.ObjectTypeCode + "5");
}
hideActionMenuActivateButton = function()
{
hideActionMenuItem("_MIchangeStateactivate" + crmForm.ObjectTypeCode + "6");
}
/* Hides the associated Views buttons. i.e Hides the add existing button. */
/* NB: If called multiple times, the settings of the previous calls are overwritten by the final one! */
/* A menu element on the "More actions" drop-down menu can be hidden
* by adding a string such as 'More Actions::Activate' to the buttonTitles array.
*/
HideAssociatedViewButtons = function(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);
}
}
}
<strong>/* Used internally by the 'HideAssociatedViewButtons' method */</strong>
HideViewButtons = function(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++)
{
buttonTitleParts = buttonTitles[j].split('::');
if (buttonTitleParts.length > 0)
{
buttonTitle = buttonTitleParts[0];
for (var i = 0; i < liElements.length; i++)
{
liElement = liElements[i];
if (liElement.getAttribute('title') == buttonTitle)
{
if (buttonTitleParts.length == 1)
{
liElement.style.display = 'none';
break;
}
else
{
/* We want to hide a menu item in a drop-down menu.
Find the descendant text element with the specified text.
Then find its parent list item and hide it:
*/
menuText = buttonTitleParts[1];
var spanElements = liElement.getElementsByTagName('span');
for (var k = 0; k < spanElements.length; k++)
{
spanElement = spanElements[k];
if (spanElement.className == 'ms-crm-MenuItem-Text' )
{
textElement = spanElement.firstChild;
if (textElement != null && textElement.nodeType == 3) /* 3 = Node.TEXT_NODE */
{
if (textElement.data == menuText)
{
liMenuItemElement
= spanElement.parentNode.parentNode.parentNode;
liMenuItemElement.style.display = 'none';
break;
}
}
}
}
}
}
}
}
}
}
}
}
}
<strong>// Load up a CRM entity into an iframe - typically the main view screen</strong>
getCRMFormSource = function(tabSet)
{
if (crmForm.ObjectId != null)
{
var oId = crmForm.ObjectId;
var oType = crmForm.ObjectTypeCode;
var security = crmFormSubmit.crmFormSubmitSecurity.value;
return "/userdefined/areas.aspx?oId=" + oId + "&oType=" + oType + "&security=" + security + "&tabSet=" + tabSet;
}
else
{
return "about:blank";
}
}
setVisibilityOfSectionContainingField = function(crmField, visibility)
{
if (visibility)
{
crmField.parentElement.parentElement.parentElement.style.display = 'block';
}
else
{
crmField.parentElement.parentElement.parentElement.style.display = 'none';
}
}
hideSectionContainingField = function(crmField)
{
setVisibilityOfSectionContainingField(crmField, false);
}
setVisibilityOfSectionWithName = function(tabNumber, sectionName, visibility)
{
var tab = document.getElementById('tab' + tabNumber.toString());
if (tab != null)
{
var tdElements = tab.getElementsByTagName('td');
for (var i = 0; i < tdElements.length; i++)
{
tdElement = tdElements[i];
if (tdElement.className == 'ms-crm-Form-Section ms-crm-Form-SectionBar')
{
textElement = tdElement.firstChild;
if (textElement != null && textElement.nodeType == 3) /* 3 = Node.TEXT_NODE */
{
if (textElement.data == sectionName)
{
trSectionElement
= tdElement.parentNode.parentNode.parentNode.parentNode.parentNode;
if (visibility)
{
trSectionElement.style.display = 'block';
}
else
{
trSectionElement.style.display = 'none';
}
return true;
}
}
}
}
}
return false;
}
hideSectionWithName = function(tabNumber, sectionName)
{
return setVisibilityOfSectionWithName(tabNumber, sectionName, false);
}
hideSection = function(tabName, sectionName) {
var tabNumber = getTabNumber(tabName);
return setVisibilityOfSectionWithName(tabNumber, sectionName, false);
}
showSection = function(tabName, sectionName) {
var tabNumber = getTabNumber(tabName);
return setVisibilityOfSectionWithName(tabNumber, sectionName, true);
}
showModalWindow = function(url, objectparams, x, y, height, width)
{
return window.showModalDialog(url, objectparams,
(height != null ? "dialogHeight:" + height.toString() + "px;" : "") +
(width != null ? "dialogWidth:" + width.toString() + "px;" : "") +
(y != null ? "dialogTop:" + y.toString() + "px;" : "") +
(x != null ? "dialogLeft:" + x.toString() + "px;" : "") +
"center:Yes;" +
"help:No;" +
"resizable:No;" +
"scroll:No;" +
"status:No;");
}
FetchViewer = function( iframeId )
{
var Instance = this;
var vDynamicForm;
var m_iframeTab;
var m_iframeDoc;
Instance.Entity = "";
Instance.Iframe = null;
Instance.FetchXml = "";
Instance.QueryId = "";
Instance.LayoutXml = "";
Instance.RegisterOnTab = function( tabIndex )
{
Instance.Iframe = document.getElementById( iframeId );
if( !Instance.Iframe )
return alert( "Iframe " + iframeId + " is undefined" );
m_iframeDoc = getIframeDocument();
var loadingGifHTML = "<table height="'100%'" width="'100%'" style="'cursor:wait'">";
loadingGifHTML += "<tr>";
loadingGifHTML += "<td valign="'middle'" align="'center'">";
loadingGifHTML += "<img alt="''" src="'/_imgs/AdvFind/progress.gif'/" />";
loadingGifHTML += "<div/><b>Loading View...</b>";
loadingGifHTML += "</td></tr></table>";
m_iframeDoc.body.innerHTML = loadingGifHTML;
if( parseInt( "0" + tabIndex ) == 0 ) Instance.Refresh();
else Instance.Iframe.attachEvent( "onreadystatechange" , RefreshOnReadyStateChange );
}
function RefreshOnReadyStateChange()
{
if( Instance.Iframe.readyState != 'complete' )
return;
Instance.Refresh();
}
Instance.Refresh = function()
{
if( !Instance.Iframe )
return alert( "Iframe " + iframeId + " is undefined" );
m_iframeDoc = getIframeDocument();
Instance.Iframe.detachEvent( "onreadystatechange" , RefreshOnReadyStateChange );
var create = m_iframeDoc.createElement;
var append1 = m_iframeDoc.appendChild;
vDynamicForm = create("<form name="'vDynamicForm'" method="'post'">");
var append2 = vDynamicForm.appendChild;
append2(create("<input type="'hidden'" name="'FetchXml'">"));
append2(create("<input type="'hidden'" name="'LayoutXml'">"));
append2(create("<input type="'hidden'" name="'EntityName'">"));
append2(create("<input type="'hidden'" name="'DefaultAdvFindViewId'">"));
append2(create("<input type="'hidden'" name="'ViewType'">"));
append1( vDynamicForm );
vDynamicForm.action = prependOrgName("/AdvancedFind/fetchData.aspx");
vDynamicForm.FetchXml.value = Instance.FetchXml;
vDynamicForm.LayoutXml.value = Instance.LayoutXml;
vDynamicForm.EntityName.value = Instance.Entity;
vDynamicForm.DefaultAdvFindViewId.value = Instance.QueryId;
vDynamicForm.ViewType.value = 1039;
vDynamicForm.submit();
Instance.Iframe.attachEvent( "onreadystatechange" , OnViewReady );
}
function OnViewReady()
{
if( Instance.Iframe.readyState != 'complete' ) return;
Instance.Iframe.style.border = 0;
Instance.Iframe.detachEvent( "onreadystatechange" , OnViewReady );
m_iframeDoc = getIframeDocument();
m_iframeDoc.body.scroll = "no";
m_iframeDoc.body.style.padding = "0px";
}
getIframeDocument = function()
{
return Instance.Iframe.contentWindow.document;
}
}
<strong>// Set custom form title</strong>
setFormTitle = function(title)
{
document.all.crmMenuBar.nextSibling.rows[0].cells[1].childNodes[0].innerText = title;
}
setLookupEnabled = function(control, enabled)
{
control.Disabled = !enabled;
}
<strong>/****************** BUTTONS *************************/</strong>
// Get an element in a document by it's class name
// Parameters:
// oElm = starting element
// strTagName = tags to filter on, e.g. TR or * for all
// oClassNames = arraylist of class names to find
// Returns:
// array of elements found
function getElementsByClassName(oElm, strTagName, oClassNames){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var arrRegExpClassNames = new Array();
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames.push(new RegExp("(^s)" + oClassNames[i].replace(/-/g, "-") + "(s$)"));
}
}
else{
arrRegExpClassNames.push(new RegExp("(^s)" + oClassNames.replace(/-/g, "-") + "(s$)"));
}
var oElement;
var bMatchesAll;
for(var j=0; j<arrElements.length; j++){
oElement = arrElements[j];
bMatchesAll = true;
for(var k=0; k<arrRegExpClassNames.length; k++){
if(!arrRegExpClassNames[k].test(oElement.className)){
bMatchesAll = false;
break;
}
}
if(bMatchesAll){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements)
}
<strong>// hide the entire grid menu bar of normal CRM grid view</strong>
hideGridViewMenuBar = function(document)
{
if (document != null)
{
var menuBar = document.getElementById('gridMenuBar');
if (menuBar != null)
{
menuBar.style.display = "none";
}
}
}
<strong>// hide the entire grid view bar of normal CRM grid view</strong>
hideGridViewGridBar = function(document)
{
if (document != null)
{
var gridBar = document.getElementById('gridBar');
if (gridBar != null)
{
gridBar.style.display = "none";
}
}
}
<strong>// Hide all the menu items/buttons on a menu bar of normal CRM grid view.
// The menu bar will still be visible when done</strong>
hideAllGridViewMenuBarButtons = function(document)
{
if (document != null)
{
var menuBar = getElementsByClassName(document, "ul", "ms-crm-MenuBar-Left");
if (menuBar != null && menuBar.length > 0)
{
menuBar[0].style.display = "none";
}
}
}
<strong>// hide the status bar of normal CRM grid view.</strong>
hideGridViewStatusBar = function(document)
{
if (document != null)
{
var menuBar = getElementsByClassName(document, "tr", "ms-crm-List-StatusBar");
if (menuBar != null && menuBar.length > 0)
{
menuBar[0].style.display = "none";
}
}
}
<strong>// add a button to the grid menu bar</strong>
addGridViewMenuButton = function(document, text, toolTipText, image, javaScriptString)
{
var buttonScript = "<li class="ms-crm-Menu" tabindex="-1" title="'" action="" onclick="'window.execScript(action)'">";
buttonScript += " <span class="ms-crm-Menu-Label">";
buttonScript += " <a class="ms-crm-Menu-Label" tabindex="-1" onclick="'return" href="'javascript:onclick();'" target="_self">";
if (image != null)
{
buttonScript += " <img class="ms-crm-Menu-ButtonFirst" tabindex="-1" alt="'" src="'/_imgs/vieweditor/" />";
}
buttonScript += " <span class="ms-crm-MenuItem-TextRTL" tabindex="0">" + text + "</span>";
buttonScript += " </a>";
buttonScript += " </span>";
2009/08/31
Hiding Navigational Items based on drop down value
Shawn Redmond
hideNavBarItemByName("Details:", "Divisions");
If (crmForm.all.fieldname != 3)
{
hideNavBarByItemName(‘Details’, ‘Value1');
hideNavBarByItemName(‘Details’, ‘Value2');
}
{
setNavBarItemVisibilityByName(sectionName, itemName, false);
}
setNavBarItemVisibilityByName = function( sectionName, itemName, visible )
{
var groups = document.getElementById("crmNavBar").childNodes;
if( groups != null )
{
for( var i = 0; i < groupname =" groups[i].childNodes[0];" items =" groups[i].childNodes[1].childNodes;" n =" 0;" item =" items[n];" display =" visible">
2009/08/29
Update Rollup 6 for Microsoft Dynamics CRM 4.0
The Microsoft Dynamics CRM Sustained Engineering team released Microsoft Dynamics CRM 4.0 Update Rollup 6 on Thursday, August 27, 2009.
Below are the links to the release and related information about the Rollup. Please see the Knowledge Base (KB) article for more details about the Update Rollup 6 content and instructions.
Microsoft Download Center: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=79f90982-c039-41c2-af8e-3119ecf27790
Microsoft Knowledge Base Article: http://support.microsoft.com/?kbid=970148
Install Details about Update Rollup 6
Update Rollup 6 is cumulative. You do not need to install any previous Update Rollups prior to Update Rollup 6
The Update Rollup 6 client can be deployed before the server is upgraded to Update Rollup 6
Update Rollup 6 can be uninstalled
Steps to make Update Rollup 6 available via AutoUpdate can be found in the Update Rollup 4 blog posting. The Link and Patch IDs can be found in the kb article at http://support.microsoft.com/?kbid=970148.
Information about how to avoid reboots when installing the CRM Outlook Client can also be found in the Update Rollup 4 blog posting.
Update Rollup 6 and all future Update Rollups will contain Mobile Express
The CRM team released the English version of Mobile Express on July 8, 2009 as an update to the CRM Server. Since Mobile Express is now part of the Server product it will be installed and updated as part of all Update Rollups going forward. There is a Getting Started: CRM Mobile Express blog that has some pointers on how to get started. The localized versions of Mobile Express will be delivered in a future update rollup.
2009/08/21
CRM integration into Skydrive
Hi
Last week I was asked to assist a user in Russia to integrate Skrydrive into CRM.
Skydrive is a online document mangement system provided by Microsoft using your windows live id.
This is fairly simple to do:
Download the CRM demonstration Toolkit and run it on the CRM server.
Connect to your CRM installation.
Open the SiteMap editor
Select the "Open from CRM" option.
You will notice that your sitemap is loaded in a easy to use UI editor.Having grouped your areas and subareas respectively.
Add a Area called Documents
Add Under (Documents)
On Documents select "Add Under" this will give a window with a drop down to CRM entities and a URL.
Use the URL Option. (You should have created a online skydrive account.Login into skydrive and copy the url for your document library.)
Paste the Url in the URL field
Description"Documents"
Icon URL (Your choice of icon)
Select "Publish to CRM"
Open CRM /Refresh CRM
You should have a Area called "Documents " in the navigational tree.
When opening, this will open your document library on skydrive.
Easy as falling out of a tree,just remember to let go of the branch.....:)
2009/08/20
Microsoft CRM Information Documentation
Top 10 Compelling Reasons to Use CRM Download
Customer Case Studies Download
What’s New in MS CRM 4.0 Download
Sales Force Automation Overview Download
Marketing Automation Overview Download
Customer Service Overview Download
MS CRM 4.0 What’s New Top 60 Datasheet Download
Microsoft CRM Additional Information
Implementing MS CRM 4.0 Download
Microsoft Dynamics CRM 4.0 Users Guide Download
Optimizing & Maintaining CRM 4.0 whitepaper Download
Preparing for your CRM Certication made easy with -Richard Knudson’s Dynamics CRM Trick Bag
2009/08/18
Microsoft CRM 4.0 Update Rollup Best Practices
Updates: Microsoft CRM 4.0 Update Rollup Best Practices
You may have noticed that the Microsoft CRM Update Rollups are being released on a regular basis like every 2 months since Update Rollup 2. This is much more frequent then the previous update release schedule (6 to 9 months). So how do Small Medium Businesses (SMB) manage this given the more frequent updates?
Here are three approaches and my notes on each one:
1. Only apply Update Rollup as needed to solve bugs/issues
- requires the least amount of administration resource, but could result in the highest reactive situation when encountering CRM issues/bugs that are solved by an Update Rollup
2. Apply every Update Rollup upon being released
- requires the most amount of administration effort to update the CRM Server and all of the CRM Outlook Clients upon each release of an Update Rollup. However, this offers the highest avoidance of CRM issues/bugs that are solved by Update Rollups
3. Apply Update Rollup on every 4, 5, or 6 months cycle
- a good balance of administration resource and risk avoidance due to CRM issues/bugs that are solved by an Update Rollup. As for 4, 5, or 6 - it would be your preference.
Guess which approach I'd recommend for most SMBs? Yup, number 3. I'd personally select the every 4 months cycle.
Some good practices on deploying Update Rollups:
1. Always backup your CRM environment per the Update Rollup instructions prior to applying the Update Rollup. If you have a test environment (I highly recommended having one), apply the Update Rollup there first.
2. Wait two weeks after the release of an Update Rollup before applying it - just like any software, Update Rollup may contain some bugs itself. There were some Update Rollups in the past that were "re-released" due to issues/bugs arised from the Update Rollup. If this does happen, contact Microsoft CRM Support immediately for resolution. And if you had waited after two weeks, you would mostly enjoy the benefit that a work-around/resolution is available due to Support already encountered the issue already. No need to be the very first to apply an Update Rollup in production unless it fixes a specific issue/bug
3. It is not necessary to apply both the CRM Server Update and CRM Outlook Client Update at the same time. I do highly recommend they are both applied the same time to get the latest fixes to all your CRM enviornments (Server and Outlook Clients). However, it is OK to apply the CRM Server Update first, and then apply the CRM Outlook Client Update the next few days/weeks. Or the other way around - apply the CRM Outlook Client Update first and then apply the CRM Server Update afterwards
4. Most SMB doesn't have a large CRM Users count, but if yours do, then I would look into auto deployment of the CRM Outlook Client Update to save time. Reference the Microsoft CRM 4.0 Implementation Guide - Microsoft_Dynamics_CRM_IG_Operating.doc, section "Automatically update Microsoft Dynamics CRM for Outlook" for details
5. If you had encountered a bug/issue and have not apply the latest Update Rollup yet. What should you do? I would open a CRM Support Incident via CustomerSource - if the bug is a bug and "not a feature" then there is no cost to the Support Incident and you would get a resolution from the CRM Support engineer to either apply the latest Update Rollup, a Hot Fix, or other work-around.
Configuring Microsoft Dynamics CRM 4.0 for Internet-facing deployment
Published: February 13, 2009 Updated: May 15, 2009
This document describes configuring Microsoft Dynamics CRM (On-Premise Edition) for Internet-facing deployment (IFD), and a few of the common issues and resolutions associated with Microsoft Dynamics CRM IFD.
You can deploy Microsoft Dynamics CRM (On-Premise Edition) using one of the following deployment types:
· Microsoft Dynamics CRM for internal users only
· Microsoft Dynamics CRM for internal users and IFD access
· Microsoft Dynamics CRM for IFD-only access
For more information about configuring Microsoft Dynamics CRM for Internet access only, see Internal Network Address under the "IFD configuration properties details" section in this article.
Microsoft Dynamics CRM uses Integrated Windows authentication to authenticate internal users. Integrated Windows authentication implements pass-through authentication functionality so that Microsoft Dynamics CRM users are not prompted a second time to log in to Microsoft Dynamics CRM after their initial sign on to the Active Directory network.
Configuring IFD for Microsoft Dynamics CRM enables access to Microsoft Dynamics CRM from the Internet, outside of the company firewall, without using a VPN solution. Microsoft Dynamics CRM configured for Internet access uses forms authentication to verify credentials of external users. When configuring Microsoft Dynamics CRM for Internet access, Integrated Windows Authentication must remain for internal users.
Configuring IFD sets the Microsoft Dynamics CRM Web site to use anonymous authentication for external users, and provides a sign on page to capture users' credentials and obtain an authentication ticket cookie. Microsoft Dynamics CRM IFD checks for a valid CRM ticket cookie before processing the page request. When a page request does not contain a valid CRM ticket, the page request is redirected to the sign-on page. A page request with an expired CRM ticket is also redirected to the sign-on page. Users access the Microsoft Dynamics CRM Web site by typing the IFD URL in Internet Explorer. Because this type of authentication sends user credentials and passwords using clear text, you should always configure Microsoft Dynamics CRM using a Secure Sockets Layer (SSL). For more information about SSL, see Make Microsoft Dynamics CRM 4.0 client-to-server network communications more secure. For more information about forms authentication and IFD, see Web Form (IFD) Authentication. For more information about forms authentication with active directory, see Forms Authentication in ASP.NET.
On This Page
Common Issues
Methods available to configure IFD
You can deploy Microsoft Dynamics CRM for IFD by using one of the following methods:
· During Microsoft Dynamics CRM Server installation or upgrade.
o Install a new deployment of Microsoft Dynamics CRM (On-Premise Edition) using command-line options and an XML configuration file that contains IFD configuration information (specified in the following topic).
o Upgrade from Microsoft Dynamics CRM 3.0 to Microsoft Dynamics CRM (On-Premise Edition) using command-line options and an XML configuration file that contains IFD configuration information (described in the following topic).
· Configure an existing deployment using the Microsoft Dynamics CRM Internet Facing Deployment Configuration tool. Configure an existing deployment of Microsoft Dynamics CRM that did not use an XML configuration file that contained IFD configuration information (described in the following topic). To configure the existing deployment, download and run the Microsoft Dynamics CRM Internet Facing Deployment Configuration Tool (described in the topic below).
Configure during Microsoft Dynamics CRM Server installation or upgrade
When using the command-line option to deploy a new installation of Microsoft Dynamics CRM or upgrade from Microsoft Dynamics CRM 3.0, you can enable IFD by adding the
For more information about the IFD deployment properties in the
The Microsoft Dynamics CRM Internet Facing Deployment Configuration tool adds a node to the web.config file for IFD settings, creates deployment properties in the MSCRM_config database, and adds a registry key to Microsoft Dynamics CRM Server enabling Internet-facing access. You can use the Internet Facing Deployment Configuration tool after installing or upgrading to Microsoft Dynamics CRM. You can also use this tool any time you want to change the IFD configuration properties.
Read the Microsoft Dynamics CRM 4.0 Internet Facing Deployment Scenarios document for specific configuration scenarios and instructions to help you successfully implement Microsoft Dynamics CRM IFD.
You can also get detailed instructions for using the Microsoft Dynamics CRM Internet Facing Deployment Configuration tool in How to use the Microsoft Dynamics CRM Internet Facing Deployment Configuration tool.
Note
To update other configuration fields, download and run the Microsoft Dynamics CRM Internet Facing Deployment Configuration tool from Microsoft Dynamics CRM 4.0: Planning and Deployment Guidance for Service Providers.
IFD configuration properties details
Internal Network Address
When you configure Microsoft Dynamics CRM for IFD using the Internet Facing Deployment Configuration tool or using an XML configuration file, on initial Microsoft Dynamics CRM installations only, you are adding a new Windows registry key. The IfdInternalNetworkAddress registry key contains the IP addresses and subnet masks for internal computers using Microsoft Dynamics CRM. The registry key location is
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM
When a user submits a page request, the Microsoft Dynamics CRM Server compares the user's IP address and subnet mask with the values in the registry key to determine which authentication type to use, anonymous access authentication for Internet access or Integrated Windows authentication for internal users. For example, the IP addresses and subnet masks of your Microsoft Dynamics CRM users are as follows:
10.10.1.1-255.255.255.0,157.55.164.93-255.255.255.0
When the subnet is 255.255.255.0 and the IP address are 10.10.1.1 or 157.55.164.93 then any IP address that starts with 10.10.1 or 157.55.164 is considered internal.
When a user requests a Microsoft Dynamics CRM page and the user's IP address and subnet masks is 157.55.165.22-255.255.254.0 and the IP address and subnet mask is not found, Microsoft Dynamics CRM uses forms authentication to display a sign on page. Any IP addresses and subnet masks not in the Internal Network Address registry key cause the Microsoft Dynamics CRM Server to respond with the IFD sign on page to request the user's credentials.
If users are accessing Microsoft Dynamics CRM from multiple subnets, you must update the IfdInternalNetworkAddress registry value to reflect the different subnets. When you have more than 1 subnet, you can add multiple values to the IfdInternalNetworkAddress registry key. Separate the values using a comma but do not add a space after the comma.
To configure Microsoft Dynamics CRM for IFD only access, enter the IP address to the Microsoft Dynamics CRM Server and a subnet mask of 255.255.255.255. Then only those page requests from the Microsoft Dynamics CRM Server are considered internal, and all other page requests prompt the sign on page.
IFD Root Domain Scheme
In the Root Domain Scheme or IFD Root Domain when using the Internet Facing Deployment Configuration tool, enter https as the value of this MSCRM_config database property when you have SSL set for the Web site.
Important
SSL is strongly recommended fo Internet-facing deployment of Microsoft Dynamics CRM.
SDK Root Domain
In the SDK Root Domain or the IFD SDK Domain when using the Internet Facing Deployment Configuration tool , enter the domain name where the SDK Server role is installed. This is used for applications that use the methods from the Microsoft Dynamics CRM Software Development Kit(SDK) as the value for this MSCRM_config database property. Add the domain name and the root domain (.com), for example mycompany.com rather than mycompany. If using a port that is not the default, then you need to include the port number in the SDK Root Domain, for example, domain.com:5555.
Web Application Root Domain
In the Web Application Root Domain or the IfdWebApplicationRootDomain when using the Internet Facing Deployment Configuration tool , enter the domain name only for the Microsoft Dynamics CRM Web application as the value for this MSCRM_config database property. Add the domain name and the root domain (.com), for example mycompany.com rather than mycompany. If using a port that is not the default, then you need to include the port number in the Web Application Root Domain, for example, domain.com:5555.
Important
When using server roles divided out to different computers, you must use different domain name values for IfdWebApplicationRootDomain and IfdSdkRootDomain. For more information, see the topic below Using Server Roles.
Service Provide License Agreement
ServiceProviderLicenseAgreement replaces OnPremise as the authentication strategy in the
IFD URL
You must define a URL for the Microsoft Dynamics CRM IFD deployment using the following format:
https://
For information about changing Microsoft Dynamics CRM port assignment, see
Common Issues
Use DNS host or alias record with IFD
Create a host or alias record for each organization that plans to access Microsoft Dynamics CRM externally from the Internet. If you use host headers to uniquely identify the Microsoft Dynamics CRM Web site, you should remove the host headers and set up a Domain Name Service (DNS) alias record. This is particularly important because SSL does not work with host headers. The DNS alias record ensures that the URL address for the external and internal organization resolves correctly. The alias record is a name for your Web application that is composed of a subdomain name to identify the organization, second-level domain name to identify your company, and root domain name such as .gov, .tv. or .com. For Microsoft Dynamics CRM IFD, your DNS alias record should resemble the following:
crm_organization_name.domain.com
The Internet Facing Deployment Configuration tool includes a Check DNS option on the Tools menu to test DNS resolution. If you have not defined domain names in DNS, the Internet Facing Deployment Configuration tool displays a message indicating that the domain name cannot be resolved. For specific instructions, see Setup test DNS record in How to configure an Internet-Facing Deployment for Microsoft Dynamics CRM 4.0.
Firewall exceptions
If one or more firewalls are running between the clients and the Microsoft Dynamics CRM Server, an exception for the port used by the Microsoft Dynamics CRM Web site must be established to allow clients to connect.
Running reports
To enable complete reporting functionality for a Microsoft Dynamics CRM deployment configured for IFD, the deployment must be running the Microsoft Dynamics CRM Connector for SQL Server Reporting Services.
When a Microsoft Dynamics CRM user runs a report from Microsoft Dynamics CRM, Microsoft SQL Server Reporting Services Viewer requests the report and data from the remote Microsoft SQL Server Reporting Services computer. To access the report, the Microsoft Dynamics CRM user enters the Microsoft Dynamics CRM server URL. Microsoft Dynamics CRM Connector for SQL Server Reporting Services runs as a Microsoft SQL Server Reporting Services data processing extension and handles the authentication in the delegated mode used for reports.
However, the Microsoft Dynamics CRM Connector for SQL Server Reporting Services does not work with the Microsoft SQL Server 2005 Workgroup Edition because it does not support custom data extensions used in the Microsoft Dynamics CRM Connector for SQL Server Reporting Services. To resolve this issue, upgrade Microsoft SQL Server 2005 Workgroup Edition to one of the following editions:
· SQL Server 2005 Standard Edition
· SQL Server 2005 Enterprise Edition
· SQL Server 2008 Enterprise Edition
· SQL Server 2008 Standard Edition
For specific SQL Server 2008 upgrade version information, see SQL Server 2008 Books Online Version and Edition Upgrades.
Using Dynamic worksheets or Dynamic PivotTables
To export data to Dynamic worksheets or Dynamic PivotTables for Microsoft Dynamics CRM users connecting to a Microsoft Dynamics CRM IFD deployment, install and configure the Microsoft Dynamics CRM for Microsoft Office Outlook client on the computer of the Microsoft Dynamics CRM user trying to open the Dynamic worksheet. When Microsoft Dynamics CRM is not in the same domain as the client computer, Microsoft Dynamics CRM for Microsoft Office Outlook client handles the Microsoft Dynamics CRM user login credentials for the Microsoft Dynamics CRM database used in the worksheet.
For information about securing data exported to Microsoft Office Excel, see Microsoft Dynamics CRM Team blog article Dynamic Export to Excel feature – How to protect data over the wire.
Using server roles
In a Microsoft Dynamics CRM deployment you can split the configuration into two separate server role groups or separate each individual server role across multiple computers. If you configure IFD for a Microsoft Dynamics CRM deployment using server role groups or separate server roles, you must obtain different SSL certificates if the Application server role and the SDK server role are on different computers. You cannot use the same certificate for both server roles. If you did not obtain different SSL certificates defined with root domain names specific to the Application server role and SDK server role, then the DNS server detects duplicate mappings and cannot resolve the domain names. To resolve this duplicate mapping issue, assign different values in the deployment properties for the IFD App Root Domain and IFD SDK Root Domain. The value that you enter in the Internet Facing Deployment Configuration tool for the App Root Domain is the domain associated with the Application server role. The value that you enter in the Internet Facing Deployment Configuration tool for the SDK Root Domain is the domain associated with the SDK server role.
For more information about server roles, see Making Sense of Server Roles.
Configure IFD with an ISA server
After you configure Microsoft Dynamics CRM for IFD and you are using an Internet Security and Acceleration (ISA) server, any user attempts to login from the Internet are challenged for a Windows login instead of the Microsoft Dynamics CRM sign on page. This causes the user authentication to fail. You can resolve this issue by changing the configuration setting on the ISA server to Request Appear to come from Original Client. This setting causes the ISA server to interpret the request as coming from the original client IP. For this configuration setting to work, the web server must point to ISA Server's internal IP address as the Default Gateway.
Configure IFD for a multi-forest with a perimeter network model
When you use a perimeter network to isolate Internet-facing resources from your internal corporate network, you have to open the ports to the local area network to successfully deploy Internet-facing Microsoft Dynamics CRM. You can see an example of a perimeter network model in the Planning Guide in the Microsoft Dynamics CRM 4.0 Implementation Guide under the heading, "Multi-forest with client Internet access."
The following information on how to configure Microsoft Dynamics CRM for IFD with a perimeter network model is from Joel Lindstrom's CustomerEffective blog. You need to do the following when using a perimeter network model:
1. Install and configure Microsoft Dynamics CRM.
On an initial installation, you can install and configure Microsoft Dynamics CRM for Internet-facing access using the command-line installation options or you can wait until after you have Microsoft Dynamics CRM running and tested before configuring it for IFD.
2. Enable the perimeter network solution.
3. Open the required ports to the local area network:
o Microsoft SQL Server
o Microsoft SQL Server Reporting Services
o Microsoft Exchange Server 2003 or Microsoft Exchange Server 2007
o Domain Controllers
For more information about Microsoft Dynamics CRM ports, see "Network ports used for Microsoft Dynamics CRM 4.0" in the Planning Guide in the Microsoft Dynamics CRM 4.0 Implementation Guide.
4. Test the Microsoft Dynamics CRM server to ensure that it is working as expected.
5. Obtain and install a wildcard SSL certificate for your Microsoft Dynamics CRM deployment.
6. Use the Internet Facing Deployment Configuration tool to set up the IFD deployment. While using the IFD tool, verify that the DNS values resolve.
Hiding Button's on related views in CRM
HideAssociatedViewButtons = function(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);
}
}
}
/* Used internally by the 'HideAssociatedViewButtons' method */
HideViewButtons = function(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++)
{
buttonTitleParts = buttonTitles[j].split('::');
if (buttonTitleParts.length > 0)
{
buttonTitle = buttonTitleParts[0];
for (var i = 0; i < liElements.length; i++)
{
liElement = liElements[i];
if (liElement.getAttribute('title') == buttonTitle)
{
if (buttonTitleParts.length == 1)
{
liElement.style.display = 'none';
break;
}
else
{
/* We want to hide a menu item in a drop-down menu.
Find the descendant text element with the specified text.
Then find its parent list item and hide it:
*/
menuText = buttonTitleParts[1];
var spanElements = liElement.getElementsByTagName('span');
for (var k = 0; k < spanElements.length; k++)
{
spanElement = spanElements[k];
if (spanElement.className == 'ms-crm-MenuItem-Text' )
{
textElement = spanElement.firstChild;
if (textElement != null && textElement.nodeType == 3) /* 3 = Node.TEXT_NODE */
{
if (textElement.data == menuText)
{
liMenuItemElement
= spanElement.parentNode.parentNode.parentNode;
liMenuItemElement.style.display = 'none';
break;
}
}
}
}
}
}
}
}
}
}
}
}
}
HideAssociatedViewButtons("CRMRELATIONSHIP", ["Add existing XXXXto this record", "Add a new XXXX to this record"]);