Sunday, August 13, 2017

Powershell ISE Cheat sheet

1# How to Comment Multi line code in ISE editor

Put cursor on start of code. Select Shift +Alt and move down arrow key to end of code line. Then press Shift +#

2# How to open/load web page ?

start-process -FilePath ""

Thursday, August 3, 2017

Sitecore XFrameOptionsHeaderModule and Chrome 60.0.3112.78 (official build) (64-bit) x-frame-options SAMEORIGIN Refused to display


Chrome Side of story:-
X-Frame-Option Same origin issue appeared in Chrome version 60+ and it came surprising when browser started upgraded from lower version to this version. What if such issue appeared in production where your platform is dependent on third party service provider such as payment gateway through IFrame or any data layer that injects data to your system. Well the point is everything boils down to how secure you want to create a platform.

Your site- Domain ABC- Allow access to Domain XYZ[SameOrigin will not work]
Chrome version 60 and above enforce this and check this X-frame-options.

What happened next?
It started throwing below error in developer tool f12 - console

Refused to display https://abc' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
iframe-tunnel.js:60 GET https://xyz net::ERR_BLOCKED_BY_RESPONSE

Sitecore MVC Side of story:-

From sitecore 8.1 update 3 onwards sitecore introduce default module to add X-FRAME-OPTION Sameorigin using below module

One can check this in web.config file
 type="Sitecore.Web.XFrameOptionsHeaderModule, Sitecore.Kernel" name="SitecoreXFrameOptionsHeaderModule"/>

Probable Solution

using System.Web.Mvc;

namespace Test.Filters
    public class RemoveXFrameOptionsAttribute : ActionFilterAttribute
        public override void OnResultExecuted(ResultExecutedContext filterContext)
public class TestController : Controller
    public ActionResult Index()
        return View();
//this worked for us.
public class TestController : Controller
    public ActionResult Index()
        return View();

Bit of background

Why x-frame-options SameOrigin thing? This is required to avoid CLICK JACKING.

My final Say

Sitecore should add this in their KB site to be more explicit so that customer is aware of such changes.

Thursday, July 20, 2017

IIS Log Parser and important troubleshooting queiries

Understand your IIS Log better

There are cases when even and sitecore application level logs doesn't provide much of an information.The reason behind is some request is just processed by IIS webserver but never executed at application server i.e sitecore or pipeline.

This is where HTTP.Sys , Failed Request Tracing and IIS logs comes into picture. This is not when you looking for memory leak or CPU utilization.But this is certain some of the pattern of page execution or 500 internal server exception indirectly contributes to memory leak or CPU utilization. Always visit your IIS logs post performance load test. This will help you align your performance results with incoming request made in IIS.

Long story short. Download log parser studio if you have IIS log to analyze. This is very handy tool.

Query#1 Http.5xxx

    time-taken as time_taken_MS,
    DIV(time-taken,60000) as timetaken_MM,
    cs-uri-query ,
    Count(*) AS Total
    From '[LOGFILEPATH]'
    Where sc-status = 500
    Group By cs-username, sc-status, cs-uri-stem, cs-uri-query,date,time,cs-method, cs-uri-query ,time-taken,sc-substatus

Query#2:/*  Count and sort all HTTP status codes */
Remember http status code below have apended http SUB STATUS CODE

    STRCAT('.', TO_STRING(sc-substatus))) As Status,  
    COUNT(*) AS Hits  
GROUP BY Status  

Query#3 To find DDOS Attack

A distributed denial-of-service (DDoS)attack occurs when multiple systems flood the bandwidth or resources of a targeted system, usually one or more web servers. Such an attack is often the result of multiple compromised systems (for example, a botnet) flooding the targeted system with traffic.

/* Hits on a particular page by IP address */

select c-ip, count(c-ip) as requestcount 
where cs-uri-stem like '%/%' 
group by c-ip order by count(c-ip) desc

Monday, July 10, 2017

Sitecore Pipeline HttpBeginRequest and Processor HttpRequestProcessor to Intercept requests before page get processed completely.

Problem Statement:
To intercept each request and check site configuration and take required steps before it is served and processed complete. This can be enabling intermediate maintenance page or site down page in case unfortunate events occurred such as third party service is down . This in particular is the case your content site is more dependent on upstream or downstream application to serve user specific data. Even though you aimed for zero downtime as per your architecture.

