You may experience errors while running the CrmSvcUtil tool against an IFD enabled Microsoft Dynamics CRM 2011 server. This is due to a bug (specific only to CrmSvcUtil) in the way that the credentials are established. This article describes a workaround that resolves the issue using a custom metadata provider component. Note that this approach specifically targets claims-based authentication scenarios and should not be used for Active Directory or Live ID authentication.

Download the attached MetadataProvider.dll assembly or compile your own with the following steps:

  1. Create a new class library project named MetadataProvider
  2. Add the source code (IfdMetadataProviderservice.cs) below into the project
  3. Add references to the assemblies:
    1. Microsoft.Xrm.Sdk.dll
    2. crmsvcutil.exe
    3. System.Runtime.Serialization.dll
    4. System.ServiceModel.dll
  4. The output file name of the project should be MetadataProvider.dll
  5. Build the project
  6. Copy the MetadataProvider.dll file into the same folder where CrmSvcUtil.exe is located

Use the following command line:

crmsvcutil.exe /metadataproviderservice:"MetadataProvider.IfdMetadataProviderService, MetadataProvider" /codecustomization:"Microsoft.Xrm.Client.CodeGeneration.CodeCustomization, Microsoft.Xrm.Client.CodeGeneration" /url:"https://orgname.domain.com/XRMServices/2011/Organization.svc" /out:"xrm.cs" /namespace:Xrm /serviceContextName:XrmServiceContext /serviceContextPrefix:Xrm /u:"domain\username" /p:password 

Note that this example uses an ADFSv2 based username but any username appropriate to your identity provider will work. The /domain (/d) option should not be specified.

The IfdMetadataProviderService.cs file:

// - create a new class library project
// - add references to the following assemblies:
//   - Microsoft.Xrm.Sdk.dll, crmsvcutil.exe, System.Runtime.Serialization.dll, System.ServiceModel.dll
// - generate an output library named:
//   - MetadataProvider.dll
// - copy this DLL to the same folder as crmsvcutil.exe
//
// - Command line usage:
// crmsvcutil.exe
//  /metadataproviderservice:"MetadataProvider.IfdMetadataProviderService, MetadataProvider"
//  /codecustomization:"Microsoft.Xrm.Client.CodeGeneration.CodeCustomization, Microsoft.Xrm.Client.CodeGeneration"
//  /url:"https://orgname.domain.com/XRMServices/2011/Organization.svc"
//  /out:"xrm.cs" /namespace:Xrm /serviceContextName:XrmServiceContext
//  /serviceContextPrefix:Xrm
//  /u:"domain\username"
//  /p:password
//
// Note: omit the /domain (/d) option

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.ServiceModel.Description;
using Microsoft.Crm.Services.Utility;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Metadata;

namespace MetadataProvider
{
	public sealed class IfdMetadataProviderService : IMetadataProviderService
	{
		private class OrganizationMetadata : IOrganizationMetadata
		{
			public EntityMetadata[] Entities { get; set; }
			public OptionSetMetadataBase[] OptionSets { get; set; }
			public SdkMessages Messages { get; set; }
		}

		private readonly Dictionary<string, string> _parameters;
		private OrganizationMetadata _metadata;

		public IfdMetadataProviderService(IDictionary<string, string> parameters)
		{
			_parameters = new Dictionary<string, string>(parameters, StringComparer.InvariantCultureIgnoreCase);
		}

		IOrganizationMetadata IMetadataProviderService.LoadMetadata()
		{
			if (_metadata == null)
			{
				var credentials = new ClientCredentials();
				credentials.UserName.UserName = _parameters["username"];
				credentials.UserName.Password = _parameters["password"];

				using (var service = new OrganizationServiceProxy(new Uri(_parameters["url"]), null, credentials, null))
				{
					service.Timeout = new TimeSpan(0, 5, 0);

					_metadata = new OrganizationMetadata
					{
						Entities = RetrieveEntities(service),
						OptionSets = RetrieveOptionSets(service),
						Messages = RetrieveMessages(service),
					};
				}
			}

			return _metadata;
		}

		private static EntityMetadata[] RetrieveEntities(IOrganizationService service)
		{
			var request = new OrganizationRequest("RetrieveAllEntities");
			request.Parameters["EntityFilters"] = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships;
			request.Parameters["RetrieveAsIfPublished"] = false;
			var response = service.Execute(request);
			return response.Results["EntityMetadata"] as EntityMetadata[];
		}

		private static OptionSetMetadataBase[] RetrieveOptionSets(IOrganizationService service)
		{
			var request = new OrganizationRequest("RetrieveAllOptionSets");
			request.Parameters["RetrieveAsIfPublished"] = false;
			var response = service.Execute(request);
			return response.Results["OptionSetMetadata"] as OptionSetMetadataBase[];
		}

		private static SdkMessages RetrieveMessages(IOrganizationService service)
		{
			var type = Assembly.LoadFrom("crmsvcutil.exe").GetType("Microsoft.Crm.Services.Utility.SdkMetadataProviderService");
			var getMessages = type.GetMethod("RetrieveSdkRequests", BindingFlags.Instance | BindingFlags.NonPublic);
			var provider = FormatterServices.GetUninitializedObject(type);
			return getMessages.Invoke(provider, new object[] { service }) as SdkMessages;
		}
	}
}