Sonoma Partners Microsoft CRM and Salesforce.com Blog

A Step by Step Guide to Create Your First Survey with Dynamics CRM 2016 Voice of the Customer

Dynamics CRM 2016 was recently released and with it a whole slew of new features and functionality.  A bunch of features were planned for the initial 2016 release, but for one reason or another were delayed.  This website is a very simple way of understanding what’s been released for primetime, versus what’s in preview, what’s in development, and what’s been indefinitely postponed.

One such feature that wasn’t immediately available at the release of 2016 was Voice of the Customer.  This is the ability to create, send, and monitor surveys from Dynamics CRM.  This feature is currently only available for CRM Online, and below I’ll go into more detail on how to get it enabled, and how to create your first survey.

Note that this feature is delivered through an integration with Azure Web Services. This means data will be flowing and queued through Azure in order to take any workload of delivering and capturing customer survey data off of your CRM system for the best possible performance.  This also means that there could be a delay between survey response from making it into CRM.

Below we’re going to go into an overview of enabling Voice of the Customer, and setting up and sending your first survey.  This post won’t go into everything that’s available with Voice of the Customer as there’s a lot to it, but will cover the basics. 

Enabling

To enable Voice of the Customer, simply log into the CRM Online Administration Center, and select the org you want to install VOTC to, and click on Solutions.  Then you’ll be taken to the page with the preferred solutions that you can install, and simply click on the “Install” icon to start the installation. 

image

image

Once the installation is complete in CRM navigate to Solutions and open up the Voice of the Customer solution.  Then check off “I agree to the terms and conditions” and click on “Enable Voice of the Customer”.  You’re now set to start configuring your first survey!

image

 

Survey Creation

The Voice of the Customer functionality allows you to add theming to your surveys.  To do so you just navigate to the Images and Themes area of the VOTC module. 

image

And from there you can go ahead and create an Image record and upload a logo that you want to use in your survey will be accomplished in later steps.  After you upload the logo and save the record you’ll be able to see a preview of the image.

image

You can also go to the Themes area and create a new Theme to use for your logo.  You have the ability to change the colors of most of the survey elements such as the header, navigation bar, and progress background.  I strongly recommend you make use of a UX engineer to help you pick your colors wisely so that they don’t clash too much.  If you wanted to get more advanced, you can even upload your own CSS to apply even more custom styles to your survey.

image

Now that you have your image and theme setup, you’re ready to create your survey.  Navigate to Voice of the Customer –> Surveys, and click New to create your new survey.  You’ll see on the survey form that there are a lot of options to configure your survey.  We’re not going to cover them all in this post but you’ll notice that the we’re able to apply the Image and Theme we created previously.

image

In order to actually start building out the survey questions, you need to change from the Survey to the Designer form.  You’ll notice that here there’s also the Dashboard form where you can see statistics about survey responses.  For now we’ll click on Designer and start creating some questions.

image

On the Designer form, you have the ability to add or delete pages in your survey via the buttons that appear underneath the vertical page layout on the left.  You can’t delete the Welcome or Complete page – those are required for all surveys.

image

When in the design mode, you’ll be able to drag question types from the right over onto the main pane in the middle.  When you hover over a question on the page, you’ll be able to delete the question, make quick edits inline on the page to the question label, or click the pencil icon to take you to a more advanced editor so you can change more settings for the question other than the label.

image

image

In the text box of the question (and of any label control on the survey), you can click on the (Pipe) dropdown to insert piped data into your survey.  We’ll see how this works with workflows later when we create a workflow to automatically send out the survey upon case resolution.  In this example, we’ll insert the case number into the survey question, and we’ll use the Other1 pipe to store this data (again, that’s setup when you create the workflow and we’ll discuss that in a later step).

image

image

Here’s what our welcome page looked like with all the pipes in it.  We want to make a very personalized experience for the customer as they take the survey.  I also threw the other pipes in there so you can see how we’re able to get as much data out of CRM as possible to personalize our survey for our customer.