Approach 1: To check this flag at every action call using action filter in mvc sitecore controller.
Approach 2: To intercept the call before it call action filter.

Reference: Pipeline and its Processor


Add processor just after ItemResolver to intercept the request to check for sitecore stored flag and take action based on values that something suits your requirement

Pipeline: httpBeginRequest: Sitecore.Pipelines.HttpRequest

Key Notes:
  • Ensure you have proper patch insert for CD and delete for CM. As per the scenario.
  • Ensure you have AbortPipeline in place to prevent -Cascading response header issue- Such as append header and results in Too many redirects.
  • Use custom processor wisely and regression test to cover different use case across the page navigation involves logout /login [For transactional Site or Personalised site]

Thursday, July 6, 2017

Maintenance Page Take App Offline! Magic with App_Offline.htm


The App_offline thing is around for quiet long time and I haven't seen enterprise level system use it. Either they do it using at load balancer end or redirect to some third party hamster page until the site is provision for up and running. Leaving the real time usage and know-how.


Here are quick help tip if you want to enable it.

Key Note
Remember just putting App_offline.htm in the root folder of the website will just stop the further processing of request and always return =

Http Status 503:

The service is unavailable.

If you really want to show up App_Offline.htm custom page you must add this in your web.config file

Refer this for more information

One can even try to automate this using FTP command and powershell or either use out of the box option in VSO Build and Release pipeline.

Take App Offline option under Deployment

Tuesday, July 4, 2017

Gotcha ! Special Character & in web.config

What is special about &?

Whenever you're dealing with ampersand or querystring url in rewrite rules beware of special character "&". There are chances you may play around with different ways to make it working. Inline rewritemap maps things bit difficult. Yes it might happen you have few rewrite and you end up with inline rewrite in web.config. Careful watch rewritemap urls as these may content special character as part of URI and redirection symantics. Sometimes # results in error and exception.

Always try this!

  • Replace & with &Make use of html encode and decode instead of URL Encode value such as "%26"
  • Good practice to keep rewritemap outside web.config . In many scenario the URL encode for ampersand as well # in querystring works.


Monday, July 3, 2017

Sitecore CMS Logout not working due to conflicting Authentication Controller


Sitecore CMS Logout will throw Javascript error due to multiple controller named 'Authentication'

Sitecore Logs
10344 02:57:52 ERROR Application error.
Exception: System.InvalidOperationException
Message: Multiple types were found that match the controller named 'Authentication'. This can happen if the route that services this request ('sitecore/shell/api/sitecore/{controller}/{action}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

The request for 'Authentication' has found the following matching controllers:
Source: System.Web.Mvc
   at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces)
   at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext)
   at Sitecore.Mvc.Routing.RouteHandlerWrapper.GetHttpHandler(RequestContext requestContext)
   at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


  1. Either rename your custom controller from Authentication to something Account to avoid sitecore conflict.
  2. Else apply below Maproute.

public override void RegisterArea(AreaRegistrationContext context) 
              new { controller = "Authentication", action = "Index" },
              new[] { "Sitecore.Controllers" });


Sitecore .Net File Change Notification Shut down issues


Problem Statement

Not sure what is causing file change in webapps whether it is appinsight or for that matter logging handler that keep adding debug, info and error traces, cache or something else. For some reason there is something going under the hood which causes this file change notification. This take me back to the basics of file change notification causes app pool recycle when there is change in web.config or global.asax. Now as best practice it is always mentioned the logging has to be done outside your webroot and for some reason this is not the case with webapp. I'm naïve in webapp world and file and drive structure in azure webapp paas environment. Those days are gone when you use to have full control of VMs and you can deep dive into solving and identifying issues.

KB: Sitecore stability issues when using Azure Web Apps

It talks about dynamic cache- WEBSITE_DYNAMIC_CACHE

