Monday, August 10, 2015

Install Sitecore.Ship From NuGet with PowerShell

Download from GitHub.



PowerShell To The Rescue


  1. Download Sitecore.Ship
  2. Recursively download dependent packages
  4. Install assemblies and apply config files
  5. Write to an (optional) log file

NuGet And You



Version Testing


Happy deployments!

Wednesday, July 8, 2015

Basic Tips to Prevent Solr Downtime






Java Heap


  • Xms - The minimum size of your heap
  • Xmx - The maximum heap size




Disk Cache


Secondary Cores




    • On Master
      • enable.master=true
      • enable.slave=false
    • On Slave
      • enable.master=false
      • enable.slave=true

Further Reading

Monday, July 6, 2015

PowerShell Sitecore Install Script


Download from GitHub.


Search for a Solution


Sitecore Instance Manager


Sitecore's Installer


PowerShell Script




The Solution

  • Community feedback will help me improve it

Major Features

  • Install Sitecore with or without the databases.
  • Write output to the screen and to a log file.
  • Assign recommended file system permissions on web server.
  • Create user mappings for login in SQL.
  • Install database files on any valid path or UNC
  • May specifiy a host name and port used for MongoDB
  • May supply a Solr base address
  • Choose to use SQL as a session state server
  • Many CD-hardening options



Tuesday, June 30, 2015

Unit Testing in Sitecore





Some Lessons Learned


Everybody Loves an Example

