3

Is there any way to track changes to Metadata, like new fields, new entities and so on?

It is difficult to control a very large project in the same environment, so sometimes there are some customization that should not be deployed to productions (Mostly are mistakes or test in a development environment).

And there is a way to know who did that customization?

I am looking to know every possible change, not any in particular.

Sxntk
  • 845
  • 14
  • 29
  • Possible duplicate of [Is it possible to retrieve schema change information in Dynamics CRM online?](https://stackoverflow.com/questions/41575510/is-it-possible-to-retrieve-schema-change-information-in-dynamics-crm-online) – Arun Vinoth-Precog Tech - MVP Sep 13 '17 at 20:09
  • @ArunVinoth that is a specific question and not very clear, I've been searching for a while and no one could be very clear to answer this, not even the official documentation, you are welcome to contribute to my answer. – Sxntk Sep 13 '17 at 20:25
  • 2
    So you are looking for a blaming tool; does not sound like a very constructive approach to me. I recommend storing CRM solutions in source control. You can use the solution packager to unpack solutions. Benefit is that it enables you to track all solution components, not only the entities. – Henk van Boeijen Sep 13 '17 at 20:56
  • @HenkvanBoeijen It is not possible to know 'who' so it is difficult to blame and not what I want. Our team is very large and there are new people once in a while. Customizations in CRM are very sensitive and we don't want "new_" fields (if deployed). I hope to make myself understood. – Sxntk Sep 13 '17 at 21:31
  • @ArunVinoth I had some troubles with your answer because it is not very clear where to get the TimeStamp and how to make the query. I think it is because your answer is based on the msdn and it is confusing too. I made a workaround and hope it will be useful for people looking what I was looking – Sxntk Sep 13 '17 at 21:34

2 Answers2

4

You have to use the RetrieveMetadataChangesRequest and it is not possible to know who made the change.

This is available only from Microsoft Dynamics CRM 2011 Update Rollup 12

This request is intended to be used to cache information from the metadata and be able to work offline, but we can use it to track changes to metadata in complex projects and complex teams

Examples on internet are not very friendly so this is how you can use the request:

The request can be completed only with filling one parameter

RetrieveMetadataChangesRequest req = new RetrieveMetadataChangesRequest()
{
    ClientVersionStamp = null
};
var response = (RetrieveMetadataChangesResponse)service.Execute(req);

The first time you executed this request ClientVersionStamp needs to be null, because there was no request made to the metadata before and there is no ClientVersionStamp. This parameter is the last time you query for metadata changes and if it is null it will bring all customization from all time, so probably this request won't complete on time so we need to tune up.

var EntityFilter = new MetadataFilterExpression(LogicalOperator.And);
EntityFilter.Conditions.Add(new MetadataConditionExpression("SchemaName", MetadataConditionOperator.Equals, "ServiceAppointment"));
var entityQueryExpression = new EntityQueryExpression()
        {
            Criteria = EntityFilter
        };
RetrieveMetadataChangesRequest req = new RetrieveMetadataChangesRequest()
        {
            Query = entityQueryExpression,
            ClientVersionStamp = null
        };
var response = (RetrieveMetadataChangesResponse)service.Execute(req);

This will query all metadata changes for "ServiceAppointment", feel free to use the entity you want, but what we need is the ServerTimeStamp from the response, it will looks like "22319800!09/13/2017 16:17:46", if you try to send this time stamp first, it will throw an exception, so it is necessary to query first to get a server time stamp.

Now you can use the request and the time stamp to retrieve all new changes since "22319800!09/13/2017 16:17:46"

RetrieveMetadataChangesRequest req = new RetrieveMetadataChangesRequest()
        {
          Query = entityQueryExpression,
          ClientVersionStamp = @"22319800!09/13/2017 16:17:46"
        };

var response = (RetrieveMetadataChangesResponse)service.Execute(req);

You can filter the query to match your needs, only search for specific entities, labels, relationship, keys and attributes or specific properties.

EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
{
    Criteria = EntityFilter,
    Properties = EntityProperties,
    RelationshipQuery = new RelationshipQueryExpression()
    {
        Properties = RelationshipProperties,
        Criteria = RelationshipFilter
    },
    AttributeQuery = new AttributeQueryExpression()
    {
        Properties = AttributeProperties,
        Criteria = AttributeFilter
    }
};

Use this request and implement it the way you need.

Sxntk
  • 845
  • 14
  • 29
0

A couple more options:

  1. Register a plugin on Publish and Publish All, and track who did the publish and when. That may help you narrow down who was making changes, although someone could technically make a change without publishing it, so not perfect information.

  2. If you're using Dynamics OnPremise, the Metadata tables sometimes store information about who made a change that is not visible through a Metadata retrieve. I've found this to be very spotty though, not all Metadata has a Modified By user stored.

Matt
  • 4,656
  • 1
  • 22
  • 32
  • Matt, Can you be more specific? How is it possible to know the 'Who' on Publish? – Sxntk Sep 15 '17 at 21:59
  • You can grab it from the plugin execution context: InitiatingUserId (https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.iexecutioncontext.initiatinguserid.aspx) – Matt Sep 15 '17 at 22:01
  • When I press the publish button, the xml doesn't have anything relevant, only the name of the entity – Sxntk Sep 27 '17 at 14:09