FCN Cause and Effect
Now this file change notification itself is a problem which as ripple effect on few things. This is how it works.
Chain and sequences of events due to FCN- Filewatcher/File change notification
  1. File change notification, filewatcher notification triggers
  2. Sitecore shut down
  3. Solr or lucene Indexing lookup failed. Empty Index found.
  4. Session State, if sql , Redis or Mongo used: Failure of session state, results in session leaks and session_end events, and all other subsequent calls.
  5. XDb: Analytics current tracking failed or current tracking is null
  6. Eventually spike in CPU utilization and memory leaks.

How it goes?

FCN Cause -> Affected--> Sitecore shut down-> Session --> Indexing--> Analytics-> CPU utilization--> Memory Leaks

It is very important to understand how we approach to the problem and how we look up error logs. It is not that straight forward instead need problem occurrence chart[Fish bone technique to lay down the cause and effect] to note down each events. In fact I see this as solving mystery or identify suspects. Like above chain of sequence. As rule of thumb memory leaks and CPU utilization always leads you to bad code or DI leaks etc. I insist more lateral thinking than primitive way of identifying problem.

.Net Way Short term Workaround: Brute force Fixes

As a work-around I have added fcnMode = "Disabled" to the httpRuntime element in the web.config. The root cause remains unknown.

httpruntime fcnmode="Disabled"/

Wednesday, June 21, 2017

KeepAlive Url agent SSL Forced authentication issues and quick fix!

Table of Contents

  1. Introduction
  2. Problem Statement: Failed SSL forced Authenticatio
  3. Bit of a background
  4. Quick Fix: Sitecore SSL Keepalive UrlAgent Issue
  5. Miscellaneous Custom UrlAgent for KeepAlive


The purpose of this article is bring forward the key issues that one can come across when dealing with keepalive url. I'll not delve deep into what is Keepalive rather I'll focus on problem statement and list of references that can handy. Also I have given my way of approaching to the solution in different scenario. Maybe the solution I have provided may not stand the best recommended practice however it atleast give some foresight to deal with issues like this. The content more or less is about using https :// keepalive url when working with .net 4.5 azure webapp or environment required forced ssl.

Problem Statement: Failed SSL forced Authentication

Bit of a background

The SSL forced authentication will only arise if you have forced https for your website and http is restricted through firewall. Now if you are using .net 6.0 or higher this will work without any issue whereas .net 4.5 and lower version will not enforce TLS protocol by default.You may have to set them explicitly to map to your ssl certificate.
  • .NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
  • .NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it.
Refer this

***Poodle Attack

As per my understanding reason to do this to prevent poodle attack. Refer this for more details Security bulletin TechNet Poodle Attack

***SSL Scan

You can scan your site for poodle attack. Scan your site for poodle attack SSL Scan Test

Quick Fix: Sitecore SSL Keepalive UrlAgent Issue

Add this  Global.asax startup Or application Start method for .net 4.5 web app. This explains lot
 System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 
Add this to your web config Ip restriction to allow access to O.0.0.0 azure webapps

The above solution will solve your forced ssl authentication issue.

Sitecore support KB must eloborate and refine this one to reduce number of support request. [Check out 4th Scenario Covered]

Someone even face this for mongo integration.

Miscellaneous Custom UrlAgent for KeepAlive

If you are facing some other issues you will always have an options to create custom URLagent like this one below. I tried to create one with adding above solution. You can even create generic version to get azure host using custom solution making use of sitecore webutil. For e.g calling out of box webtil methods. for e.g GetHostIPAddress
Making use of above method we can create custom urlagent and add it to our solution.For testing purpose we reduce the interval to 2 minutes. Sitecore.config

using Sitecore.Diagnostics;
using Sitecore.Web;
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace MyProject
    public class SslUrlAgent

        private bool _logActivity = true;
        private readonly string _url;

        public bool LogActivity
                return this._logActivity;
                this._logActivity = value;

        public SslUrlAgent(string url)
            Assert.ArgumentNotNull((object)url, "url");
            this._url = url;

        public void Run()
                string fullUrl = WebUtil.GetFullUrl(this._url);
                this.LogInfo("Scheduling.UrlAgent started. Url: " + fullUrl);
                this.LogInfo("Scheduling.UrlAgent done (received: " + (object)ExecuteSSLWithCertificatePolicyWebPage(fullUrl).Length + " bytes)");
            catch (Exception ex)
                Log.Error("Exception in UrlAgent (url: " + this._url + ")", ex, (object)this);
        private bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
            // If the certificate is a valid, signed certificate, return true.
            if (error == System.Net.Security.SslPolicyErrors.None)
                return true;

            LogInfo("ICertificatePolicy: " + error.ToString());

            return false;
        private string ExecuteSSLWithCertificatePolicyWebPage(string url)
            System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
            using (WebClient webClient = new WebClient())
                // System.Net.ServicePointManager.ServerCertificateValidationCallback += (send, certificate, chain, sslPolicyErrors) => { return true; };
                // ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
                System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;                          
                return Encoding.UTF8.GetString(webClient.DownloadData(url));
        private void LogInfo(string message)
            if (!this.LogActivity)
            Log.Info(message, (object)this);

