Setting up a Domain Controller on Microsoft Azure Virtual Machine

Installing a Domain Controller on Microsoft Azure Virtual Machine turned out to be quite a challenge and it was not even the primary task I was trying to achieve this weekend. I was trying to setup a Microsoft CRM VM on Azure and it all lead to 24 Hours of learning on Azure Services and Azure Powershell. I am used to setting up a separate Active Directory Server when installing CRM or SharePoint locally (Standard or Enterprise SharePoint installations don’t allow installing AD on the same machine anymore) – what I understood from the effort is that if you are new to Azure, the order of the following steps are really important.

  1. Setup a Virtual Network (VNet) under your Microsoft Azure Subscription.
  2. Select New > Network Services > Custom Create.
    • Give your Virtual network a name and click Next.
    • Leave the DNS Servers Empty for now – we will come back to it after our AD Forest and DNS Server are all setup.
    • Click Next and leave Virtual Network Address Spaces to Default 10.0.0.0 subnet
  3. Create the first domain controller Virtual Machine  – New > Compute > Virtual Machine > From Gallery.
    • Select “Windows Server 2012 R2 Datacenter”, give your Virtual Machine a Name and specify a username / password
    • In Virtual Machine Configuration, Select a new Cloud Service (if you are setting up a second domain domain controller, you will have to select the same Cloud Service)
    • Select your virtual network that you setup in Step 1 in the Region / Affinity Group / Virtual Network.
    • Select the default storage account (or the same storage account as the first DC machine if you are adding more than one DCs)
    • Create an Availability Set for your first DC VM (You will have to add all subsequent DC VMs in the same Availability Groups)
    • Click Next and check “Install the VM Agent” and Clock Complete.
  4. You can also setup more than one Domain Controllers by following additional information mentioned in Step 3.
  5. Setup Static Internal IP Addresses for each of your DC VMs. (You can use Azure Powershell Console on your local machine to setup the Static Internal IPs – you may have to install the Azure SDK on your local machine to get the Azure Powershell. The SDK also installs some great Visual Studio Tools for you if you have Visual Studio 2013 Update 3 or above)
  6. PS C:\> Get-AzureVM -ServiceName AleemVNet2DC -Name AleemVNet2DC | Set-AzureStaticVNetIP -IPAddress 10.0.0.4 | Update-AzureVM

    image

  7. Attach a new Empty Hard Disk to each of your DC VMs. This disk will be used for saving the Active Directory Files, Logs etc.
    • Go to the Azure Virtual Machines dashboard on Azure Portal and clock “Attach” in the bottom Ribbon options – Select “Attach an Empty” disk and create a new empty disk – specify name and size of the disk (say 10 GB).
    • Repeat this step for each of your DC VMs
  8. Login to the DC VM and Setup the new attached disk
    • Go to Server Manager > Storage > Disks and select the new attached disk.
    • Right Click and Create a New Volume on the disk.
    • Select all default options and complete the wizard.
    • A new NTFS Volume will be created on the new disk.
  9. Go to your Virtual Network (VNet) created in Step 1
    • Select the Virtual Network and Select Configure
    • Under DNS Servers enter the server name and Static IP Address of your DC Server
    • If you are planning to setup multiple DCs, then enter all the server names and static IPs that you have setup in Step 5.
  10. Login to your Domain Controller VM and install the Active Directory using the Roles and Features Wizard.
    • Go to Server Manager > Manage > Add Roles and Features > Active Directory Services.
    • Complete the Wizard and the Installation
    • After your installation is complete, the server will ask you to configure your feature and if you want to promote this active directory server as domain controller.
    • Complete the Configuration on the Primary Server.
    • The system will ask for a server restart.
    • In case if you are installing multiple DCs, you will have to join all other DC machines to the primary domain first by logging in to the VM – then repeat the same steps of installing and configuring the Active Directory and promoting the server as a Domain Controller
      • You will have to specify the same domain name for secondary controllers and also select the replication from primary server option during the domain controller configuration. Apart from that the configuration is the same as primary server.
  11. Restart the machines and your domain Controller should be up and running with multiple redundant DCs (in case of multiple DCs).

The following article http://azure.microsoft.com/en-us/documentation/articles/active-directory-new-forest-virtual-machine/ on Azure website was extremely helpful but since I am new to Azure and still figuring out the Powershell commands and the order order of all the steps mentioned above. In the end it all worked out and I have an AD Forest on an Azure Virtual Network with two replicated Domain Controllers under a single Azure Cloud Service and an Availability Set.

FIX: MVC 4 – jqGrid Theme Issue

Just wasted 30 minutes trying to load the jqGrid theme – and it just won’t load. Tried setting up the new bundle configuration – even tried loading the scripts and css files directly in the <head> of _Layout.cshtml but the theme would still not load.

FIX:

The MVC 4 Project Template inserts the following at the end of footer –

@Scripts.Render(“~/bundles/jquery”)
@RenderSection(“scripts”, required: false)