image

Something else you can do to add logic to your survey is to create Response Routings.  An example of when you’d use a response routing is if you want a customer to fill out an additional question, if they answered a certain way on a previous question.  For example, you may ask the customer how they’d rate the experience with your company, and if they provide a low rating, you may want to display an additional question to gather more information on why they felt that way.  To get to response routings, click on the related records dropdown of your survey.

image

When you setup your response routing rules, you need to create Conditions and Actions for each Response Routing.  See below how we’re only showing the “Can you please provide us with additional information” question if the user responded 1 to the star rating question.  Otherwise we don’t show it.

image

After completing the above, your survey is ready to be published.  If you toggle back to the Survey form, you can click on the Preview button to see what the survey would look like to your end users.  When you’re all set, you can click on Publish so that the survey is now accessible externally.

Survey Automation and Results

Now that you have your survey setup, you can use it along with native CRM workflow to have surveys automatically sent out to your customers based on actions to CRM data.  For example, lets create a workflow that sends our survey automatically to the customer of a Case when the case is marked Resolved, asking them how their experience working with your support team was, so you can make improvements if needed, or provide recognition where deserved.

First off, create a new Workflow and make sure to have it run on update of the Case Status field.  Check to make sure the status has been updated to Resolved, and then add in a step to create a new email.  Your workflow should look similar to that below.

image

Now when editing the email step of the workflow, you’ll want to copy the value in the “Email Snippet” field of the Survey, and paste this into the body of the email step in your workflow.  Your email step may look something similar to the following.

image 

image

Notice in this email above that I’m making the use of the piped tokens (that I had placed in my survey earlier) with dynamic data from the Case record the workflow is running on.  It doesn’t matter what field from the record I’m on that I use within each pipe.  You’ll see that in the actual survey the user is taken to that the pipes are resolved to the actual data on the Case that was recently resolved. 

Make sure to Activate the workflow, and then you can go and test it out.  Once a Case is resolved in CRM, the email that’s send to the customer looks similar to the following.

image

And if the user clicks on the hyperlink to launch their survey, they’ll be taken to the actual survey.  As stated above, the pipes used in the survey are resolved to the actual data from the case.  You can also see that if I answer greater than 1 on the 5 star rating of my overall experience, that I won’t see the question asking me why I rated the overall experience a 1 based on the routing rules we setup earlier.

image

image

Also note that the survey has a responsive design so that if you’re accessing it from a mobile device such as a phone, the survey resizes to fit the screen appropriately.

image   image

Upon completion of the survey, and after the data from Azure syncs back to Dynamics CRM, you’ll be able to change to the Dashboard form on your survey record to see the results trickling back in from your survey. 

image

You can also navigate to Survey Responses off of the Survey to see the individual responses.  If you open up a response you’ll be able to see the individual questions and answers that were asked and part of that specific response.

Note:  The responses (including the question and answer) are stored in a first class Question Responses entity.  This means that if you wanted to take this one step further, you could create a workflow on the Question Responses entity, and if a Question Response record is created where a response is poor (e.g., where the customer rated the overall experience a 1 star), an email can be sent to the appropriate team to follow up on why that customer answered that question the way they did.

image

image

 

Gotchas

As I was working through and testing out my first survey, I ran into a few gotchas that I figured would be great to note down as I suspect others may run into these similar issues.

First off, when using Response Routings, if you want to only show a question when another question has a certain value (for example in my case where I wanted to show a text box if someone rated the service a 1), you probably don’t want the text box to appear when the customer hasn’t answered the rating question.  In other words, you don’t want the text box to appear when they initially load the page of questions.  You ONLY want it to appear when they rate your service a 1.  In order for this to happen, you have to make sure that on that specific question that you set the Visibility field to “Do not display” which is the default visibility of the question.