namespace MyPOCO.Tests.Data.Domain
    public class My_POCO_Tests
        public class DoesQueryStringMatchMethod

            public static DbTemplate GetMyPOCOTemplate()
                return new DbTemplate(IMy_POCOConstants.TemplateName, IMy_POCOConstants.TemplateId)
                    new DbField(IMy_POCOConstants.Query_String_Value_To_MatchFieldName, 
            public void RequestedUrlHasUpperCaseValues()
                string requestedUrl = "";
                using (var db = new Db
                    new DbItem("test", ID.NewID, IMy_POCOConstants.TemplateId)
                        {IMy_POCOConstants.Query_String_Value_To_MatchFieldName, requestedUrl}
                    My_POCO poco = home.GlassCast<My_POCO>();

                    bool result = poco.DoesQueryStringMatch(requestedUrl);




Friday, May 22, 2015

MSBuild and TDS









Some Miscellaneous Issues




    msbuild myproject.csproj /p:VisualStudioVersion=12.0.


  2. I was receiving a post-build error:



Thursday, May 21, 2015

Create a Reverse Proxy Controlled By Sitecore

Reverse proxies can be an incredibly useful technology in your Sitecore implementation depending upon your needs. The basic idea is that a reverse proxy forwards requests on to other servers on behalf of the requesting client, sort of like a traffic cop. The responses from the servers behind the reverse proxy are then returned to the requesting client. This can be done in such a way that is completely transparent to the end-user.

The Use Case

So why bother? Well, as Grant Killian suggests over on his blog at least two scenarios come to mind (I'm sure all you very smart folks could undoubtedly name more!) I want to focus on the case of a reverse proxy sitting between the Internet and a set of web servers that includes one or more legacy web servers and a Sitecore instance.

I've kept the conceptual diagram above simple (no load-balanced servers, firewalls, cache servers, etc.) but the technique readily applies to an enterprise ecosystem. The basic strategy is as follows:

  1. A user tries to browse a page (perhaps one they have bookmarked) e.g.
  2. The reverse proxy receives the request and "asks" Sitecore where to route the request
  3. Sitecore tells the reverse proxy if it can handle the request and, if so, what the URL should be.
  4. The reverse proxy rewrites the request and forwards it. For example, if Sitecore responded positively to the reverse proxy our URL might be transformed to
  5. Sitecore or the legacy server responds to the page request
  6. The reverse proxy rewrites the response so that the end-user is unaware the page they see was came from a different server than the one they contacted.

The payoff with this scenario is we can now manage incremental content migrations from legacy servers to Sitecore servers without any disruption to end-user experience. Bookmarks, campaign emails, RSS feeds, Google search result rankings....all of it will happily continue on as always regardless of whether the legacy web server or Sitecore actually answers the HTTP request. Powerful stuff! This technique is especially useful for clients that have a very large inventory of content and cannot or are unwilling to migrate everything all at once.

The Solution

The first order of business is setting up a reverse proxy in IIS. The goal is to have a dedicated web site in IIS as the reverse proxy. To do that we need to install the Application Request Routing (ARR) extension. Once ARR is installed we'll need to do perform the following configuration steps

  1. Open IIS Manager and select the server node. Double click on the Application Request Routing Cache icon.

  2. In the right-hand pane click Server Proxy Settings.

  3. Check the Enable proxy setting and uncheck the Reverse rewrite host in response headers option.

  4. Set the Response buffer and Response buffer threshold values for 8092 and then click Apply. The reason for this I discovered through the school of hard knocks: some pages were mysteriously causing YSODs. After digging through logs (more on that later) we found that the response from the server was literally truncated. The page was large enough that it was overflowing the response buffer and causing it to flush with only a part of the overall page.

Now that ARR is installed and configured at the server level we need to turn our attention to the reverse proxy site. Here is the secret sauce of our solution: rather than merely write in some rules for routing in the web.config we are going to create our own custom Rewrite Provider. This will allow us to execute our own code during the runtime of the reverse proxy. I followed this guide to develop my own custom provider; it should get you up and running.

So what does my rewrite provider do? At its heart it's just a very simple URL resolver. The provider is rather dumb (and it should be!) We want the reverse proxy to do as little processing as possible.

  1. First make a request to Sitecore to see if the requested page (rewritten with Sitecore's host header) can be served, i.e. does the web request return with a response status code < 400.
  2. If that fails, the reverse proxy contacts a web service that knows how to map a legacy URL onto a Sitecore URL. Thus a URL like /news/article.php?id=foobar in the legacy system can be mapped onto /news/articles/foobar for example.
  3. If steps 1 and 2 fail, then the request is routed to the legacy server.

You may be wondering if all of that still sounds like too much work given that every request passes through the reverse proxy. Fortunately ARR has very good built-in caching, so in practice, your most requested pages (and resources) will not be processed in code continuously.

Closing Thoughts

Beyond what's already been covered, I recommend you consider the following:

  1. You need some kind of logging strategy. I write to the event logs from the reverse proxy and Sitecore's logs during the runtime of Sitecore (for example, the URL mapping web service.)
  2. Perform load testing. ARR is remarkably good OOTB with its cache settings, but better to test and know than simply assume.
  3. Think ahead about sessions and how you will deal with them.
  4. Redundancy. Our solution uses more than one reverse proxy. As a side-note with my implementation, if Sitecore itself goes down, the reverse proxy will continue to function. All requests would simply go to the legacy server. Eventually this behavior may become undesirable, but early in a project's lifetime this can be a real selling point.
  5. You definitely need to create some outbound rewrite rules in your reverse proxy's web.config to deal with:
    1. Rewriting relative links in the response HTML
    2. Rewriting the Location in the response Header when the status code is a 3XX (a redirect) and the host name is your backend server. This will prevent the end-user's browser being redirected to rather than
  6. You should absolutely turn on Failed Request Tracing Rules. This is the logging function I discussed earlier that proved invaluable in diagnosing and resolving issues during development

Monday, April 27, 2015

SwitchMasterToWeb Woes

Scenario: You are using Sitecore 8—I think this also applies to 7.5—and have enabled the SwitchMasterToWeb.config. You now see see an exception related to 'master' database. For example:

  • Could not find configuration node: contentSearch/indexConfigurations/indexUpdateStrategies/syncMaster

Cause: Sitecore patches files found in the \Include folder first and then recursively patches all files found in sub-folders of \Include. In all cases, Sitecore follows alphabetical order when deciding which folder or file to examine next. This means that the SwitchMasterToWeb.config file placed in \Include will be merged before config files found in sub-folders. Some of those config files are for indexes and those index try to use the syncMaster strategy.

Resolution: Place the SwitchMasterToWeb.config file in a sub-folder like "zzzMustBeLast" and reload your site!

Saturday, April 25, 2015

NuGet Tip: Automatically Set 'Copy Local' Property to False

This is probably slightly off the beaten path for some of the Sitecore community, but I suspect quite a few of us use NuGet. Furthermore, of those that do, some not only consume but produce NuGet packages. One annoyance I've had is the good ol' Copy Local property of an assembly reference.

When this property is set to true, the assembly will be copied to the output directory of your project. This can be problematic. For example, with TDS, when you build your solution the output directory of your web application project gets copied to your Sitecore instance. Ideally, you don't want to overwrite or add DLLs to your Sitecore instance by accident. While you can prevent this from happening by maintaining an exclusion list in TDS, it's easy to forget.

How does this relate to NuGet packages?

Usually when you add a new package one or more DLL references are added to your project(s) and almost invariably the Copy Local property will be set to true. If you create your own NuGet package and wish to prevent this, here is a PowerShell script that will do the trick:

Simply add/overwrite the Install.ps1 script found in the "tools" folder of the NuGet package. Voila!

Friday, April 3, 2015

How to Map Sitecore Rules Field with Glass and TDS

tl;dr Copy lines 246 and 247 from here. Regenerate your Glass classes. 

Today a colleague asked how to map the rules field from Sitecore with Glass Mapper using TDS and T4 templates. It just so happens that I'd recently worked on this problem, and I thought I would share it with others here.

The basic issue is that the template doesn't know how to deal with the Rules field. The GetGlassFieldByType method is responsible for assigning a type to mapped field. It does this with a switch statement. Our rules field is falling all the way through to the default case which maps the field to an object. We need to add a case for the field.Type value when it equals "rules".

What type will we map to though? On first pass I thought something like XDocument would make a lot of sense. Problem is that doesn't work. The value is always null. I took a look inside the Glass.Mapper.Sc.dll at what I believe is the code responsible for returning a value. It looks to me like the mapping code isn't fully implemented, and Glass relies on a generic method that simply returns a string value.

Not a big deal. We can work with this.

After you've modified the T4 template and regenerated your Glass classes, you should have a mapped property on your class of type string. I've found for my purposes this is perfect for my needs, but that didn't stop me from extending my partial class with an XDocument property...just in case.

public partial class GeneratedClass
    public XDocument RuleAsXDocument
        get { return XDocument.Parse(this.Rule); }

Thursday, April 2, 2015

A SIMple Error

While installing Sitecore Instance Manager (SIM) I made a silly mistake that gave me pause. I figured I would document it here in the hope it might help someone else might benefit.

The final step in the installation wizard attempts to do a permission check. It is labeled as "File Systems permission" and, indeed, it does check this and even provides a handy "Grant" button if SIM does not have the permission it thinks it needs.

What can be a bit confusing is that even after seeing the success message above you still encounter an error dialog complaining that "You probably don't have necessary permissions set. Please try to click 'Grant' button before you proceed."

What's happening? Under the hood, SIM isn't just checking the file system, it is also trying to create a test database in SQL. If the SQL login SIM uses doesn't have the right to create a database, then SIM will fail this "file system" check with (in this specific case) a misleading error. The fix is simple, make sure your SQL login has the dbcreator role or higher. Thus my silly mistake: Of course SIM needs the ability to create databases why didn't I think of that sooner....DUH! :)

Rerun the last step and enjoy the wonders of SIM!

Saturday, March 28, 2015

On Second(ary) Thought...

Recently I posted my thoughts regarding the proper ratio of Solr cores to Sitecore indexes. In it, I mentioned the need to double the number of cores to support the SwitchOnRebuildSolrSearchIndex feature. It turns out, this isn't quite right. Creating a secondary core for the analytics index does no good and should be avoided.

You'll want to avoid a secondary core for the analytics index because trying to use one results in exception. The analytics index has an extra "group" parameter, and Sitecore cannot find a matching constructor. The SolrSearchIndex class allows for the group parameter but the SwitchOnRebuildSolrSearchIndex does not.

Why is this? As Adam Conn explains, the types of crawlers responsible for maintaining the analytics index are observers of data. This means that the crawler is notified when data is available and then passed that data. Therefore, rebuilding the analytics index would result in an empty index unless you rebuild the reporting database so that the analytics crawlers may observe (and index) the data. This is the reason why the UI doesn't provide the option of rebuilding the analytics index.

Tuesday, March 24, 2015

Solr + Glass = Castle Windsor Crashers?

(I know the title isn't technically true...don't judge me!)

I think it's safe to say most of us Sitecore developers are using some form of ORM these days, right? ...Right? :)

Of course you are, and – most likely – that means you are using Glass Mapper. Probably, you are also using Castle Windsor as your choice of Inversion of Control. You could use some other IoC, but there's a NuGet package that makes incorporating Castle Windsor + Glass into your Visual Studio solution quite easy.

So what if you read my series on Solr and were inspired to use it for Sitecore? Solr also requires an IoC. As I mentioned here, you may choose from Castle Windsor, AutoFac, Ninject, StructureMap, and Unity. It seems only natural to stick with the same IoC as Glass. Common sense says don't add more moving parts than necessary.

And this is why common sense isn't always common or sensible. The moment you deploy your Glass dependent (and thus Castle Windsor dependent) code to your Sitecore instance, you are going to be treated to some ugly YSODs. The issue is that Glass wants to use a higher version of Castle Windsor (3.2) than your Solr-enabled Sitecore instance; it wants version 3.1.

Luckily the fix is relatively painless. We are going to instruct .NET to redirect bindings of earlier versions of Castle.Core and Castle.Windsor to our later version. All you need to do is add the following section to your web.config:

Saturday, March 7, 2015

Friday, March 6, 2015

A Solr Core-nucopia?

[N.B.: If you haven't already, check out my series of posts (1, 2, and 3) that walk through installing Solr for Sitecore.]

Given that there isn't yet a search scaling guide for Sitecore 8.0, the current, best authoritative source of guidance is the Sitecore Search Scaling Guide for 7.5. There is an interesting line in the guide that recommends creating "separate cores for each Sitecore index." This was necessary to avoid inconsistent and unexpected results.

While digging through the release notes for Sitecore 8 update 1 I found a good, technical description of the risk:

When two indexes were configured to use the same SOLR core, it was impossible to differentiate the index data between the indexes. As a result, index data related in one index would override the index data in the other index. This has been fixed so that the _uniqueid index field value has been extended with information about the index name. (426743)

Out of curiosity I decided to validate the fix. Here is a query from one of my Solr cores connected to a Sitecore 8 update 2 instance (a big thumbs-up to Solr's built-in admin tool!)

Let's breakdown the taxonomy of this _uniqueid:

  1. sitecore://<database name>/<item id>?lang=<language name>&ver=<version number>&ndx=<index name>

Clearly, the index name is now a part of the key! Does this mean you can disregard the advice in the Search Scaling Guide? In a word, yes. A more important question is, "Should you?" Well, probably not. Here are some reasons why:

  1. Any single Sitecore index (Solr core) rebuild is less expensive since there is less data. Thus, the rebuild is quicker.
  2. When reviewing statistics about a core in Solr's core admin, facts about the core such as the number of documents easily translate to facts about the Sitecore index.
  3. Probably most important of all, it's possible to tune the cache and core's settings as necessary per Sitecore index. Undoubtedly, usage patterns will vary per Sitecore index. So should the strategies you implement to tune the Solr core responsible for that Sitecore index.

Update (3-8-2015): In Sitecore update 2, one Solr core was removed and two were added. I updated the paragraph below to reflect this.

Keep in mind, these advantages do come at a cost. There will be some amount of overhead incurred per core. Also, there is the management headache of maintaining many cores. As of Sitecore 8 update 2 there are 13 indexes for a vanilla install. If you want to take advantage of the SwitchOnRebuildSolrSearchIndex feature (while an index rebuilds, Sitecore can still return search results for that index) then you will need to add an additional core for each Sitecore index that uses this feature. That is a possible 26 25 (see here for an explanation why the total number changed) cores to manage!

I'm interested in other people's opinions on this topic. Let me know what you all think.

Saturday, February 28, 2015





  1. Stop the Tomcat service.
    1. Rename the folder to "sitecore_analytics_index"


    1. Copy the sitecore_analytics_index folder.
    2. Repeat steps 2a and 2b for each copy.


    1. Config files to DISABLE:

      \App_Config\Include\Sitecore.ContentSearch.Lucene.Indexes.Sharded.Core.config.example (left as is)
      \App_Config\Include\Sitecore.ContentSearch.Lucene.Indexes.Sharded.Master.config.example (left as is)
      \App_Config\Include\Sitecore.ContentSearch.Lucene.Indexes.Sharded.Web.config.example (left as is)

    2. Config files to ENABLE:



    • Castle.Facilities.SolrNetIntegration.dll
    • Microsoft.Practices.ServiceLocation.dll
    • Sitecore.ContentSearch.Linq.Solr.dll
    • Sitecore.ContentSearch.SolrProvider.CastleWindsorIntegration.dll
    • Sitecore.ContentSearch.SolrProvider.dll
    • SolrNet.dll






  15. Drink a beer; you deserve it!

Friday, February 27, 2015

Sitecore 8 + Solr (part 2/3): Install Solr

In part one of this series, I covered the installation of Tomcat. Now we are ready to get an instance of Solr up and running.

  1. Download Solr 4.10.3 from Since we are installing on a Windows machine, you will want to get the .zip file version of the download.
  2. Extract the contents of the .zip to a temporary location of your choice.
  3. Find the \dist folder in the extracted solr-4.10.3 directory. Rename the solr-4.10.3.war to solr.war and copy the file to the Tomcat’s \webapps folder. The path in my environment was C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps.
  4. Create an empty Solr home folder. This will be the permanent place of residence on your machine for your Solr instance. For example, D:\solr is where I put my Solr instance.
  5. Find the \example\solr folder in the extracted solr-4.10.3 directory. Copy the contents of \example\solr to the empty Solr home folder you just created in step 4.
  6. Find the \example\lib\ext folder in the extracted solr-4.10.3 directory. Copy the contents of \example\lib\ext to Tomcat’s \lib folder. The path in my environment was C:\Program Files\Apache Software Foundation\Tomcat 8.0\lib.
  7. Set the home directory for Solr in Tomcat. This is done by adding a new Java option with the Monitor Tomcat program. In my case, the option was -Dsolr.solr.home=D:\solr

  8. Stop/start Tomcat and try browsing to your Solr instance. For example, http://tomcat:8080/solr.

In the third and final post of this series I'll show you how to get Sitecore and your shiny, new Solr instance working together.

Thursday, February 26, 2015

Sitecore 8 + Solr (part 1/3): Install Tomcat

This is part one of a three-part series intended to guide you step-by-step through the process of making Sitecore 8 and Solr work together. There are some good resources on the Internet, but none of them are a soup-to-nuts walkthrough, and unfortunately there are many pitfalls along the way especially if you are unfamiliar with tools like Apache Tomcat or Solr -- even if you are, the current state of Sitecore's documentation for working with Solr isn't complete for Sitecore 8. I'm sure that will change soon! :)

So, in this first post our goal is to get Apache Tomcat running on a Windows machine installed as a Windows service. Onwards!

  1. Since Solr and Tomcat both require the Java Runtime Environment (JRE) to run, we'll need to start with installing the correct JRE for our machine. This guide uses jre-8u31-windows-x64.exe.
  2. Download and install the Windows Service Installer for Tomcat. This guide uses version 8.0.18 of Tomcat, but you can safely use a more recent version. There are a few decisions to make with the installation wizard. You may choose to install the Host Manager component; this will expose a host manager gui to Tomcat’s built-in administration page.

  3. The default port used by Tomcat is 8080 (used to be 8983) but you may elect to use some other port. Don’t choose port 80 unless you are prepared to tinker with IIS to re-route requests meant for Tomcat to Tomcat; it’s not really worth the effort. Nevertheless, here is a link to a helpful resource:

    If you do not supply an optional user name and password, then you will need to manually edit the conf/tomcat-users.xml file (found under the Tomcat install path) in order to manage Tomcat from the built-in administrative web site. If you do find yourself editing the tomcat-users.xml file, don’t forget to stop-restart Tomcat for those changes to take effect. You can do this with the Monitor Tomcat tool:

  4. Test the Tomcat installation by pointing your browser to http://localhost:8080 assuming that you used port 8080 as your HTTP Connector Port.

  5. By default, the Tomcat Windows service startup type is “Manual.” This means that after rebooting your machine you will need to remember to manually restart the Tomcat service. Change the Tomcat Windows Service startup to “Automatic.”

  6. As a final, optional step, you might elect to add an alias to Tomcat so that the website can be accessed using something other than localhost. For example, you could add the tag <Alias>tomcat</Alias> to the conf/server.xml file. Don't forget—if you use an alias then make sure you either update your DNS server to use that alias or edit your hosts file in Windows. :)

At this point you should have a working Tomcat installation that will be available even after a reboot of your machine. In the next post of this series we will tackle installing Solr on top of Tomcat.

Sunday, February 1, 2015

MongoDB University Course for .NET Developers

Given that MongoDB is an integral part of Sitecore's xDB architecture starting with Sitecore 7.5, it stands to reason that our clients and colleagues will look to us, the Sitecore experts, for guidance. So what can us mere mortals who aren't already NoSQL experts do to prepare ourselves? Enroll in a course taught by NoSQL experts, of course!

Now, I know what you might be thinking, "Online courses are of limited value." And, normally, I'm right there with you. The quality of the material on offer from MongoDB University is truly worth the investment of your time, however. The only catch was none of the courses on offer were tailored for .NET developers. Last year I decided to dive in anyway with the Node.js course -- it's excellent, of course -- but just recently MongoDB University has expanded their course catalog with something for us .NET folks! Be prepared to devote several hours a week, and in return you will get a solid foundation on which to build solutions ranging from CRUD, to schema design, to performance tuning and application engineering.

Solr 4.8 and Higher with Sitecore - Schema Issue Resolved

Dan Solovay has a great blog post that details how to setup Solr with Sitecore 7. One potential problem stood out though: Sitecore didn't play well with Solr 4.8.x or higher due to an assumption Sitecore made about Solr's schema.

If you, like me, read this and had reason to hesitate then I say worry not! Sitecore has provided a solution that will allow you to deploy Solr 4.8 and later to your environment. In a nutshell, the fix is to modify the Solr's schema.xml file.

From the kb article:

  1. Make the following changes in the default schema.xml file shipped with Solr:
    • enclose all <field> and <dynamicField> elements in the <fields> tag.
    • enclose all <fieldType> elements in the <types> tag.
  2. Pass the modified schema.xml file to the Build Solr Schema Wizard to add the Sitecore specific specific configuration.
  3. Put the resulting file to the configuration folder of the Solr core.
  4. If you use Solr 4.9 or later, ensure that the following field type is defined in the schema.xml file:
  5. <fieldType name="pint" class="solr.IntField"/>
  6. Reload the core to apply schema changes.