The jquery files should be loaded in the <head> section – Moving @Scripts.Render(“~/bundles/jquery”) should solve the issue – Even if you load the jquery files in the <head> section explicitly – the @Scripts.Render(“~/bundles/jquery”) at the bottom would cause problem and would not let the theme load.

Dynamics CRM 2013 – Sales Entities & Sales Process

Dynamics CRM includes the following Sales Entities and few of these specially Leads, Accounts, Contacts, Opportunities, Quotes, Orders and Invoices are very important for the Sales Process (shown in the diagram below)

  • Lead
    • Leads when Qualified can be converted into Contacts, Accounts and/or Opportunities
  • Accounts
  • Contacts
  • Opportunities
  • Competitors
  • Products
  • Quotes
  • Orders
  • Invoices
  • Goals
  • Goals Metrics
  • Rollup Queries
  • Marketing Lists
  • Sales Literature
  • Quick Campaigns

The following Sales Process is available out of the Box in the Dynamics CRM (diagram courtesy Microsoft VA). The Sales Process Starts with a Lead – which has to be Qualified to Create an Opportunity which can then result in a Quote, an Order and Finally an Invoice.

The Lead Qualification Process depends on the Organization – and there are different methodologies to qualify a lead – the most popular being the BANT (Budget, Authority, Need, Timeline). A Salesperson determines if the Lead has the Authority, and Real Need for the Product or Service and if they have the budget and can make t he purchase in an appropriate time – Once the lead is qualified it can be converted into a potential opportunity.

image

Dynamics CRM 2013 – Installing Sample Data

Loved the way Dynamics 2013 allows you to install Sample Data from within the product without restoring any sample databases (I miss AdventureWorks Db !) – I used a CRM Online Account last year for a few days and it had the sample data which made it really easy for me to browse and understand different areas of the system – but when I installed the On-Premise CRM 2013 on a VM – it had no data and I had to create the Accounts, Contacts, Leads etc.

The quick way to setup the Sample Data on a clean installation is to go to CRM >> Settings >> Data Management and Click on Sample Data.

image

image

The popup will let you install the Sample Data on the CRM.

image

The other nice feature is the background installation so you don’t have to wait for the data to be setup – you can close the dialog and continue to work on the product while the data is setup quietly – and Viola now I have the data.

image

image

The Sample Data can also be removed using the same steps – and works perfectly.

Reference Books these days

Some amazing books which I am keeping with me these days for reference and going through portions whenever I get the opportunity.

Amazon List: http://amzn.com/w/LJTHFOO05T4U

TITLE

C# in Depth, Second Edition by Jon Skeet

CLR via C#, Second Edition (Pro Developer) by Jeffrey Richter (Author)

Framework Design Guidelines: Conventions, Idioms, and
Patterns for Reusable .NET Libraries (2nd Edition)
 
by Krzysztof Cwalina, Brad Abrams

Microsoft® .NET: Architecting Applications for the
Enterprise (Pro-Developer)​
 
by Dino Esposito, Andrea Saltarello

Microsoft® Application Architecture Guide, 2nd Edition
(Patterns & Pra​ctices)
 
by Microsoft Patterns & Practices Team (Author)

NHibernate 3.0 Cookbook by Jason Dentler

Patterns of Enterprise Application Architecture by Martin Fowler

Professional ASP.NET Design Patterns by Scott Millett

Programming Entity Framework: DbContext by Julia Lerman, Rowan Miller

 

Writing Fluent API in your applications

