Recover “lost” CRM encryption key

Have you ever had “Data encryption can’t be activated because the encryption key doesn’t match the source encryption key used to encrypt the data” error when trying to activate/change encryption key on organization that was imported or upgraded from previous CRM version?
If you’re on on-prem and you have MSCRM_CONFIG database of source organization, you can recover your key – that told if you don’t have backed it up 🙂

First, let’s retrieve it from database:

SELECT ColumnName, VarBinaryColumn FROM OrganizationProperties
WHERE Id IN (SELECT Id FROM Organization WHERE UniqueName = '<OrgUniqName>')
AND (ColumnName = 'SymmetricKeySource')

It will look like “0xABCDEF”, looks like hexstring, let’s decode:

var sb = new StringBuilder();
var str = "0x37323A303A3130313A303A3130383A303A3130383A303A3131313A303A33323A303A38343A303A3130343A303A3130353A303A3131353A303A33323A303A37333A303A3131353A303A33323A303A3131323A303A39373A303A3131353A303A3131353A303A36343A303A3131393A303A3131313A303A3131343A303A3130303A303A34393A303A33323A303A3130323A303A3131343A303A3131313A303A3130393A303A33323A303A36373A303A38323A303A37373A30";
for (int i = 2; i < str.Length; i += 2)
{
var b1 = byte.Parse(str.Substring(i, 2), NumberStyles.HexNumber);

var part = ASCIIEncoding.ASCII.GetString(new byte[] { b1 });

sb.Append(part);
}
Console.WriteLine(sb);

Now it should look like this:

72:0:101:0:108:0:108:0:111:0:32:0:84:0:104:0:105:0:115:0:32:0:73:0:115:0:32:0:112:0:97:0:115:0:115:0:64:0:119:0:111:0:114:0:100:0:49:0:32:0:102:0:114:0:111:0:109:0:32:0:67:0:82:0:77:0

As you know, password can be Unicode, so here we go again:

var parts = sb.ToString().Split(':');
sb.Clear();
for (int i = 0; i < parts.Length; i += 2)
{
var b1 = byte.Parse(parts[i]);
var b2 = byte.Parse(parts[i + 1]);
var part = UnicodeEncoding.Unicode.GetString(new byte[] { b1, b2 });
sb.Append(part);
}
Console.WriteLine(sb);

And we have our password: Hello This Is pass@word1 from CRM.

Compare this with CRM to be sure:
CRM Encryption Key

Hope this will help someone.

 

 

Installing Microsoft Dynamics CRM 2016 on Windows Server 2016

Running Out-of-the-box Windows 2016 Technical Preview 4, when trying to install Microsoft Dynamics 2016, I’ve run into this error (Action Microsoft.Crm.Setup.Common.InstallWindowsSearchAction failed):

CRM 2016 Installation Error

Checking for Windows Search Service, it looks like it’s installed:

Windows Search

Checking under “services.msc” – it was disabled. Simple changeing to “Manual”,  hitting “Retry” and installation continued without any further problems.

CRM Online Security roles strange issue

I’ve seen some strange issue lately (similar to this one), with one of our CRM Online deployment. We had 2 users, in the same BU, with the same security roles.
Problem was:

  1. First user was able to access CRM records based on priviliges
  2. Second one was “blind” – couldn’t see any records

After looking at all possible settings, the solution was:

  1. Add System Administrator role to second user
  2. Remove System Administrator role from second user

After that, second user could “see” again. Don’t know if removing all roles or any other than System Administrator would do the trick.

CRM Security Roles Summary

To quickly view which role have what rights, You can use this SQL query:

SELECT  DISTINCT
        r.Name
        ,COALESCE(e.OriginalLocalizedName, e.Name) AS EntityName
        ,CASE p.AccessRight
             WHEN 32     THEN 'Create' 
             WHEN 1      THEN 'Read'
             WHEN 2      THEN 'Write'
             WHEN 65536  THEN 'Delete' 
             WHEN 4      THEN 'Append'
             WHEN 16     THEN 'AppendTo'
             WHEN 524288 THEN 'Assign' 
             WHEN 262144 THEN 'Share' 
             ELSE 'None'
        END AS [Privilege]
        ,CASE (rp.PrivilegeDepthMask % 0x0F)
             WHEN 1 THEN 'User (Basic)'
             WHEN 2 THEN 'Business Unit (Local)'
             WHEN 4 THEN 'Parental (Deep)'
             WHEN 8 THEN 'Organization (Global)'
             ELSE 'Unknown'
        END AS [PrivilegeLevel]
        ,(rp.PrivilegeDepthMask % 0x0F) as PrivilegeDepthMask
        ,CASE WHEN e.IsCustomEntity = 1 THEN 'Yes' ELSE 'No' END AS IsCustomEntity
FROM    Role AS r
INNER JOIN RolePrivileges AS rp ON r.RoleId = rp.RoleId
INNER JOIN Privilege AS p ON rp.PrivilegeId = p.PrivilegeId
INNER JOIN PrivilegeObjectTypeCodes AS potc ON potc.PrivilegeId = p.PrivilegeId
INNER JOIN MetadataSchema.Entity AS e ON e.ObjectTypeCode = potc.ObjectTypeCode
ORDER BY r.Name, EntityName

Get strongly typed attribute logical name for CRM Entity

When using early bound entities, there’s a easy way to get CRM entity logical attribute name thanks to AttributeLogicalNameAttribute attribute in generated code. You can use this simple extension method:

        public static string GetEntityPropertyLogicalName<E, P>(this E src, Expression<Func<E, P>> expression)
        {
            var member = expression.Body as MemberExpression;
            if (member != null && member.Member is PropertyInfo)
            {
                var pi = member.Member as PropertyInfo;
                var pn = pi.Name;

                var epi = typeof(E).GetProperty(pn);
                var attr = (AttributeLogicalNameAttribute) epi.GetCustomAttribute(typeof(AttributeLogicalNameAttribute));

                if (attr == null)
                {
                    throw new System.ArgumentNullException(pn, "AttributeLogicalNameAttribute not found on property");
                }

                return attr.LogicalName;
            }

            throw new ArgumentException("Expression is not a Property");
        }

And usage is very simple:

            var account = new Account();
            var line1 = account.GetEntityPropertyLogicalName(p => p.Address1_Line1);

Now line1 should contain address1_line1 string.

Lookup Dialog in CRM 2013 with custom FetchXML filtering

Dynamics 2013 introduced some new cool functions to filter lookup during “run-time”, so we can do something like this:

var ctrl = Xrm.Page.getControl('some_lookup_control');
ctrl.addPreSearch(function() {
 var someFetchXml = '<filter type="and"><condition attribute="some_field" operator="eq" value="some_value" /></filter>';
 ctrl.addCustomFilter(someFetchXml);
});

Continue reading