Next, I ran into an issue with the pipes in my survey not actually being populated with dynamic data from CRM.  It had turned out that when I was testing this out with my workflow, I had copied the Email Snippet of the survey to my workflow email body more than once.  This causes the Email Snippet and Piped data to break and after I removed the duplicate Email Snippet from my workflow email, the pipes began to work as expected.

Also note that if you want the updates you made to your survey to be live, you’ll need to publish your survey after making changes.  Simply saving it using the native CRM buttons will not publish it to Azure, but instead just save the updates in CRM.

Finally, if your survey responses aren’t being returned to CRM, navigate to the Voice of the Customer solution and make sure to click on the link to Trigger Response Processing.  Note that this could take up to 15 minutes to complete and for responses to appear in CRM.

image

For more information on Voice of the Customer, head over to Microsoft’s website.

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

Project Service - The more you know

Today's post is written by Jeff Meister, Principal Consultant at Sonoma Partners.

The release of Microsoft CRM Online Spring Wave brings some great news for those of us focused on delivering quality customer service to our clients. 

In addition to the integration with two recent Microsoft acquisitions, ADX Studios (customer portal) and FieldOne (field service), Microsoft is also releasing  a new Project Service solution. Project Service is a PSA (Project Service Automation) solution that provides an end to end solution for delivering professional engagements and will be ideal for service-based firms.

Picture141-1024x605

Today, I wanted to walk you through a high-level overview of the functionality based on what we've learned to date about the solution.

Opportunity Management

CRM has traditionally handled opportunities with product line items. Project Service updates this functionality to handle what sales of service projects would need. Some key highlights would be contracts and labor rates, collaboration, practice lines, price lists and quotes; all while following your pre-defined sales methodology and best practices.

Project Planning

This is where things start to get interesting. This aspect of the solution brings key components from MS Project, and embeds them directly into CRM. Users are able to store templated project plans which are then modified and used for estimating, definition and timeline/budget tracking throughout the project lifecycle. Having these tools accessible within CRM allows for more accurate quoting, ensuring profitability and resource estimates are aligned early in the sales process. It also provides enterprise visibility to project status.

2

Resource Management

The solution takes the pre-sales planning work and applies that to your staffing model for demand fulfillment. This can be done across various staffing models. Whether or not your project manager or team members access the demand pool directly, or if you have centralized resource managers, resource scheduling can be done via the new solution, taking into account availability, capacity and skill sets while maintaining competencies and proficiencies.

(On a side note, we are really excited to see where this part of the solution can go when paired with machine learning!)

Time and Expense

This one is easy…mobile and desktop support for time and expense entry, with routing and a built-in process for approval. Having these data points tied directly to the project in CRM also provides the ability for immediate impact to project financials. Plus, you can access these functions through mobile applications.

Billing

Having all the project related data (contract, time reporting, expenses, billing details) under one roof allows us to easily source our invoices directly from the solution. We don’t believe this will be a full blown replacement for an ERP backend, especially at the enterprise level. That being said, this is a great direction to see the product headed, and we expect integration with other ERP systems to be available.

Analytics

The Project Service solution will have built in BI capabilities around actual records for financial events, profitability, and utilization. It is also expected to have content packs available for PowerBI, allowing for rich dashboards and ad hoc analytics. 

1

Sonoma Partners was fortunate enough to be an early participant with this process. The solution uses native functionality in conjunction with custom screens to deliver an intuitive and very compelling application targeted for firms that manage projects, time, and resources. The solution is easy to install and configure on your base CRM Online deployment. 

As mentioned above, Project Service is available as part of the Spring Wave for CRM Online.  And, we have our fingers crossed that we will see solution available for the on premises version at some point as well. Pricing details are yet to be published, but check back for more details as those become available.

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM Online

Lookups - Null vs Empty Array

The other day I discovered an interesting ‘gotcha’ when working with a lookup in JavaScript.  A business requirement called for some JavaScript to be registered when a lookup value changed and then execute certain logic based on if the lookup had a value or not. 

This is pretty straightforward logic and could be handled easily with the following code:

var customerValue = Xrm.Page.getAttribute('parentcustomerid').getValue();
if (!customerValue) {
   // do some logic
}
else
{
   // do some other logic
}

Come to find out, this works for the most part but there is one scenario where it falls short which is where the ‘gotcha’ comes in. 

  1. Record form loads and the lookup doesn’t have a value
  2. The lookup has a value and the user selects the lookup and hits the “Delete” key
  3. The lookup has a value and the user clicks the magnifying glass, then “Look Up More Records” and then clicks “Remove Value” on the subsequent dialog
In the first two scenarios with the above JavaScript code, the customerValue variable will be null and will work as expected.  In the third scenario, the customerValue variable will be an empty array and not work as expected as it isn’t null.


Therefore we need to update the block of code with the following:

var customerValue = Xrm.Page.getAttribute('parentcustomerid').getValue();
if (!customerValue || customerValue.length == 0) {
   // do some logic
}
else
{
   // do some other logic
}

Now the code is flexible and will handle all 3 scenarios where the lookup value doesn’t exist.

Note:  This was tested in CRM 2015 Update 1 and CRM 2016

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2015 Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

Understanding Office 365 User Account Management for Dynamics CRM Online

Today's post is written by Aaron Robinson, an Engagement Manager at Sonoma Partners.

Microsoft Dynamics CRM has long offered customers the option of choice when it comes to deployment as a differentiation of their product relative to other customer relationship management solution offerings.

But there are some differences in administration and capabilities depending on the deployment option chosen.  Let’s take a look at user administrator as it relates specifically to Dynamics CRM 2016 in Office 365.

Account Types

One benefit of the online or “cloud” offering of Dynamics CRM is how users are created and managed.  But before we get into how administration works, we need to understand the ways user accounts are created for Office 365.

Cloud Accounts

If you created an Office 365 tenant and use the Administration portal to create users, you are more than likely creating “cloud accounts”.  What does this mean?  Office 365 authentication is supported by a version of Microsoft’s authentication engine Active Directory.  More specifically, it is Azure Active Directory, meaning it is also a cloud service, just hosted on the Azure platform.  So how do I know if they are cloud accounts?  Easy!

First login to portal.office.com (I’m going to assume that you are a global (tenant) admin and have permission to the admin tab, otherwise you will not be able to do this).  Once logged in, browse to Users>Active Users and look for the Status Column shown below:

1

The important piece to understand about this method is that the accounts are stored in an instance of Azure Active Directory. You can view this directory by navigating to Admin>Azure AD in the same Admin Portal as shown below.

2

If you do, it will redirect you to the Windows Azure management website, and ask for you to create an account to manage this Azure tenant. Note this is not a requirement.  You can continue to manage users in the Admin portal without ever visiting the Azure AD page. Since this azure portal is a whole other beast, its better left for another time.

Local Accounts

Another method is more common in enterprise scenarios, where Active Directory domains have already existed for years and single sign-on (SSO) is preferred for on premises and cloud services in an organization. These accounts must either be sync’d with a cloud Active Directory, or redirected to federation service for authentication. For users this means they will continue to use same email address and password they currently use, and password changes will sync automatically.

DirSync or Azure AD Connect

Directory Sync is one method for enabling single sign-on.  One aspect I like about this method is that it is a single page authentication, rather than redirection, meaning less clicks for a user. However, administration of this method can be more demanding, as you need to make sure the service is always running.  Microsoft does aide in this process as they will notify the tenant admin if the sync goes down for a predetermined period of time, letting you know that someone should look into it.

3

The requirement for directory sync is to set up a synchronization service on a server behind the corporate firewall which can connect to the local Active Directory.  This was previously done with a tool called DirSync, but has since been replaced by a newer version called Azure AD Connect.  There is plenty of information on the deployment of DirSync and Azure AD Connect, so we won’t cover that here.

Active Directory Federation Services