Some useful webutil method for reference. I used dotPeek to get the implementation of these method.
    public static string GetFullUrl(string url)
      Assert.ArgumentNotNull((object) url, "url");
      return WebUtil.GetFullUrl(url, WebUtil.GetServerUrl());

    public static string GetFullUrl(string url, string serverUrl)
      Assert.ArgumentNotNull((object) url, "url");
      Assert.ArgumentNotNull((object) serverUrl, "serverUrl");
      if (url.IndexOf("://", StringComparison.InvariantCulture) < 0)
        return FileUtil.MakePath(serverUrl, url, '/');
      return url;

    public static string GetHostIPAddress()
      HttpContext current = HttpContext.Current;
        if (current != null)
          if (current.Request != null)
            Uri url = current.Request.Url;
            if (url.HostNameType == UriHostNameType.Dns)
              IPHostEntry hostEntry = Dns.GetHostEntry(url.Host);
              if (hostEntry.AddressList.Length >= 0)
                return hostEntry.AddressList[0].ToString();
      catch (SocketException ex)
        Log.SingleWarn(string.Format("Cannot resolve the IP address of the web server with the specified hostname: {0}.", (object) current.Request.Url.Host), (object) typeof (WebUtil));
      return string.Empty;

    public static string GetHostName()
      HttpContext current = HttpContext.Current;
      if (current != null && current.Request != null)
        return current.Request.Url.Host;
      return string.Empty;

    public static string GetIISName()
      HttpServerUtility server = WebUtil.GetServer();
      if (server != null)
        return SecurityUtil.ComputeHash(server.MapPath("/"));
      return string.Empty;

With above implementation if you have any webproxy issue or anything you can try to resolve using custom urlagent approach as given above. Hope this article help you to some extend. Thanks.

Monday, May 1, 2017

Domain Name Service Cheat Sheet

Domain Name Service

First look for domain name to IP mapping is done through Host file and if not exist it look up in server domain cache. If the mapping is not available in host and aswell as in DNS cache it will eventually look up into DNS server.
  1. Host- This is host file C:\Windows\System32\drivers\etc\hosts
  2. DNS Cache
  3. DNS Server

DNS Attribute
Flush DNS Cache
Display DNS Details
Forward DNS Lookup
Internet domain name to find an IP address
Reverse DNS Lookup
Internet IP address to find a domain name.
Root Hint

Authorative DNS Response
Contains Address reference in Enterprise DNS server
Non Authorative DNS Response
Available either in non enterprise root dns server
Cache DNS Path
To intercept all network protocal
Addr (inverse address)
Translate IP address to a hostname
PTR-record Reverse DNS
Translaate Hostnmae to IP address
Cname - Canonical Name
The ALIAS record maps a name to another name, but in turns it can coexist with other records on that name
Load balancing
Netmasking Ordering
Identify default gateway Ip and subnet of incoming request and based on zone/Subnet it allows the access to server.
Round Robin
Based on availability and if server is not busy it will access and route request to the given server
Fully Qualified Domain Name
DNS Resolution

Thursday, April 20, 2017

Rules Based Engine using Tuples

