How to change the DashboardSettings of maximum controls limit in Dynamics CRM2011/2013

The maximum number of controls allowed on CRM2011 or CRM 2013 dashboards is 6. You cannot put the more than 6 graphs/charts/iframes/web resources etc. on the dashboard.

We can extend the number of controls as per the user needs. This setting is applied to the server not a organization setting. So you cannot change this setting for CRM Online but you can change this for an on-premise installation.

Option 1: Using Window Power Shell we can achieve it.

  1. Open the Windows Power Shell command window
  2. Add the Microsoft Dynamics CRM PowerShell snap-in using

Add-PSSnapin Microsoft.Crm.PowerShell
Sometimes You may get the message saying something like “Add-PSSnapin : Cannot add Windows PowerShell snap-in Microsoft.Crm.PowerShell because it is already added.” It is fine no problem.

3.  Run the following 3 commands

$setting = Get-CrmSetting -SettingType DashboardSettings

$setting.MaximumControlsLimit = 10

Set-CrmSetting -Setting $setting

After that open CRM, still you will be see only 6 components on the dashboard design, however you can add extra components based on how much you have set the limit.

Once you crossed the limit you will get following error message.

DashboardSettings

Option 2: If Powershell does not work, use following C# code to do the same

  public static void UpdateDashboardSettings()
        {
            //Create Instance of Deployment Service
            DeploymentServiceClient service = Microsoft.Xrm.Sdk.Deployment.Proxy.ProxyClientHelper.CreateClient(new Uri("http://CRMServer/Organization/XRMDeployment/2011/Deployment.svc"));
            //Use Default network Credentials(User should de Deployment Admin in Deployment Manager and System Admin in CRM)
            service.ClientCredentials.Windows.ClientCredential = (NetworkCredential)CredentialCache.DefaultCredentials;

            //Retrieve Current Dashboard Settings MaximumControlsLimit
            Microsoft.Xrm.Sdk.Deployment.RetrieveRequest retrieveReq = new Microsoft.Xrm.Sdk.Deployment.RetrieveRequest();
            retrieveReq.EntityType = DeploymentEntityType.DashboardSettings;

            Microsoft.Xrm.Sdk.Deployment.RetrieveResponse retrieveRes = (Microsoft.Xrm.Sdk.Deployment.RetrieveResponse)service.Execute(retrieveReq);
            if (retrieveRes != null && retrieveRes.Entity != null)
            {
                DashboardSettings dsCurrentResult = (DashboardSettings)retrieveRes.Entity;
                if (dsCurrentResult != null)
                    Console.WriteLine("Current DashboardSettings MaximumControlsLimit is " + dsCurrentResult.MaximumControlsLimit);
            }
            //Update Current Dashboard Settings MaximumControlsLimit = 10
            Microsoft.Xrm.Sdk.Deployment.UpdateRequest updateReq = new Microsoft.Xrm.Sdk.Deployment.UpdateRequest();
            DashboardSettings ds = new DashboardSettings();
            ds.MaximumControlsLimit = 10;
            updateReq.Entity = ds;
            Microsoft.Xrm.Sdk.Deployment.UpdateResponse updateRes = (Microsoft.Xrm.Sdk.Deployment.UpdateResponse)service.Execute(updateReq);

            //Retrieve again after updating Current Dashboard Settings MaximumControlsLimit
            Microsoft.Xrm.Sdk.Deployment.RetrieveRequest retrieveReq1 = new Microsoft.Xrm.Sdk.Deployment.RetrieveRequest();
            retrieveReq1.EntityType = DeploymentEntityType.DashboardSettings;
            Microsoft.Xrm.Sdk.Deployment.RetrieveResponse retrieveRes1 = (Microsoft.Xrm.Sdk.Deployment.RetrieveResponse)service.Execute(retrieveReq1);

            if (retrieveRes1 != null && retrieveRes1.Entity != null)
            {
                DashboardSettings dsUpdatedResult = (DashboardSettings)retrieveRes1.Entity;
                if (dsUpdatedResult != null)
                    Console.WriteLine("After Updating DashboardSettings MaximumControlsLimit is " + dsUpdatedResult.MaximumControlsLimit);

            }
        }