ADFS is another way to go for enabling SSO.  Many enterprises will already have this in place for other SSO applications they manage, and as such may be more desirable.  The downside of this method in my opinion is the user experience.  From the Office 365 sign-in page, a user will enter their email address, and Office 365 will redirect them to the ADFS sign-in page for the organization, where they will have to enter their credentials, possible for a second time (the experience can be a bit inconsistent here depending on the device, operating system and browser).

4

Once again, there is plenty of good information on the setup here.

User Management

Now that we have covered where the user accounts can exist, let’s examine how they become users of Dynamics CRM.  This is a two step process that is fairly straight forward. Let’s start with license assignment.  Back to our trusty Admin Portal for Office 365 where our users now exist, you will want to expand the Active Users.  Select a user, which will give you the user admin panel to the right side as pictured below.

5

Click Edit on the Assigned license section and add a Dynamics CRM license to this user (this assumes you have purchased the licenses in advance, otherwise you may not have them available). The nice part here is that Microsoft has automated the user creation in Dynamics for you.  Once you have assigned the license, an automated routine will run to create the user record in Dynamics.  Keep in mind that this automation is not instantaneous, and it may take a few minutes for the user to appear.  But in most cases I see it appear in under a minute.

The last step is to sign into Dynamics as a CRM Administrator, and add a security role to the new user account. Unsure how to do that?  Refer to this TechNet article.

And one more thing…

Would you like to see a list of all Dynamics CRM Licensed users in the Admin portal? On the Active Users page, there is a view filter dropdown for seeing users by different attributes, such as Active Users, SignIn Allowed or Blocked, Unlicensed Users, etc.  A really helpful view is Dynamics CRM Licensed Users, but it doesn’t exist by default.  Here’s how you would add one.  Click the dropdown for Select a View, and select New View.

1

Name your view (“Dynamics CRM Licensed Users” works for me), and then under the Assigned License dropdown, select Microsoft Dynamics CRM Online Professional, and then click save.

2

Now pop into the Active Users, select your new view, and there you go!

3

Looking for help with your Dynamics CRM deployment?  You came to the right place! We can help you better understand Office 365 user account management and so much more. 

 

 

Topics: Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

FetchXML: Left Outer Joins with Multiple On Clauses

Having worked on CRM for ten years, I thought I understood everything that was possible with FetchXML. After all it seems pretty straight forward and each clause has almost a one to one equivalent with SQL. However, while I was recently doing some work on a project that required me to find records missing certain child records, I was surprised to find my understanding of left outer joins was incomplete.

The Requirement

In the project I was working on, we were using the native Connection entity to track relationships between contacts and users. Some of the Connections were manually created, but others needed to be automatically created based on business logic. In some cases we needed to detect all contacts that a user did not have a connection of a specified role with.  This seemed like a good case for using a left outer join and I sat down and wrote the following FetchXML:

The Concern

As I reviewed the FetchXML, I became concerned that I wouldn’t get the proper results with this query. I was assuming that CRM only used the to and from attributes on the link-entity element to build the on clause for the left join in SQL.  I knew that if the additional conditions inside the link-entity were added to the SQL where clause, that I would get no rows back.  In short, I was worried the generated SQL would look something like this:

It was enough of a concern that I decided to fire up SQL Profiler on my local dev org and see what exactly CRM generates in this case.  Much to my surprise I found the following (slightly cleaned up to help legibility):

In Summary

So in the end, CRM came through and put the link-entity’s conditions in the on clause for the left join.  This subtle change makes a huge difference in the results returned and makes left joins much more useful in CRM than one might assume based on the FetchXML structure.  This left me with an efficient query to solve the business requirement and a new found respect for FetchXML.

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2013 Microsoft Dynamics CRM 2015 Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

CRM DevTools - Easily Update Hidden or Read-Only Fields for Testing