Dynamic Rules Defined Using Tuple

  1. Input: Define Rules Case Conditions
  2. Output :Define Results based on Rules case conditions


    class Program
        static void Main(string[] args)
            var options = GenerateRulesBasedResults(true, false, false, false, true);
            foreach (var option in options)
                Console.WriteLine (option.ToString());
                /* Ford
                 * BMW
                 * Mercedes
        public static List<CarSale> GenerateRulesBasedResults(bool isCruiseControl, bool isAutomatic, 
                                                               bool isUnderWarranty, bool isOnSale, bool isOnRoadOffSale)
            List<CarSale> options;
            Results.TryGetValue(Tuple.Create(isCruiseControl, isAutomatic, isUnderWarranty, isOnSale, isOnRoadOffSale), out options);
            return options;

        //I/P Rule Case Condition variant
        private static readonly Tuple<bool, bool, bool, bool, bool> RuleCaseCondition1 = Tuple.Create(true, false, false, false, true);
        private static readonly Tuple<bool, bool, bool, bool, bool> RuleCaseCondition2 = Tuple.Create(false, true, false, false, true);       

        //O/P Rule based results.
        private static readonly Dictionary<Tuple<bool, bool, bool, bool, bool>, List<CarSale>> Results =
            new Dictionary<Tuple<bool, bool, bool, bool, bool>, List<CarSale>>
                { RuleCaseCondition1, new List<CarSale> {   CarSale.Ford , CarSale.BMW, CarSale.Mecedes} },

                { RuleCaseCondition2, new List<CarSale> {   CarSale.Suzuki , CarSale.Mazda} },

        public enum CarSale



Tuesday, April 11, 2017

Sitecore MVC best practice Avoid Multiple types were found that match the controller


Pre- production cleanup and performance improvement. In terms of security and performance optimization, sitecore logs, iis logs, http sys logs or event logs are best place to look upon. It give detailed behavour of application in terms of errors, redundant calls and other user specific details that are security threats. Having said that keeping production environment clean is good for application overall health. Below is the one of the example that we may ignore. This can be viewed in event logs mostly.

Event Log

Multiple types were found that match the controller named 'Authentication'. This can happen if the route that services this request ('sitecore/shell/api/sitecore/{controller}/{action}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter. The request for 'Authentication' has found the following matching controllers: Sitecore.Controllers.AuthenticationController My.MVC.Areas.MyAPI.Controllers.Api.AuthenticationController at System.Web.Mvc.DefaultControllerFactory.GetControllerTypeWithinNamespaces(RouteBase route, String controllerName, HashSet`1 namespaces) at System.Web.Mvc.DefaultControllerFactory.GetControllerType(RequestContext requestContext, String controllerName) at System.Web.Mvc.DefaultControllerFactory.System.Web.Mvc.IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at Sitecore.Mvc.Controllers.SitecoreControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, String controllerName) at System.Web.Mvc.MvcRouteHandler.GetSessionStateBehavior(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.GetHttpHandler(RequestContext requestContext) at System.Web.Mvc.MvcRouteHandler.System.Web.Routing.IRouteHandler.GetHttpHandler(RequestContext requestContext) at Sitecore.Mvc.Routing.RouteHandlerWrapper.GetHttpHandler(RequestContext requestContext) at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


Never use sitecore or .net intrinsic names for controller

Sunday, April 9, 2017

Add Sitecore AD Membership Provider at runtime

Before you refer this blog, refer this blogpost

I have taken more generic approach to add this. I have refined the above method with c# generic constraint.

Things to be taken care.      

We cannot use below Providers add due: Exception Details: System.NotSupportedException: Collection is read-only.

Therefore we should use utility class that give extension method AddTo.

Generic Membership Provider

 public static void InitialiseProviders <T>(T provider, string providerName, NameValueCollection providerConfiguration) where T : MembershipProvider
            provider.Initialize(providerName, providerConfiguration);
            //We cannot use below Providers add due: Exception Details: System.NotSupportedException: Collection is read-only.

Utility Extension Method

public static class ProviderUtil
    static private FieldInfo providerCollectionReadOnlyField;

    static ProviderUtil()
        Type t = typeof(ProviderCollection);
        providerCollectionReadOnlyField = t.GetField("_ReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);

    static public void AddTo(this ProviderBase provider, ProviderCollection pc)
        bool prevValue = (bool)providerCollectionReadOnlyField.GetValue(pc);
        if (prevValue)
            providerCollectionReadOnlyField.SetValue(pc, false);


        if (prevValue)
            providerCollectionReadOnlyField.SetValue(pc, true);

Initialize the LDap AD Configuration and call the generic method

 public static NameValueCollection LdapSitecoreProviderConfiguration
            get {

                 NameValueCollection config = new NameValueCollection();                                 
                 config["type"] = "LightLDAP.SitecoreADMembershipProvider";
                 config["name"] = "SomeProviderName";

                 config["connectionStringName"] = "LDAPConnString";
                 config["applicationName"] = "sitecore";
                 config["connectionUsername"] = ConfigurationManager.AppSettings["AppSettingKeys-UserName"];
                 config["connectionPassword"] = ConfigurationManager.AppSettings["AppSettingKeys-Password"];
                 config["minRequiredPasswordLength"] = "1";
                 config["minRequiredNonalphanumericCharacters"] = "0";
                 config["requiresQuestionAndAnswer"] = "false";
                 config["requiresUniqueEmail"] = "false";
                 config["connectionProtection"] = "secure";
                 config["attributeMapUsername"] = "sAMAccountName";
                 config["enableSearchMethods"] = "true";
                 config["customFilter"] = "(memberOf=Your org custom filter)";
                 return config;
InitialiseProviders(new SitecoreADMembershipProvider(), "someldapName", xyz.LdapSitecoreProviderConfiguration);

Saturday, April 1, 2017

Devops- VSO and Git!

Azure :Continuous Delivery Preview

Donovan Brown Channel 9 Session

Devops Systematic Integration 
  • Build -CI 
  • Deploy Release -CD
Helped me create first end to end devops CI and CD pipeline using continuous delivery preview.

I face one issue with nuget restore and it is because of this error causing constant issue.
After configuring continuous delivery with resource group and app service plan. It asks for repository and setup build and release pipeline by itself. In fact zero configuration.

Options : Multiple configuration To queue parallel build on different agents

Even you can apply above magic directly from powershell script.

Create New: Yo team

Update existing CI and CD:Yo team/pipeline

Build Agents

  • No physical controller
  • Work side by side with XAML
  • Agents are XCOPY deployed and auto updated from server
  • Agent pool and collection assign to machine Agent

Gear Icon

Important Information
  • Download agents
  • Unblock the folder
  • Run ConfigureAgent.Ps1
  • Copy Team foundation server url
  • Give working folder name
  • Run as window service or interactive mode

  • Agent Capability in relation with Build General Tab -> Demand.
  • Demand can be used to run build on Premise agent or cloud agent.

Monday, March 27, 2017

Solr Basic Authentication : Secure through key vault

If you are using key vault and you want to secure solr basic authentication credential, it is good practice to fetch it from appsettings which will retrieve from key vault server for specific environment at runtime. In order to do that you may have to configure solr configuration programmatically. Below is the useful sitecore stackexchange link that can come handy.

namespace MyClassLibrary
  public class MyBasicAuthHttpWebRequestFactory : IHttpWebRequestFactory

    public MyBasicAuthHttpWebRequestFactory(string username, string password)
      this.username = ConfigurationManager.AppSettings["username"];
      this.password = ConfigurationManager.AppSettings["password"];

    public IHttpWebRequest Create(string url)
      return this.Create(new Uri(url));

    public IHttpWebRequest Create(Uri url)
      HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
      string base64String = Convert.ToBase64String(Encoding.ASCII.GetBytes(this.username + ":" + this.password));
      request.Headers.Add("Authorization", "Basic " + base64String);
      return (IHttpWebRequest) new HttpWebRequestAdapter(request);

Tuesday, March 21, 2017

Devops Cheat sheet

Try new Continuous Delivery Preview:

Scan your build with Whitesource for open source code base.


Release Pipeline: 


Set Pre-approval or post approval before someone deploy the release into test or prod.

Sitecore Active Directory:SitecoreADMembershipProvider Initialize and add provider at runtime in application_start

Key : Know and how

These are the following set of queries may be asked once we able to roll out , design or implement sitecore ldap module.

  • Whether Membership, role or profile provider required. Choose wisely, if membership is required just use that. 
  • The project requirement might be to use sitecore custom or out box role so active directory ldap role might not be worth to include.
  • Ensure you don't allow admin to action delete , edit of active directory users from sitecore. This may have implications. The rational: There could be service account or group created for content author and administrator user will be different from centralized security team. Let one team handle the removal of users from active directory server rather handle through sitecore.(Ensure you give read only permission to service account that is created in active directory server) This will allow one direction add and delete of users. This will help avoid accidental deletion from sitecore.
  • Understand Role and profile provider does not support SSL whereas membership support SSL only when it is trusted and known. (Need to explore more.) Therefore sometimes port 636 will not accept ssl certificate however sign and seal options are available with port 389 check ConnectionProtection attribute of LightLdap SitecoreAdMembership membership provider., the LDAPS connection should use a certificate which is properly validated by a Root CA:
  • This should be validated as per environment ‘sign-and-seal’ only works if the client (Web App VM) is on the same domain as the Server (AD Domain Controller) .Check below article web post by microsoft.
  • Consider credentials to be stored in key vault for azure environment. Downside the ldap membership provider of sitecore stores it in custom configuration unlike connectionstring or appsettings. For this to overcome you have to configure and initialize the sitecore membership provider at runtime in Application_start. I have given some reference code block to help you get around this.

Anton Jason, Has helped me with below solution reference. Later it helped me integrate this further.

Remember to add reference LightLdap.dll

public class ApplicationStartup
        public static void Startup()

        public virtual void Process(object args)
                SitecoreADMembershipProvider provider = new SitecoreADMembershipProvider();
                NameValueCollection config = new NameValueCollection();
                SitecoreADMembershipProvider provider = new SitecoreADMembershipProvider();
                 NameValueCollection config = new NameValueCollection();
                 // Configure your provider here. 
                 config["type"] = "LightLDAP.SitecoreADMembershipProvider";
                 config["name"] = "SomeProviderName";
                 config["connectionStringName"] = "LDAPConnString";
                 config["applicationName"] = "sitecore";
                 config["connectionUsername"] = ConfigurationManager.AppSettings["AppSettingKeys-UserName"];
                 config["connectionPassword"] = ConfigurationManager.AppSettings["AppSettingKeys-Password"];
                 config["minRequiredPasswordLength"] = "1";
                 config["minRequiredNonalphanumericCharacters"] = "0";
                 config["requiresQuestionAndAnswer"] = "false";
                 config["requiresUniqueEmail"] = "false";
                 config["connectionProtection"] = "secure";
                 config["attributeMapUsername"] = "sAMAccountName";
                 config["enableSearchMethods"] = "true";
                 config["customFilter"] = "(memberOf=Your org custom filter)";
                 provider.Initialize("SomeProviderName", config);

I used jetbrains dotpeek to look into sitecore LightLdap and it helped me understand how sitecore has created a custom wrapper
to implement its membership, role and profile.

Remember one thing there is struct MembershipProviderSettings which has all the above configuration defined.
This is protected if you planning to extend create custom class and inherit SitecoreADMembership provider. This is the only way out.

namespace LightLDAP
  public class SitecoreADMembershipProvider : MembershipProvider
    protected bool initialized;
    protected MembershipProviderSettings settings;
    protected PartialDataSource source;

    public override string ApplicationName { get; set; }

    public SitecoreADMembershipProvider()
      : this((IAdMembershipProvider) new AdMembershipProvider())

    public SitecoreADMembershipProvider(IAdMembershipProvider innerProvider)
      this.InnerProvider = innerProvider;
      this.settings = new MembershipProviderSettings();

    public override void Initialize(string name, NameValueCollection config)
        this.ApplicationName = config["applicationName"];
          bool isInnerFailed = false;
            this.InnerProvider.Initialize(name, config);
          catch (Exception ex)
            isInnerFailed = true;
            this.settings.InitializeHidden(this.InnerProvider, isInnerFailed);
            this.source = DataStorageContainer.GetPartialSource(this.settings.AdsPath, this.settings.UserName, this.settings.Password, this.settings.AttributeMapUsername, this.settings.UseNotification);
            this.initialized = true;
          catch (Exception ex)
          base.Initialize(name, config);
        catch (Exception ex)
          Log.Error("The AD membership provider couldn't be initialized: " + ex.Message, ex, (object) this);
      catch (Exception ex)
        Log.Error("AD:", ex, (object) this);