NOTE: You need add microsoft.xrm.sdk.deployment DLL from SDK to access those Deployment classes and methods. User who is running this should be Deployment Admin in Deployment Manager and Sys Admin in CRM

Incase if you are getting 404 error while accessing Deployment service, you need to check your CRM web server IIS settings and make sure XRMDeployment is not configured in Hidden Segments in IIS, Follow below steps to remove/add XRMDeployment setting in IIS

  1. Open Internet Information Services(IIS) Manager
  2. Expand Server on left navigation
  3. Expand Sites on the Left Navigation
  4. Click on Microsoft Dynamics CRM
  5. Click on “Request Filtering” icon in IIS on right side window
  6. Click on “Hidden Segments” tab on Request Filtering window on right side
  7. If “XRMDeployment” exists then select “XRMDeployment” and right click on “Remove” and say “Yes” to remove “XRMDeployment” from Hidden Segments
  8. Once you are done executing PowerShell, SDK Code you can add using “Add Hidden Segment” option, enter “XRMDeployment” in Hidden Segment window and click on “OK” to close the window.
Advertisements

Re-assign Account/User territory in Dynamics CRM 2011

Unfortunately Dynamics CRM 2011 does not support deactivating Territory, If you get a situation where you want to delete the existing territory, you need to first check if it is associated to any accounts or users, if the territory has salespeople(users) or accounts associated with it, the deletion will not succeed, Territory entity have 1:N relationships with “Referential, Restrict Delete” behavior on Account and User, Users cannot directly delete a territory, If the Territory has Users or Accounts associated with it, In order to delete the Territory, need to reassign associated Users and Accounts to different Territory.