When testing functionality in CRM, most likely you will need to update some data in order to complete the test.  But what happens if the field doesn’t exist on the record form or is read-only?  One option would be to edit the form temporarily to display the field on the form, update the field value and then remove the field from the form after your test.  A better option, to save the hassle of all that publishing, would be to create an on demand workflow that updates your field directly and then manually run that workflow against your record.  However, CRM DevTools provides an even better option through the Test tab by allowing a System Administrator to update the field value through the record form even if the field doesn’t exist on the form or it is read-only.

First, you need to head over to the Chrome web store and add the CRM DevTools extension to your Chrome browser.  Also make sure you are System Administrator of your environment, otherwise the Test tab will not display.

Next, head to the record you want to update and press F12 which will pop open Chrome’s DevTools pane.  There should be a CRM DevTools tab at the top of the pane.

image

Click CRM DevTools and once it loads, click on the TEST tab.  You can now select up to three fields at a time.  Once you select a field, it will display the existing value in the Value column and then you can change that value.  If the field is a Lookup then you will need to enter the schema name for that Lookup in the Entity Schema Name column.  Then click Update and your field will be set to the new value.

image

Now you can easily update hidden or read-only fields in just a few easy steps without messing with the form or creating unnecessary workflows! 

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2013 Microsoft Dynamics CRM 2015 Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

Dynamics CRM - Entity Change Tracking

With the release of Dynamics CRM 2015 Online Update 1, Microsoft has provided developers many different ways to optimize performance when integrating with other systems.  We already covered Alternate Keys in a previous post which help increase performance by reducing the need to make retrieve API calls in order to find the primary key of a record.  In this post I will cover Entity Change Tracking, another feature of 2015 Online Update 1 which increases performance when needing to send data to an external system by retrieving only a subset of data that has changed since the last retrieval. 

So how does it work?

First you need to enable Change Tracking for the specific entity you want to use it on.  You can do this through the Entity customizations as shown below.

image

Then the RetrieveEntityChanges request can be used in code to get a list of entity records that have changed since the last retrieval.  If it is the first request then you’ll want to pass in an empty string or null to the DataVersion property but subsequent requests should use a token (which is returned from RetrieveEntityChangesRespone) in order to retrieve a list of records that have been changed since the last request.

string token = "";

var records = new List<Entity>(); 
    
var request = new RetrieveEntityChangesRequest(); 
request.EntityName = "account"; 
request.Columns = new ColumnSet("name"); 
request.PageInfo = new PagingInfo() { Count = 5000, PageNumber = 1, ReturnTotalRecordCount = false }; 
request.DataVersion = token;    
    
while (true) 

     var response = (RetrieveEntityChangesResponse)orgService.Execute(request); 
    
     records.AddRange(response.EntityChanges.Changes.Select(x => (x as NewOrUpdatedItem).NewOrUpdatedEntity).ToArray()); 
     records.ForEach(x => Console.WriteLine(x.Id)); 
     if (!response.EntityChanges.MoreRecords) 
     { 
         token = response.EntityChanges.DataToken; 
         Console.WriteLine(token); 
         break;    
     } 
        
     request.PageInfo.PageNumber++; 
     request.PageInfo.PagingCookie = response.EntityChanges.PagingCookie; 
}   

Running this code using LinqPad in a brand new Online trial org with no token provided a list of 10 records that have been changed:

c15e1260-e2cf-e511-80de-a45d36fd127c
c35e1260-e2cf-e511-80de-a45d36fd127c
c55e1260-e2cf-e511-80de-a45d36fd127c
c75e1260-e2cf-e511-80de-a45d36fd127c
c95e1260-e2cf-e511-80de-a45d36fd127c
cb5e1260-e2cf-e511-80de-a45d36fd127c
cd5e1260-e2cf-e511-80de-a45d36fd127c
cf5e1260-e2cf-e511-80de-a45d36fd127c
d15e1260-e2cf-e511-80de-a45d36fd127c
d35e1260-e2cf-e511-80de-a45d36fd127c

And then the DataToken:

568840!02/10/2016 21:11:27

Running the same code above but passing in the token of “568840!02/10/2016 21:11:27” will now yield no results as expected as Account records haven’t been changed since we made our RetrieveEntityChanges request.