Fluent Interfaces / APIs are an amazing way of chaining methods and passing the input of the previous operation to the next operation. This reduces the amount of code required to declare similar objects or setting properties and configurations of the same object and makes the code more readable. Martin Fowler and Eric Evans coined the term back in 2005 (http://martinfowler.com/bliki/FluentInterface.html)

The implementation is very straight forward. The general pattern is to have chained methods each of which should be self-referential (should return object of its own type) and a terminating method to end the chain.

Following is a simplest example, a Number class which provides self-referential methods of operations returning the Number Object itself and an Equals method to terminate the chain.

    public class Number

    {

        private int _number;

        public Number(int num)

        {

            _number = num;

        }

        public Number Add(int num)

        {

            _number += num;

            return this;

        }

        public Number Subtract(int num)

        {

            _number -= num;

            return this;

        }

        public Number Multiply(int num)

        {

            _number *= num;

            return this;

        }

        public Number Divide(int num)

        {

            _number /= num;

            return this;

        }

        public int Equals()

        {

            return _number;

        }

    }

So, we can use the number class as follows by chaining the operations together.

              Console.WriteLine(

                new Number(10)

                .Add(10)

                .Subtract(5)

                .Multiply(10)

                .Divide(2)

                .Equals()

                );

Dynamically Adding DbSet Properties in DbContext for Entity Framework Code First

When working with Entity Framework Code First, the general pattern to add DbSet properties to the DbContext object is as follows. The Entity Framework will build the model according to the DbSet properties defined in the DbContext.

public class MyAppContext : DbContext

    {

        DbSet<Customer> customers { get; set; }

    }

However, for a project with even a fair bit of domain complexity, defining DbSet properties for all entities would not be possible and we need a way to dynamically read our Entity Types and add them dynamically in the DbContext. This can be achieved by implementing OnModelCreating method of the DbContext. The Entity Types can be read from either the executing assembly Assembly.GetExecutingAssembly() or by loading more than one assemblies which can be placed in a configuration file (as shown below in the example). For details about setting up the custom configuration section with your assemblies see my last post

The following code will add all Class Types to the DbContext for all the assemblies added in the configuration file, notice we are actually calling modelBuilder.Entity<T>() method through reflection.

 

public class MyAppContext : DbContext

    {

        protected override void OnModelCreating(DbModelBuilder modelBuilder)

        {

            CustomAssemblySection configSection = (CustomAssemblySection)System.Configuration.ConfigurationManager.GetSection("CustomAssemblySection");

 

            foreach (CustomAssembly customAssembly in configSection.Assemblies)

            {

                Assembly assembly = Assembly.Load(customAssembly.Name);

                foreach (Type type in assembly.ExportedTypes)

                {

                    if (type.IsClass)

                    {

                        MethodInfo method = modelBuilder.GetType().GetMethod("Entity");

                        method = method.MakeGenericMethod(new Type[] { type });

                        method.Invoke(modelBuilder, null);

                    }

                }

            }

            base.OnModelCreating(modelBuilder);

        }

    }

Adding Custom Configuration Section in .NET Configuration Files

In order to add a Custom Configuration Section in any of .NET configuration files like app.config or web.cofig, the framework provides classes in the System.Configuration namespace such as System.Configuration.ConfigurationSection, System.Configuration.ConfigurationElement, System.Configuration.ConfigurationElementCollection and others.

Lets say we want to add the following Custom Section in the configuration file which can hold a list of assemblies.

<CustomAssemblySection>

    <assemblies>

      <add name="System.Configuration"></add>

      <add name="System.Data.Entity"></add>

      <add name="System.Data"></add>

      <add name="System.Xml"></add>

      <add name="System.Xml.Linq"></add>

      <add name="System.Core"></add>

    </assemblies>

  </CustomAssemblySection>

We need a Custom ConfigurationSection, a Custom ConfigurationElementCollection (assemblies) and a Cusom ConfigurationElement with one property which is “name” of the assembly. The following code is achieving exactly that. We have three classes CustomAssemblySection, CustomAssemblyCollection and CustomAssembly which inherit from the respective classes of System.Configuration.

Following is code for a simple Console Application with Program.cs and App.config files. The Program Main is reading the configuration and writing the assembly names on the Console.

For further reading you can refer to MSDN How To: http://msdn.microsoft.com/en-us/library/2tw134k3(v=vs.100).aspx

Program.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Configuration;

namespace CustomConfigurationSectionConsole

{

    class Program

    {

        static void Main(string[] args)

        {

            CustomAssemblySection customSection = (CustomAssemblySection)System.Configuration.ConfigurationManager.GetSection("CustomAssemblySection");

             foreach (CustomAssemblyElement customAssembly in customSection.Assemblies)

             {

                 Console.WriteLine(customAssembly.Name);

             }

             Console.ReadLine();

        }

    }

    public class CustomAssemblySection : ConfigurationSection

    {

        [ConfigurationProperty("assemblies", IsDefaultCollection = false)]

        [ConfigurationCollection(typeof(CustomAssemblyCollection))]

        public CustomAssemblyCollection Assemblies

        {

            get

            {

                return (CustomAssemblyCollection)base["assemblies"];

            }

        }

    }

    public class CustomAssemblyCollection : ConfigurationElementCollection

    {

        protected override ConfigurationElement CreateNewElement()

        {

            return new CustomAssemblyElement();

        }

        protected override object GetElementKey(ConfigurationElement element)

        {

            return ((CustomAssemblyElement)element).Name;

        }

        public CustomAssemblyElement this[int Index]

        {

            get

            {

                return (CustomAssemblyElement)BaseGet(Index);

            }

            set

            {

                if (BaseGet(Index) != null)

                {

                    BaseRemoveAt(Index);

                }

                BaseAdd(Index, value);

            }

        }

        new public CustomAssemblyElement this[string Name]

        {

            get

            {

                return (CustomAssemblyElement)BaseGet(Name);

            }

        }

    }

    public class CustomAssemblyElement : ConfigurationElement

    {

        [ConfigurationProperty("name", IsRequired = true)]

        public string Name

        {

            get

            {

                return (string)this["name"];

            }

            set

            {

                this["name"] = value;

            }

        }

    }

}

App.config

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <section name="CustomAssemblySection" type="CustomConfigurationSectionConsole.CustomAssemblySection, CustomConfigurationSectionConsole"/>

  </configSections>

    <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

    </startup>

  <CustomAssemblySection>

    <assemblies>

      <add name="System.Configuration"></add>

      <add name="System.Data.Entity"></add>

      <add name="System.Data"></add>

      <add name="System.Xml"></add>

      <add name="System.Xml.Linq"></add>

      <add name="System.Core"></add>

    </assemblies>

  </CustomAssemblySection>

</configuration>