Following code helps to re-assign accounts and users territory from one territory to another one.

 private void ReAssignAccountTerritories(IOrganizationService service, string oldTerritoryName, string newTerritoryName)
        {
            try
            {
                string accountsFetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                            <entity name='account'>
                                                                <attribute name='accountid' />
                                                                <attribute name='name' />
                                                                <link-entity name='territory' from='territoryid' to='territoryid' alias='aa'>
                                                                    <filter type='and'>
                                                                        <condition attribute='name' operator='eq' value='{0}' />
                                                                    </filter>
                                                                </link-entity>
                                                            </entity>
                                                        </fetch>", oldTerritoryName);

                var accountsFetchExp = new FetchExpression(accountsFetchXML);

                //Get Accounts with Old Territory
                EntityCollection accountsResults = service.RetrieveMultiple(accountsFetchExp);

                string territoryFetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                            <entity name='territory'>
                                                                <attribute name='territoryid' />
                                                                <filter type='and'>
                                                                    <condition attribute='name' operator='eq' value='{0}' />
                                                                </filter>
                                                            </entity>
                                                        </fetch>", newTerritoryName);

                var territoryFetchExp = new FetchExpression(territoryFetchXML);
                //Get TerritoryId based on TerritoryName
                EntityCollection territoryResults = service.RetrieveMultiple(territoryFetchExp);

                EntityReference territoryReference = null;

                if (territoryResults.Entities != null && territoryResults.Entities.Count > 0)
                    territoryReference = new EntityReference("territory", territoryResults.Entities[0].Id);

                foreach (Entity account in accountsResults.Entities)
                {
                    if (territoryReference != null)
                    {
                        //Update Account Territory with new Territory
                        account.Attributes.Add("territoryid", territoryReference);
                        service.Update(account);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void ReAssignUserTerritories(IOrganizationService service, string oldTerritoryName, string newTerritoryName)
        {
            try
            {
                string usersFetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                        <entity name='systemuser'>
                                                            <attribute name='systemuserid' />
                                                            <attribute name='fullname' />
                                                            <link-entity name='territory' from='territoryid' to='territoryid' alias='aa'>
                                                                <filter type='and'>
                                                                    <condition attribute='name' operator='eq' value='{0}' />
                                                                </filter>
                                                            </link-entity>
                                                        </entity>
                                                    </fetch>", oldTerritoryName);

                var usersFetchExp = new FetchExpression(usersFetchXML);

                EntityCollection usersResults;

                //Get Users with Old Territory
                usersResults = service.RetrieveMultiple(usersFetchExp);

                string territoryFetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                            <entity name='territory'>
                                                                <attribute name='territoryid' />
                                                                <filter type='and'>
                                                                    <condition attribute='name' operator='eq' value='{0}' />
                                                                </filter>
                                                            </entity>
                                                        </fetch>", newTerritoryName);

                var territoryFetchExp = new FetchExpression(territoryFetchXML);
                //Get TerritoryId based on TerritoryName
                EntityCollection territoryResults = service.RetrieveMultiple(territoryFetchExp);

                EntityReference territoryReference = null;

                if (territoryResults.Entities != null && territoryResults.Entities.Count > 0)
                    territoryReference = new EntityReference("territory", territoryResults.Entities[0].Id);

                foreach (Entity user in usersResults.Entities)
                {
                    if (territoryReference != null)
                    {
                        //Update User Territory with new Territory
                        user.Attributes.Add("territoryid", territoryReference);
                        service.Update(user);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

There are still open activities associated with this case, when resolving/cancelling a Case in Dynamics CRM 2011

Problem:
When you try to resolve a case in Dynamics CRM 2011, which has open activities of Task, E-mail, Phone Call, Letter, Fax, Appointment and Service Activity you will get following error message “There are still open activities associated with this case, these must be closed before the case can be closed.”

Case_Open_Activities_Message

If you are trying to cancel a case which has open activities, you will get following error message.

Cancel_Case

If you are trying to resolve a case thru CRM SDK code, you will get following error message “The incident can not be cancelled because there are open activities for this incident.”

Case_Open_Activities_ErrorMessage

Solution 1:
If you are resolving a Case from CRM UI, you need to manually open each associated activity of the case and do ‘Mark Complete’ or ‘Cancel’
Solution 2:
If you are resolving a case from CRM SDK, you need to use following code to cancel all associated activities of the case.


  // Cancel all associated Case activities which are Open and Scheduled
        public static void CancelCaseActivities(IOrganizationService orgService, Guid caseId)
        {
            string fetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                    <entity name='activitypointer'>
                                                        <attribute name='activityid' />
                                                        <attribute name='activitytypecode' />
                                                        <filter type='and'>
                                                            <condition attribute='regardingobjectid' operator='eq' value='{0}' />
                                                            <condition attribute='statecode' operator='in'>
                                                                <value>0</value>
                                                                <value>3</value>
                                                            </condition>
                                                        </filter>
                                                    </entity>
                                              </fetch>", caseId.ToString());

            var fetchExp = new FetchExpression(fetchXML);

            var activities = orgService.RetrieveMultiple(fetchExp);

            foreach (Entity activity in activities.Entities)
            {
                CancelActivity(activity, orgService);
            }
        }

        // Cancel an Activity
        private static void CancelActivity(Entity entity, IOrganizationService service)
        {
            EntityReference moniker = new EntityReference();
            if (entity.LogicalName == "activitypointer")
            {
                if (entity.Attributes.Contains("activityid") & entity.Attributes.Contains("activitytypecode"))
                {
                    moniker.LogicalName = entity.Attributes["activitytypecode"].ToString();
                    moniker.Id = (Guid)entity.Attributes["activityid"];
                    SetStateRequest request = new SetStateRequest();
                    request.EntityMoniker = moniker;
                    request.State = new OptionSetValue(2);
                    request.Status = new OptionSetValue(-1);
                    SetStateResponse response = (SetStateResponse)service.Execute(request);
                }
            }
        }

Merge warning: sub-entity might lose parenting in Dynamics CRM 2011

Problem:
If you are trying to merge two accounts, If master account record does not have a parent account, but the subordinate account record does, then you will get following warning message if you do Merge from CRM UI otherwise if you do Merge from SDK code using MergeRequest class you will get an exception saying that “Exception Message: Merge warning: sub-entity might lose parenting”

Merge Warning

Solution:

If you are doing Merge from CRM UI, after you get above warning message, click on “OK” button to continue the merge.
If you are doing Merge from SDK code using MergeRequest class, you should specify PerformParentingChecks property to false. This property used to check if the parent information is different for the two entity records. If it is true it will check the parent information is different for the two entity records.

Sample code is here:

 // Merge Accounts
        public void MergeAccounts(Guid masterAccountId, Guid subOrdinateAccountId)
        {
            try
            {
                //Create CRM Connection        
                IOrganizationService crmConnection = GetCRMConnection();

                //Create the target for the request.        
                EntityReference target = new EntityReference();

                //Id is the GUID of the account that is being merged into.        
                //LogicalName is the type of the entity being merged to, as a string        
                target.Id = masterAccountId;
                target.LogicalName = "account";

                //Create the request.        
                MergeRequest merge = new MergeRequest();

                // SubordinateId is the GUID of the account merging.    
                merge.SubordinateId = subOrdinateAccountId;
                merge.Target = target;
                merge.PerformParentingChecks = false;
                Entity updateContent = new Entity("account");
                var cols = new ColumnSet(new[] { "primarycontactid", "websiteurl", "telephone1", "fax", "emailaddress1" });

                //Get Master Account Primary Contact,Website,Phone,Fax,Email
                var masterAccount = crmConnection.Retrieve("account", masterAccountId, cols);

                //Get Subordinate Account Primary Contact,Website,Phone,Fax,Email
                var subOrdinateAccount = crmConnection.Retrieve("account", subOrdinateAccountId, cols);

                //If PrimaryContact,Website,Phone,Fax,Email fields data are populated on the Subordinate Account and NOT populated on the Master Account. updated these Subordinate account values to the Master record.                  
                if (!masterAccount.Contains("primarycontactid") && subOrdinateAccount.Contains("primarycontactid"))
                    updateContent.Attributes.Add("primarycontactid", new EntityReference("contact", subOrdinateAccount.GetAttributeValue<EntityReference>("primarycontactid").Id));

                if (!masterAccount.Contains("websiteurl") && subOrdinateAccount.Contains("websiteurl"))
                    updateContent.Attributes.Add("websiteurl", subOrdinateAccount.Attributes["websiteurl"]);

                if (!masterAccount.Contains("telephone1") && subOrdinateAccount.Contains("telephone1"))
                    updateContent.Attributes.Add("telephone1", subOrdinateAccount.Attributes["telephone1"]);

                if (!masterAccount.Contains("fax") && subOrdinateAccount.Contains("fax"))
                    updateContent.Attributes.Add("fax", subOrdinateAccount.Attributes["fax"]);

                if (!masterAccount.Contains("emailaddress1") && subOrdinateAccount.Contains("emailaddress1"))
                    updateContent.Attributes.Add("emailaddress1", subOrdinateAccount.Attributes["emailaddress1"]);

                merge.UpdateContent = updateContent;

                // Execute the request.   
                MergeResponse mergeRes = (MergeResponse)crmConnection.Execute(merge);
            }
            catch (Exception ex)
            {
                //Throw the exception        
                throw ex;
            }
        }

Use ExecuteMultipleRequest for bulk Create/Update/Delete using C# in Dynamics CRM 2011

Using this we can create/update/delete bunch of records at a time. It avoids calling OrgService.Create or Update or Delete every time.

This has been added to the Microsoft Dynamics CRM 2011 Update Rollup 12, it is available from SDK 5.0.13. Here is reference MSDN URL http://msdn.microsoft.com/en-us/library/jj863631.aspx

Default max batch size is 1000, that means Using this you can create/update/delete up to 1000 records only at a time.

Here are sample code blocks for bulk Create, Update and Delete

 


     /// <summary>
        /// Call this method for bulk Create
        /// </summary>
        /// <param name="service">Org Service</param>
        /// <param name="entities">Collection of entities to Create</param>
        public static void BulkCreate(IOrganizationService service, DataCollection<Entity> entities)
        {
            // Create an ExecuteMultipleRequest object.
            var multipleRequest = new ExecuteMultipleRequest()
            {
                // Assign settings that define execution behavior: continue on error, return responses. 
                Settings = new ExecuteMultipleSettings()
                {
                    ContinueOnError = false,
                    ReturnResponses = true
                },
                // Create an empty organization request collection.
                Requests = new OrganizationRequestCollection()
            };

            // Add a CreateRequest for each entity to the request collection.
            foreach (var entity in entities)
            {
                CreateRequest createRequest = new CreateRequest { Target = entity };
                multipleRequest.Requests.Add(createRequest);
            }

            // Execute all the requests in the request collection using a single web method call.
            ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);

        }

        /// <summary>
        /// Call this method for bulk update
        /// </summary>
        /// <param name="service">Org Service</param>
        /// <param name="entities">Collection of entities to Update</param>
        public static void BulkUpdate(IOrganizationService service, DataCollection<Entity> entities)
        {
            // Create an ExecuteMultipleRequest object.
            var multipleRequest = new ExecuteMultipleRequest()
            {
                // Assign settings that define execution behavior: continue on error, return responses. 
                Settings = new ExecuteMultipleSettings()
                {
                    ContinueOnError = false,
                    ReturnResponses = true
                },
                // Create an empty organization request collection.
                Requests = new OrganizationRequestCollection()
            };

            // Add a UpdateRequest for each entity to the request collection.
            foreach (var entity in entities)
            {
                UpdateRequest updateRequest = new UpdateRequest { Target = entity };
                multipleRequest.Requests.Add(updateRequest);
            }

            // Execute all the requests in the request collection using a single web method call.
            ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);

        }

        /// <summary>
        /// Call this method for bulk delete
        /// </summary>
        /// <param name="service">Org Service</param>
        /// <param name="entityReferences">Collection of EntityReferences to Delete</param>
        public static void BulkDelete(IOrganizationService service, DataCollection<EntityReference> entityReferences)
        {
            // Create an ExecuteMultipleRequest object.
            var multipleRequest = new ExecuteMultipleRequest()
            {
                // Assign settings that define execution behavior: continue on error, return responses. 
                Settings = new ExecuteMultipleSettings()
                {
                    ContinueOnError = false,
                    ReturnResponses = true
                },
                // Create an empty organization request collection.
                Requests = new OrganizationRequestCollection()
            };

            // Add a DeleteRequest for each entity to the request collection.
            foreach (var entityRef in entityReferences)
            {
                DeleteRequest deleteRequest = new DeleteRequest { Target = entityRef };
                multipleRequest.Requests.Add(deleteRequest);
            }

            // Execute all the requests in the request collection using a single web method call.
            ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
        }

Fetch XML and ConditionExpression operators using C# in Dynamics CRM 2011

Following table describes different types of operators we can use in a ConditionExpression and Fetch XML in Dynamics CRM 2011

ConditionOperator FetchXML Operator Description
BeginsWith like The string occurs at the beginning of another string.
Between between The value is between two values.
Contains like The string contains another string.
DoesNotBeginWith not-like The string does not begin with another string.
DoesNotContain not-like The string does not contain another string.
DoesNotEndWith not-like The string does not end with another string.
EndsWith like The string ends with another string.
Equal eq The values are compared for equality.
EqualBusinessId eq-businessid The value is equal to the specified business ID.
EqualUserId eq-userid The value is equal to the specified user ID.
EqualUserTeams eq-userteams The record is owned by teams that the user is a member of.
GreaterEqual ge The value is greater than or equal to the compared value.
GreaterThan gt The value is greater than the compared value.
In in TheThe value exists in a list of values.
InFiscalPeriod in-fiscal-period The value is within the specified fiscal period.
InFiscalPeriodAndYear in-fiscal-period-and-year The value is within the specified fiscal period and year.
InFiscalYear in-fiscal-year The value is within the specified year.
InOrAfterFiscalPeriodAndYear in-or-after-fiscal-period-and-year The value is within or after the specified fiscal period and year.
InOrBeforeFiscalPeriodAndYear in-or-before-fiscal-period-and-year The value is within or before the specified fiscal period and year.
Last7Days last-seven-days The value is within the last seven days including today.
LastFiscalPeriod last-fiscal-period The value is within the last fiscal period.
LastFiscalYear last-fiscal-year The value is within the last fiscal year.
LastMonth last-month The value is within the last month including first day of the last month and last
day of the last month.
LastWeek last-week The value is within the previous week including Sunday through Saturday.
LastXDays last-x-days The value is within last X days.
LastXFiscalPeriods last-x-fiscal-periods The value is within the last X (specified value) fiscal periods.
LastXFiscalYears last-x-fiscal-years The value is within the last X (specified value) fiscal periods.
LastXHours last-x-hours The value is within the last X hours.
LastXMonths last-x-months The value is within the last X (specified value) months.
LastXWeeks last-x-weeks The value is within the last X (specified value) weeks.
LastXYears last-x-years The value is within the last X years.
LastYear last-year The value is within the previous year.
LessEqual le The value is less than or equal to the compared value.
LessThan lt The value is less than the compared value.
Like like The character string is matched to the specified pattern.
Next7Days next-seven-days The value is within the next seven days.
NextFiscalPeriod next-fiscal-period The value is within the next fiscal period.
NextFiscalYear next-fiscal-year The value is within the next fiscal year.
NextMonth next-month The value is within the next month.
NextWeek next-week The value is within the next week.
NextXDays next-x-days The value is within the next X (specified value) days.
NextXFiscalPeriods next-x-fiscal-periods The value is within the next X (specified value) fiscal period.
NextXFiscalYears next-x-fiscal-years The value is within the next X (specified value) fiscal years.
NextXHours next-x-hours The value is within the next X (specified value) hours.
NextXMonths next-x-months The value is within the next X (specified value) months.
NextXWeeks next-x-weeks The value is within the next X weeks.
NextXYears next-x-years The value is within the next X years.
NextYear next-year The value is within the next year.
NotBetween not-between The value is not between two values.
NotEqual ne The two values are not equal.
NotEqualBusinessId ne-businessid The value is not equal to the specified business ID.
NotEqualUserId ne-userid The value is not equal to the specified user ID.
NotIn not-in The given value is not matched to a value in a subquery or a list.
NotLike not-like The character string does not match the specified pattern.
NotNull not-null The value is not null.
NotOn ne The value is not on the specified date.
Null null The value is null.
OlderThanXMonths olderthan-x-months The value is older than the specified number of months.
On on The value is on a specified date.
OnOrAfter on-or-after The value is on or after a specified date.
OnOrBefore on-or-before The value is on or before a specified date.
ThisFiscalPeriod this-fiscal-period The value is within the current fiscal period.
ThisFiscalYear this-fiscal-year The value is within the current fiscal year.
ThisMonth this-month The value is within the current month.
ThisWeek this-week The value is within the current week.
ThisYear this-year The value is within the current year.
Today today The value equals today’s date.
Tomorrow tomorrow The value equals tomorrow’s date.
Yesterday yesterday The value equals yesterday’s date.

Use NoLock and Distinct in Fetch XML and QueryExpression using C# in Dynamics CRM 2011

NoLock: It indicates that no database locks are issued against the data that would prohibit other transactions from modifying the data in the records returned from the query.

Distinct:  It indicates whether results of the query contains duplicate entity instances

Using these in FetchXML and QueryExpression improves performance for checking/fetching results

 


 public static EntityCollection GetAccounts(IOrganizationService service, string accountName)
        {
            QueryExpression queryExp = new QueryExpression();
            queryExp.EntityName = "account";
            var cols = new ColumnSet(new[] { "name", "accountid" });
            queryExp.ColumnSet = cols;

            ConditionExpression conExp = new ConditionExpression();
            conExp.AttributeName = "name";
            conExp.Operator = ConditionOperator.Like;
            conExp.Values.Add(accountName);

            FilterExpression filterExp = new FilterExpression();       
            filterExp.Conditions.Add(conExp);

            queryExp.Criteria = filterExp;
                        
            queryExp.Distinct = false;
            
            queryExp.NoLock = true;

            var accounts = service.RetrieveMultiple(queryExp);

            return accounts;
        }

        public static EntityCollection GetAccounts(IOrganizationService service, string accountName)
        {            
            string fetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' distinct='false'>
                                                        <entity name='account'>                                                                
                                                            <attribute name='accountid' />
                                                            <attribute name='name' />
                                                            <filter type='and'>
                                                                <condition attribute='name' operator='like' value='{0}' />                                                                                                    
                                                            </filter>
                                                        </entity>
                                                    </fetch>", accountName);

            var fetchExp = new FetchExpression(fetchXML);

            var accounts = service.RetrieveMultiple(fetchExp);

            return accounts;
        }