As you can see, this new request will be very handy when there is a need to synchronize data to external systems.  Now you can easily optimize performance by only synchronizing records that have been changed since the last sync.

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2015 Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online

Deploy Dynamics CRM with PowerShell Part 3: Auditing

Today's post is written by Ian Moore, a developer at Sonoma Partners.

Making sure that auditing is enabled and configured correctly is usually a critical step when setting up a new Dynamics CRM organization, especially a production instance. Everything related to auditing can easily be added to a deployment or setup script with a couple extra lines of PowerShell code.

The first step in configuring auditing for your organization is to make sure it is enabled at the system level. If it is not enabled here, no auditing will ever occur. Here is a simple code snippet to test if your CRM organization has auditing enabled, and to enable it if it does not:

From there, you will need to ensure that auditing is enabled at the entity level for all data where you want to track changes. If you’re not sure which entities have been configured to audit, you can actually use PowerShell to generate a simple report of your current entity audit settings:

clip_image001

Once you know which entities still need to have auditing enabled, you can use metadata updates to configure each entity. The following snippet would enable auditing for accounts:

As with any metadata changes, you will need to make sure to publish changes for the entity. The easiest way from your PowerShell script would be to use the Publish-CrmAllCustomization function. If you are only updating a handful of entities, you could also create a PublishXmlRequest similar to the UpdateEntityRequest above rather than publishing all changes.

Hopefully these snippets help eliminate necessary manual steps when configuring auditing in your CRM environment.

Make sure to download the Microsoft.Xrm.Data.PowerShell module from GitHub at https://github.com/seanmcne/Microsoft.Xrm.Data.PowerShell and follow https://blogs.msdn.microsoft.com/crminthefield/ for updates to the module!

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM Online

Deploy Dynamics CRM with PowerShell Part 2: Importing SLAs

Today's post is written by Ian Moore, a Developer at Sonoma Partners.

If your Dynamics CRM deployment includes Service Level Agreements, you have probably encountered the following error in the import log when importing solutions from a dev environment to a testing environment:

“You can't edit an active SLA. Deactivate the SLA, and then try editing it.”

clip_image002

This error occurs because your solution contains an SLA that is active in the current environment. Having an SLA in your solution can complicate imports if you forget to deactivate the SLA before starting, as the error will come at the end of the import process and you will have to start over. Thankfully we can use PowerShell to automatically deactivate any active SLAs and re-activate after importing an updated solution.

For this example we will use a simple solution that contains one SLA component, and try importing it into an organization that already has an active previous version of the SLA.

clip_image004

After getting a connection with Get-CrmConnection, we can query for active SLA’s with Get-CrmRecords in the org we will be importing to:

$crmOrg = Get-CrmConnection –InteractiveMode

# get any active SLAs in the org
$SLAresults = Get-CrmRecords -conn $crmOrg -Entitylogicalname sla -Fields slaid, statecode, isdefault -FilterAttribute statecode -FilterOperator -eq -FilterValue Active

From here we can deactivate the SLAs with Set-CrmRecordState and import the solution:

# deactivate the active SLAs
$SLAresults['CrmRecords'] | % { Set-CrmRecordState -conn $crmOrg -CrmRecord $_ -StateCode Draft -StatusCode Draft }

# import solution
Import-CrmSolution -conn $crmOrg -SolutionFilePath C:\Path\To\Solutions\CaseEnhancements.zip -ActivatePlugins -PublishChanges

With the SLAs in draft status, the solution should import successfully. Once it is completed, we can re-activate the SLAs. One catch to this process is that any SLA that was not marked as Default will not be restored when it is reactivated – so after reactivation we can use Set-CrmRecord to update the “Is Default” property as necessary.

# re-activate SLAs
$SLAresults['CrmRecords'] | % { Set-CrmRecordState -conn $crmOrg -CrmRecord $_ -StateCode Active -StatusCode Active }

