public override void ExecuteCmdlet()
        {
            this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg),
                this.CommandRuntime.Host.UI, AzureSession.ClientFactory.CreateClient<StorageManagementClient>(DefaultProfile.Context, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription);

            base.ExecuteCmdlet();

            ExecuteClientAction(() =>
            {
                this._Helper.WriteVerbose("Retrieving VM...");

                var selectedVM = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName);
                var selectedVMStatus = ComputeClient.ComputeManagementClient.VirtualMachines.GetWithInstanceView(this.ResourceGroupName, this.VMName);

                if (selectedVM == null)
                {
                    var subscriptionId = this.DefaultContext.Subscription.Id;
                    this._Helper.WriteError("No virtual machine with name {0} in resource group {1} in subscription {2} found", this.VMName, this.ResourceGroupName, subscriptionId);
                    return;
                }

                var osdisk = selectedVM.StorageProfile.OsDisk;

                if (String.IsNullOrEmpty(this.OSType))
                {
                    this.OSType = osdisk.OsType;
                }
                if (String.IsNullOrEmpty(this.OSType))
                {
                    this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType",
                        AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux);
                    return;
                }

                var disks = selectedVM.StorageProfile.DataDisks;

                var sapmonPublicConfig = new List<KeyValuePair>();
                var sapmonPrivateConfig = new List<KeyValuePair>();
                var cpuOvercommit = 0;
                var memOvercommit = 0;
                var vmsize = selectedVM.HardwareProfile.VmSize;
                switch (vmsize)
                {
                    case AEMExtensionConstants.VMSizeExtraSmall:
                    case AEMExtensionConstants.VMSizeStandard_A0:
                    case AEMExtensionConstants.VMSizeBasic_A0:
                        vmsize = "ExtraSmall (A0)";
                        WriteVerbose("VM Size is ExtraSmall - setting overcommitted setting");
                        cpuOvercommit = 1;
                        break;
                    case "Small":
                        vmsize = "Small (A1)";
                        break;
                    case "Medium":
                        vmsize = "Medium (A2)";
                        break;
                    case "Large":
                        vmsize = "Large (A3)";
                        break;
                    case "ExtraLarge":
                        vmsize = "ExtraLarge (A4)";
                        break;
                }
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "vmsize", Value = vmsize });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.memory.isovercommitted", Value = memOvercommit.ToString() });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.cpu.isovercommitted", Value = cpuOvercommit.ToString() });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "script.version", Value = AEMExtensionConstants.CurrentScriptVersion });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "verbose", Value = "1" });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "href", Value = "http://aka.ms/sapaem" });

                var vmSLA = this._Helper.GetVMSLA(selectedVM);
                if (vmSLA.HasSLA)
                {
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.sla.throughput", Value = vmSLA.TP });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.sla.iops", Value = vmSLA.IOPS });
                }

                // Get Disks
                var accounts = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
                var accountName = this._Helper.GetStorageAccountFromUri(osdisk.Vhd.Uri);
                var storageKey = this._Helper.GetAzureStorageKeyFromCache(accountName);
                accounts.Add(accountName, storageKey);

                this._Helper.WriteHost("[INFO] Adding configuration for OS disk");

                var caching = osdisk.Caching;
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.name", Value = osdisk.Name });
                sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.caching", Value = caching });
                if (this._Helper.IsPremiumStorageAccount(accountName))
                {
                    WriteVerbose("OS Disk Storage Account is a premium account - adding SLAs for OS disk");
                    var sla = this._Helper.GetDiskSLA(osdisk);
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.type", Value = AEMExtensionConstants.DISK_TYPE_PREMIUM });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.throughput", Value = sla.TP });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.iops", Value = sla.IOPS });
                }
                else
                {
                    WriteVerbose("OS Disk Storage Account is a standard account");
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.type", Value = AEMExtensionConstants.DISK_TYPE_STANDARD });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.connminute", Value = (accountName + ".minute") });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.connhour", Value = (accountName + ".hour") });
                }

                // Get Storage accounts from disks
                var diskNumber = 1;
                foreach (var disk in disks)
                {
                    accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri);
                    if (!accounts.ContainsKey(accountName))
                    {
                        storageKey = this._Helper.GetAzureStorageKeyFromCache(accountName);
                        accounts.Add(accountName, storageKey);
                    }

                    this._Helper.WriteHost("[INFO] Adding configuration for data disk {0}", disk.Name);
                    caching = disk.Caching;
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.lun." + diskNumber, Value = disk.Lun.ToString() });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.name." + diskNumber, Value = disk.Name });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.caching." + diskNumber, Value = caching });

                    if (this._Helper.IsPremiumStorageAccount(accountName))
                    {
                        this._Helper.WriteVerbose("Data Disk {0} Storage Account is a premium account - adding SLAs for disk", diskNumber.ToString());
                        var sla = this._Helper.GetDiskSLA(disk);
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.type." + diskNumber, Value = AEMExtensionConstants.DISK_TYPE_PREMIUM });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.throughput." + diskNumber, Value = sla.TP });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.iops." + diskNumber, Value = sla.IOPS });
                        this._Helper.WriteVerbose("Done - Data Disk {0} Storage Account is a premium account - adding SLAs for disk", diskNumber.ToString());

                    }
                    else
                    {
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.type." + diskNumber, Value = AEMExtensionConstants.DISK_TYPE_STANDARD });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.connminute." + diskNumber, Value = (accountName + ".minute") });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.connhour." + diskNumber, Value = (accountName + ".hour") });
                    }

                    diskNumber += 1;
                }

                //Check storage accounts for analytics
                foreach (var account in accounts)
                {
                    this._Helper.WriteVerbose("Testing Storage Metrics for {0}", account.Key);

                    var storage = this._Helper.GetStorageAccountFromCache(account.Key);

                    if (!this._Helper.IsPremiumStorageAccount(storage))
                    {
                        if (!this.SkipStorage.IsPresent)
                        {
                            var currentConfig = this._Helper.GetStorageAnalytics(storage.Name);

                            if (!this._Helper.CheckStorageAnalytics(storage.Name, currentConfig))
                            {
                                this._Helper.WriteHost("[INFO] Enabling Storage Account Metrics for storage account {0}", storage.Name);

                                // Enable analytics on storage accounts
                                this.SetStorageAnalytics(storage.Name);
                            }
                        }

                        var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage);
                        var hourUri = endpoint + "$MetricsHourPrimaryTransactionsBlob";
                        var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob";

                        this._Helper.WriteHost("[INFO] Adding Storage Account Metric information for storage account {0}", storage.Name);

                        sapmonPrivateConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.key"), Value = account.Value });
                        sapmonPrivateConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.key"), Value = account.Value });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.uri"), Value = hourUri });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.uri"), Value = minuteUri });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.name"), Value = storage.Name });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.name"), Value = storage.Name });
                    }
                    else
                    {
                        this._Helper.WriteHost("[INFO] {0} is of type {1} - Storage Account Metrics are not available for Premium Type Storage.", storage.Name, storage.AccountType.Value.ToString());
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.ispremium"), Value = "1" });
                        sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.ispremium"), Value = "1" });
                    }
                }

                WriteVerbose("Chechking if WAD needs to be configured");
                // Enable VM Diagnostics
                if (!this.DisableWAD.IsPresent)
                {
                    this._Helper.WriteHost("[INFO] Enabling IaaSDiagnostics for VM {0}", selectedVM.Name);
                    KeyValuePair wadstorage = null;
                    if (String.IsNullOrEmpty(this.WADStorageAccountName))
                    {
                        KeyValuePair<string, string>? wadstorageTemp = accounts.Cast<KeyValuePair<string, string>?>().
                            FirstOrDefault(accTemp => !this._Helper.IsPremiumStorageAccount(accTemp.Value.Key));
                        if (wadstorageTemp.HasValue)
                        {
                            wadstorage = new KeyValuePair(wadstorageTemp.Value.Key, wadstorageTemp.Value.Value);
                        }
                    }
                    else
                    {
                        wadstorage = new KeyValuePair(this.WADStorageAccountName, this._Helper.GetAzureStorageKeyFromCache(WADStorageAccountName));
                    }

                    if (wadstorage == null)
                    {
                        this._Helper.WriteError("A Standard Storage Account is required.");
                        return;
                    }

                    selectedVM = SetAzureVMDiagnosticsExtensionC(selectedVM, wadstorage.Key, wadstorage.Value);

                    var storage = this._Helper.GetStorageAccountFromCache(wadstorage.Key);
                    var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage);
                    var wadUri = endpoint + AEMExtensionConstants.WadTableName;

                    sapmonPrivateConfig.Add(new KeyValuePair() { Key = "wad.key", Value = wadstorage.Value });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.name", Value = wadstorage.Key });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.isenabled", Value = "1" });
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.uri", Value = wadUri });
                }
                else
                {
                    sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.isenabled", Value = "0" });
                }

                ExtensionConfig jsonPublicConfig = new ExtensionConfig();
                jsonPublicConfig.Config = sapmonPublicConfig;

                ExtensionConfig jsonPrivateConfig = new ExtensionConfig();
                jsonPrivateConfig.Config = sapmonPrivateConfig;

                this._Helper.WriteHost("[INFO] Updating Azure Enhanced Monitoring Extension for SAP configuration - Please wait...");

                WriteVerbose("Installing AEM extension");
                var op = this.VirtualMachineExtensionClient.CreateOrUpdateWithHttpMessagesAsync(
                    this.ResourceGroupName, this.VMName, AEMExtensionConstants.AEMExtensionDefaultName[OSType],
                    new VirtualMachineExtension()
                    {
                        Publisher = AEMExtensionConstants.AEMExtensionPublisher[OSType],
                        VirtualMachineExtensionType = AEMExtensionConstants.AEMExtensionType[OSType],
                        TypeHandlerVersion = AEMExtensionConstants.AEMExtensionVersion[OSType],
                        Settings = jsonPublicConfig,
                        ProtectedSettings = jsonPrivateConfig,
                        Location = selectedVM.Location,
                        AutoUpgradeMinorVersion = true
                    }).GetAwaiter().GetResult();

                this._Helper.WriteHost("[INFO] Azure Enhanced Monitoring Extension for SAP configuration updated. It can take up to 15 Minutes for the monitoring data to appear in the SAP system.");
                this._Helper.WriteHost("[INFO] You can check the configuration of a virtual machine by calling the Test-AzureRmVMAEMExtension commandlet.");

                var result = Mapper.Map<PSAzureOperationResponse>(op);
                WriteObject(result);
            });
        }
        private void LoadExamples()
        {
            this.lstExamples.DisplayMember = "Key";
            //this.lstExamples.ValueMember = "Value";
            var examples = new Dictionary<string, string> {
{"Basics of SmartFormat", 
@"Basics of SmartFormat
Similar to String.Format, SmartFormat uses curly braces to identify a placeholder:  The arguments on the right side of this window can be referenced in a template as follows:
{Person}, {Date}, {Inventory}

Many .NET objects can be formatted in a specific or custom way by using a ""format string"", which is any text that comes after a colon : in a placeholder:
Long date format: {Date:D}
Short date format: {Date:d}
Custom format: {Date:""today is"" dddd, ""the"" d ""of"" MMMM}

For more information on Composite Formatting and standard formatting strings, please visit http://msdn.microsoft.com/en-us/library/txafckwd.aspx
"},

{"Named Placeholders", 
@"Named Placeholders
Placeholders can use the name of any property, method, or field:
{Person.Name.ToUpper} is {Person.Age} years old and he has {Person.Friends.Count} friends.

Nested properties can use: 
- dot-notation: {Person.Address.State}
- nested notation: {Person.Address:{State}}
- any mixture of the two: {Person.Address:{State.ToString:{ToUpper}} }
"},

{"Pluralization, Grammatical Numbers, and Gender Conjugation", 
@"Pluralization, Grammatical Numbers, and Gender Conjugation
Many languages have specific and complex rules for pluralization and gender conjugation.  It is typically difficult to use templates and still use correct conjugation.  However, SmartFormat has a library of rules for hundreds of languages, and has an extremely simple syntax for choosing the correct word based on a value!

In English, there are only 2 plural forms: singular and plural.  You can specify a format string with both words, and the correct word will be chosen:
{Person.Random}: {Person.Random:singular|plural}

Example:
There {Person.Random:is|are} {Person.Random} {Person.Random:item|items} remaining.
"},

{"List Formatting", 
@"<!-- Pay attention to the ending |}} token -->
<Items count=""{Inventory.Count}"">
{Inventory:
	<Item name=""{Name}"" price=""{Price:c}"" index=""{Index}"" components=""{Components.Count}"">
	{Components:
	    <Component name=""{Name}"" count=""{Count}"" />
	|}
	</Item>
|}
</Items>
"},
            };

	        var listObjects = examples.Cast<object>().ToArray();
	        this.lstExamples.Items.AddRange(listObjects);
	        this.lstExamples.SelectedIndex = 0;
        }