# update any default SLAs to be default again
$SLAresults['CrmRecords'] |
? { $_.isdefault -eq 'Yes' } |
% { Set-CrmRecord -conn $crmOrg -EntityLogicalName sla -Id $_.slaid -Fields @{'isdefault'=$true} }

Now any SLAs should be restored to their original state, and the solution with SLA updates is imported and applied. Here is a sample script that shows the whole process:

Make sure to download the Microsoft.Xrm.Data.PowerShell module from GitHub at https://github.com/seanmcne/Microsoft.Xrm.Data.PowerShell and follow https://blogs.msdn.microsoft.com/crminthefield/ for updates to the module!

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM Online

Dynamics CRM 2016 – Turn Any Text Field into an Auto-Complete

Before the holidays I wrote about the new keypress events that exist in Dynamics CRM 2016 and how they can be used to provide more rich data validation but also with the release of Dynamics CRM 2016, the keypress events can be utilized to provide even more functionality by way of auto-complete controls.  Auto-completion methods were added to the Xrm client-side library which can be used in conjunction with the keypress events to turn any text field into an auto-complete control.  This can come in handy if you want to pull data from a third-party source and display it as if it were a native lookup control in CRM. 

A great example of this would be turning the native State and Country address fields into an auto-complete using live data from another source.  Without further ado, lets jump into some code on how this can be accomplished using the native Country field.

In this example I will be using the geognos free web service to retrieve a list of countries as well as their respective flags.

Note:  The free web service is http only so if you are using it in an https-enabled CRM environment then you will have to manually allow access through a browser prompt.

First setup a standard onload event in your JavaScript and register it on your form.

Then make an ajax call to the geognos web service which will retrieve all countries and add them to a list along with a URL to an image of the country flag.

$.ajax({
     url: 'http://www.geognos.com/api/en/countries/info/all.jsonp',
     dataType: "jsonp",
     jsonpCallback: 'callback',
    success: function(data) {
          for (var country in data.Results) {
              countries.push({
                   id: country,
                   name: data.Results[country].Name,
                   icon: "http://www.geognos.com/api/en/countries/flag/" + country + ".png",
                   fields: [data.Results[country].Name] 
              });
          }
    }
});

Next we will write a function using the keypress event for the native address1_country field which will utilize the new auto-completion methods to hide and show a list of countries.  The kepress event needs to handle the logic to filter the list of countries based on what the user types so we will compare what the user typed to the name of the country in the list to filter it down and pass the results to the showAutoComplete method.  If the data passed into showAutoComplete has an icon property set (a url to an image) then it will display an icon next to the list item which we will utilize to display the country’s flag.

var keyPressFcn = function (ext) {
     try {
          var resultSet = { results: [] };
          var userInput = Xrm.Page.getControl("address1_country").getValue();
          var userInputLowerCase = userInput.toLowerCase();
          for (i = 0; i < countries.length; i++) {
               if (userInputLowerCase === countries[i].name.substring(0, 
                  userInputLowerCase.length).toLowerCase()) {
                     resultSet.results.push({
                          id: i,
                          fields: [countries[i].name],
                          icon: countries[i].icon
                     });
               }
               if (resultSet.results.length >= 10) break;
          }
          if (resultSet.results.length > 0) {
              ext.getEventSource().showAutoComplete(resultSet);
         }
         else {
             ext.getEventSource().hideAutoComplete();
         }
     } catch (e) {
          console.log(e);
     }
};

Lastly, we need to register the keypress function we wrote above to the address1_country keypress event

Xrm.Page.getControl("address1_country").addOnKeyPress(keyPressFcn);

Once we add the script to CRM and register the onload function we can now check it out in action!

Note:  The user can still type free-form text into the control and by default CRM won’t validate that the user selected something from the list but JavaScript validation could be added to make sure an item from the list was used if necessary for your business.

Here is the complete script for this example:

Topics: Microsoft Dynamics CRM Microsoft Dynamics CRM 2016 Microsoft Dynamics CRM Online