One Fewer Edit Frame

Recently I had a client that wanted an ‘enhanced’ Experience Editor. This was summarized as fewer clicks for the editors to perform their authoring. What made this request a little more challenging than normal was some of the fields which required editing where of type checkbox, date, and multi-select.

The following findings were based on Sitecore Experience Platform 8.2 update 4 and have not been tested on Sitecore XP 9, but my suspicion is that it will continue to work.

The Challenge

As most Sitecore developers know these types of complex fields cannot traditionally be displayed directly in the Experience Editor, and we usually end up leveraging some form of an Edit Frame, either custom built or via the very handy BeginEditFrame command via Glass.Mapper.

BeginEditFrame is very helpful in providing otherwise non-access to complex field types but does create the problem of several additional clicks, in my example it creates 3 clicks.

Enhanced Editing with Edit Frame

To make the above happen the code required is straight forward

@using (BeginEditFrame(Model, "Edit Frame", z => z.StickyDate,
                    z=> z.HideContactName,
                    z=> z.NewsandAnnouncementCategory))
    Click To Launch the Edit Frame


After a little spelunking into how the Experience Editor, I discovered that fields upon edit trigger a JavaScript function Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);.

The parameters for this are pulled from the hidden span fields with a class of ‘scChromeDate’ each field gets assigned. It looks something like the following

Enhanced Editing inline

To make this work we need to render the following values onto the page to support the setFieldValue method.

  • current page’s ID scrubbed of all brackets and dashes, I find the following works well Sitecore.Data.ID.Encode(PageId)
  • current language of the page being edited
  • current version of the page
  • the field’s ID scrubbed of all brackets and dashes

To get access to these values, I include them in as data-* attributes on the HTML, thus my checkbox would have the following HTML. (Note: my model uses GlassMapper)

< input id="hidcontact" class="editcheckbox" checked="checked"
   data-itemid="@Sitecore.Data.ID.Encode(Model.Id)" / >
< label for="hidcontact">Hide Contact Name< / label>

With the data available next we need to trigger the change or action associated with the item, in this sample for checkbox we want to handle the click event. So, the JavaScript would be something like this

 jQuery('.editcheckbox', namespace).click(function () {            
        var itemId = jQuery(this).attr('data-itemid');
        var itemLanguage = jQuery(this).attr('data-language');
        var itemVersion = jQuery(this).attr('data-version');
        var fieldId = jQuery(this).attr('data-fieldid');

        if (jQuery(this).prop('checked')) {
            SetNewFieldValue('1', itemId, 
        else {
            SetNewFieldValue('0', itemId,

In the above snippet, you will see that I make a call to SetNewFieldValue. This is a global function I wrote that facilitates the actual call to the Sitecore method. Having it as separate method allows the logic to be used across my site.

 function SetNewFieldValue(newFieldValue, itemId, itemLanguage, itemVersion, fieldId) {
  //Create the JS Item Uri Object...the last parameter is a revision, which we don't have easy access to so blank is passed in.
  var scItemUri = new Sitecore.ItemUri(itemId, itemLanguage, itemVersion, '');
  Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);

You may have noticed that setFieldValue has a parameter called scItemUri but we are not generating this value at render via something like Sitecore.Context.Item.Uri. That is because setFieldValue is expecting a JavaScript object, which we can create via the call to Sitecore.ItemUri.

This little bit of JavaScript then allows are edit experience to become

Enhanced Editing inline

Bonus – Information For the multi-select

At base of any multi-select type field is a simple pipe-delimited string of item GUIDs. This simplicity of data storage means we can leverage our SetNewFieldValue method, by simplify passing in a newly generated pipe-delimited string of selected items.

The following is useful for very small multi-select list, such as for taxonomy usage, but has the possibility of significantly effecting the performance of the Experience Editor, so be smart about how you apply the following.

To make this happen, within in the associated controller for the rendering we load up all the items normally associated to the pick list in some sort of Name-Value pair, collecting the name and ID of each item. As part of this you’ll also need to indicate what values are currently selected…my code looks like this and leverages a custom object for the name-value pair.

//C# Controller code
//Setup Category Lists
viewmodel.CategoriesListEditing = new List();
var allCategories = Sitecore.Context.Database
.SelectItems(Sitecore.Context.Site.RootPath + "/Content Taxonomy[@@templateid='{30D58A48-789D-49D2-BBEE-360E5DB10A68}']/*").ToList();
if (allCategories.Any())
   var hasCategories = viewmodel.NewsandAnnouncementCategory != null && viewmodel.NewsandAnnouncementCategory.Any();
   foreach (var cat in allCategories)
      viewmodel.CategoriesListEditing.Add(new NameValuePairObject(
       !hasCategories?false: viewmodel.NewsandAnnouncementCategory.Any(cv => cv == cat.ID.ToGuid())));

This is rendered out into a checkbox list, whenever a box is clicked this trigger the following method.

jQuery('.newscatcheckbox', namespace).click(function () {
    var itemId = jQuery(this).attr('data-itemid');
    var itemLanguage = jQuery(this).attr('data-language');
    var itemVersion = jQuery(this).attr('data-version');
    var fieldId = jQuery(this).attr('data-fieldid');

    var idList = "";
    //Get all checkboxes and determine if the item is selected
    jQuery('.newscatcheckbox', namespace).each(function (index) {
        if (jQuery(this).prop('checked')) {
            if (idList !== '') idList += '|';
            idList += jQuery(this).attr("id");
    SetNewFieldValue(idList, itemId, itemLanguage, itemVersion, fieldId);


That’s all it took to enhancing the Experience Editor one step further for your authors. Let me know if you try this out or have other suggestions that could be leveraged in enhancing the Experience Editor.


PDF iFilter and Sitecore Search

Over the past week I’ve seen a similar issue arise in two separate channels around PDF iFilter setup for Sitecore indexing. Once was over on the Sitecore Slack Channel while the second was around the Paragon office.

The Error

The errors experienced where similar dealing with a ‘could not compute value for the _content field.’ ending in a System.Runtime.InteropService.COMException. Here’s the error messages for the bots:

ManagedPoolThread #5 15:59:33 ERROR Could not compute value for ComputedIndexField: _content for indexable: sitecore://master/{BA9C8FA0-B9BC-43A2-8CF9-9B6B4139E6BE}?lang=en&ver=1
 Exception: System.Runtime.InteropServices.COMException
 Message: Exception from HRESULT: 0x80048605
 Source: Sitecore.ContentSearch
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.IPersistStream.Load(IStream stream)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterLoader.InitializeFilterAsPersistStream(IFilter filter, String fileName)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterLoader.LoadAndInitIFilter(String fileName, String extension)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterReader..ctor(String fileName)
 at Sitecore.ContentSearch.ComputedFields.MediaItemIFilterTextExtractor.ComputeFieldValue(IIndexable indexable)
 at Sitecore.ContentSearch.ComputedFields.MediaItemContentExtractor.ComputeFieldValue(IIndexable indexable)
 at Sitecore.ContentSearch.LuceneProvider.LuceneDocumentBuilder.AddComputedIndexFields()
ManagedPoolThread #10 09:26:31 WARN Could not compute value for ComputedIndexField: _content for indexable: sitecore://web/{3F5EDAB1-805D-470F-A3B6-C326B9F118E5}?lang=en&ver=1
 Exception: System.Runtime.InteropServices.COMException
 Message: Error HRESULT E_FAIL has been returned from a call to a COM component.
 Source: mscorlib
 at System.Runtime.InteropServices.ComTypes.IPersistFile.Load(String pszFileName, Int32 dwMode)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterLoader.InitializeFilterAsPersistFile(IFilter filter, String fileName)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterLoader.LoadAndInitIFilter(String fileName, String extension)
 at Sitecore.ContentSearch.Extracters.IFilterTextExtraction.FilterReader..ctor(String fileName)
 at Sitecore.ContentSearch.ComputedFields.MediaItemIFilterTextExtractor.ComputeFieldValue(IIndexable indexable)
 at Sitecore.ContentSearch.ComputedFields.MediaItemContentExtractor.ComputeFieldValue(IIndexable indexable)
 at Sitecore.ContentSearch.SolrProvider.SolrDocumentBuilder.AddComputedIndexField(IComputedIndexField computedIndexField, ParallelLoopState parallelLoopState, ConcurrentQueue`1 exceptions)

The Solution

It seems there are at least two potential fixes in correcting the COMException.

First, confirm the iFilter assemblies have been installed (or copied) to C:\Windows\System32\inetsrv. Then restart IIS and kick-off an index of your Media Library.

If this doesn’t resolve the problem you most likely need to install version 11 or higher of the PDF iFilter from Adobe

General Help – PDF iFilter Setup

When starting to setup PDF iFilters to support search scenarios, most of us have landed on the following Sitecore Document page, Index PDF files.

As of time of writing, the recommended version 9 of the iFilter does not seem to be properly indexing for users causing COM Exceptions to be seen in the log based on documented issues with version 9 on Windows 8 , I recommend and have had success running version 11 of the iFilter.


  1. Download version 11 or higher of the PDF iFilter from Adobe at
  2. Run the install on the server (or local machine)
  3. Copy all assemblies from “C:\Program Files\Adobe\Adobe PDF iFilter 11 for 64-bit platforms\bin” to “C:\Windows\System32\inetsrv
  4. Restart IIS
  5. Kick-off your re-index of PDFs

Experience Sitecore XP


There has been a spattering of blogs out there walking through the installation and setup of Sitecore 9. My series has not deviated much beyond many of these. But I feel if I can write about it, explain it, then can claim a certain level of proficiency.

This is the last in the Sitecore Experience Platform install series and at the end of this you should be up and running.

Basic Terminology

As with any new version there is some updated/new terminology used to describe Sitecore and the different elements used for it.

Sitecore is divided into two distinct product areas.

  • Sitecore Experience Management (XM) – the content management and personalization features.
  • Sitecore Experience Platform (XP) – the content management, personalization, marketing and analytics features.

The Sitecore Experience Platform is divided into many logical areas:

  • Sitecore Experience Database (xDB) – where all experience data of the contact is stored.
  • xConnect – an independent service layer that connects the xDB to Experience Applications and allows other channels to add data to the xDB.
  • Experience Applications – with applications such as List Manager, Campaign Manager, FXM, and Experience Analytics.
  • Experience content management – with applications such as the Experience Editor and Experience Explorer
  • Sitecore Installation Framework (SIF) – to PowerShell and JSON based framework for installing Sitecore 9

Topology Options

To better manage the design of a Sitecore installation, there is now better detailed information on the types topology one might use with Sitecore

  • XP0 (XP Single) – Meant for development and testing scenarios. Sitecore Experience Platform is installed as two instances, Sitecore (content management) and xConnect
  • XM1 (XM Scaled) – Installs only the Sitecore Experience Manager elements for Content Delivery and Content Management roles. No xConnect or xDB is installed in this topology.
  • XP1 (XP Scaled) – Performs an installation of the full stack of Sitecore Experience Platform, allowing for each role to be assigned to specific servers.

Environment Needs

The Procedure

This will follow the steps I used to install an XP0 on my local machine for development. This will generate the following for us:

  • The Sitecore stand-alone website that handles content management, content delivery, reporting, and processing.
  • The xConnect and xDB web services.
  • Search indexes on the Solr search engine.
  • A Windows service that runs the Marketing Automation engine.
  • A Windows service that runs the xConnect indexer.
  • The Sitecore content and xDB databases.
  • A self-signed client certificate for secure communication between Sitecore and xConnect.
  • A self-signed server certificate for running HTTPS on the xConnect and xDB web services.

Getting the Basics Ready

  1. Install Solr (a minimum and maximum of 6.6.2 is required), Solr installation does require SSL setup if you follow my instructions for Solr this will be configured for you.
  2. Install Sitecore Installation Framework (SIF), see my article name
  3. Install Sitecore Foundation, see my article name
  4. Install Web Deploy 3.6 for Hosting Servers (done via the Web Platform Installer)
  5. Install Url Rewrite 2.1 (done via the Web Platform Installer)
  6. Install Microsoft SQL Server Data-Tier Application Framework (DacFx) version 2016
  7. To support DacFx, the target SQL server needs to allow users and logins at the DB level, this can be configured/confirmed by running the following
    SQL scriptsp_configure 'contained database authentication', 1;
  8. Extract the contents of Sitecore 9.0.1 rev. 171219 (WDP XP0 packages).zip to a working directory. You should see the following
    • Sitecore 9.0.1 rev. 171219 (OnPrem)
    • Sitecore 9.0.1 rev. 171219 (OnPrem)
    • XP0 Configuration Files 9.0.1 rev
  9. Extract the contents of XP0 Configuration Files 9.0.1 rev, and you should have the following JSON configuration files:
    • sitecore-solr.json
    • sitecore-XP0.json
    • xconnect-createcert.json
    • xconnect-solr.json
    • xconnect-xp0.json

Customizing the Install Configurations

Update the parameters for each configuration file, while updating it is helpful to also include a default value for each parameter to help with future re-use as well as avoiding being prompted during the installation. (I recommend opening the parent folder in Visual Code, to easily access all the files as you work through updating them.)

NOTE: Any paths need to have the slash escaped via doubling it. ‘\’ become ‘\’.

Sitecore 9 Install - Configuration files


The first configuration file does manage is for allowing Sitecore to interact with our Solr install. There are four values of concern in this file.

Sitecore 9 Install - sitecore-solr.json

If you followed my Solr install instructions your values should be:

  1. https://sitecoresolr:8983/solr
  2. “C:\sitecoresolr\solr-6.6.2”, this is the path which the directory sever exists in.
  3. “solr-6.6.2”
  4. “coffeehousexp”


Sitecore 9 by default is meant to run as a secure application. This default secure state requires that SSL certificates are trusted and in-place at time of installation, instead of as an afterthought. On a local development machine, this means a self-signed certificate needs to be properly created and trusted.

This can easily be accomplished on a DEVELOPMENT machine via the xconnect-createcert.json file.

Sitecore 9 Install - xconnect-createcert.json

  1. Set a name for the certificate, I recommend using the same value as used for your Solr core prefixes for easy identification.
    "DefaultValue": "coffeehouse"
  2. Set the location the newly generated cert was saved, I recommend the same location as all your other install files. (Don’t forget to escape the slashes.)
    "DefaultValue": "C:\Sc9Install"
  3. Set the name of the root certificate.
    "DefaultValue": "SitecoreDevelopmentCert"


Updating sitecore-xp0.json. This file drives the main installation of Sitecore, you’ll note that there a number of items missing ‘DefaultValue’ which we want to complete to allow for easy reproduction.

Sitecore 9 Install - sitecore-xp0.json part 1

  1. Add a new default value pointing to the location of Sitecore 9.0.1 rev. 171219 (OnPrem)
    "DefaultValue": "C:\Sc9Install\Sitecore 9.0.1 rev. 171219 (WDP XP0 packages)\Sitecore 9.0.1 rev. 171219 (OnPrem)"
  2. Add a new default value pointing to your local license file.
    "DefaultValue": "C:\SitecoreVersions\license.xml"
  3. Add a default value indicating the prefix all DBs should be named with. (Hint: make this the same as the solr prefix.)
    "DefaultValue": "coffeehouse"
  4. Add a default value indicating the prefix all DBs should be named with. (Hint: make this the same as the solr prefix.)
    "DefaultValue": "coffeehouse"
  5. Name of the certificate as defined in xconnect-createcert.json, step 1.
    "DefaultValue": "coffeehouse"
  6. Enter the name of your site, for my purposes this will be ‘coffeehouse’.
    "DefaultValue": "coffeehouse"
  7. Opportunity to update that admin password (and drive you nuts during development when you change it now but forget.)
  8. and 9. are easy way to make sure all your connection strings are set accordingly.

The next segment shown of parameters continue the thread of security by allowing unique SQL users and passwords to be generated for each connection string. My only suggestion is to prefix all of these with your site name, so for future cleanup it is easy to remove.
Sitecore 9 Install - sitecore-xp0.json part 2
Sitecore 9 Install - sitecore-xp0.json part 3

In portion 4 of the parameter list we get back to values that require updating for a local environment.

Sitecore 9 Install - sitecore-xp0.json part 4

  1. Set the connection to your SQL Server Instance
    "DefaultValue": "PLW\LOCALSQL2017"
  2. If you have a custom Solr install this value you will need updated.

The final portion of the parameters deal with xConnect.

Sitecore 9 Install - sitecore-xp0.json part 5

  1. Enter the URL that will be used for xConnect connectivity.
    "DefaultValue": ""
  2. Another opportunity to make sure things are secure. (Feel free to skip over for your local setup.)


This configuration setup should mirror what was done for sitecore-solr.json.

Sitecore 9 Install - xconnect-solr.json

If you followed my Solr install instructions your values should be:

  1. https://sitecoresolr:8983/solr&#8221;
  2. “C:\sitecoresolr\solr-6.6.2”, like Sitecore-Solr.json this will point to the parent directory of Solr’s server folder.
  3. “solr-6.6.2”
  4. “coffeehousexp” (you should provide the name for your local site, this allows the same Solr instance to be used for all your Sitecore Instances, as each will be named uniquely.)


The final file to be updated is for xConnect configuration. A number of these values have been previously set as part of sitecore-xp0.json, in which case the values need to be consistent between the two files.

Sitecore 9 Install - xconnect-xp0.json - part 1

  1. Add a new default value pointing to Sitecore 9.0.1 rev. 171219 (OnPrem)
    "DefaultValue": "C:\Sc9Install\Sitecore 9.0.1 rev. 171219 (WDP XP0 packages)Sitecore 9.0.1 rev. 171219 (OnPrem)"
  2. Add a new default value pointing to your local license file.
    "DefaultValue": "C:\SitecoreVersions\license.xml"
  3. Name the XConnect instance will be installed as, make sure this is unique to this instance.
    "DefaultValue": ""
  4. Name of the certificate as defined in xconnect-createcert.json, step 1.
    "DefaultValue": ""
  5. Add a default value indicating the prefix all DBs should be named with. (Hint: make this the same as the solr prefix.)
    "DefaultValue": "coffeehouse"
  6. Add a default value indicating the prefix all DBs should be named with. (Hint: make this the same as the solr prefix.)
    "DefaultValue": "coffeehouse"
  7. Name of the certificate as defined in xconnect-createcert.json, step 1.
    "DefaultValue": ""

Sitecore 9 Install - xconnect-xp0.json - part 2

This next section deals with SQL accounts and passwords.

  1. and 2. Allow for the SQL Admin account to be setup, this will be used for DB creation and access.
  2. Set the Solr URL if it has been changed from the default setup of ‘https://sitecoresolr:8983/solr&#8217;
  3. to 7. are the different SQL User Accounts that are created, these need to match any changes made in sitecore-xp0.json.

Sitecore 9 Install - xconnect-xp0.json - part 3

The final section contains a mixture of SQL setup as well as final XConnect updates.

  1. to 4. are the different SQL User Accounts that are created, these need to match any changes made in sitecore-xp0.json.
  2. Set the connection to your SQL Server Instance
    "DefaultValue": "PLW\LOCALSQL2017"
  3. Setting the type of configuration that is to be setup for XConnect, possible options are unclear at the time, so we will leave it as is.

Finally, Time to Install

The order of installation is very important as the steps are inter-related.

  1. Open a PowerShell prompt as Admin
  2. Confirm that SIF is fully updated by running
    Update-Module SitecoreInstallFramework
  3. Change directory to the location of your config JSON files.
  4. Run
    Install-SitecoreConfiguration -Path .\configs\xconnect-createcert.json

    Sitecore 9 Install - xconnect-createcert.json - Install Output

  5. Run
    Install-SitecoreConfiguration -Path .\configs\xconnect-solr.json

    Sitecore 9 Install - xconnect-solr.json - Install Output

  6. Run
    Install-SitecoreConfiguration -Path .\configs\xconnect-xp0.json

    Sitecore 9 Install - xconnect-xp0.json - Install Output

  7. Run
    Install-SitecoreConfiguration -Path .\configs\sitecore-solr.json

    Sitecore 9 Install - sitecore-solr.json - Install Output

  8. Run
    Install-SitecoreConfiguration -Path .\configs\sitecore-XP0.json

Post-Install Sitecore Steps

After all the scripts have successfully ran it is time for a few final post steps to ensure completion.

  1. Login into the admin side of Sitecore,
  2. User the Admin password you specified in the sitecore-xp.json
  3. From the Launchpad, open Control Panel then click on Indexing Manager
  4. From the modal be sure all indexes are selected and click Rebuild.
  5. Once that completes, we will need to rebuild the Link Database. From the Control Panel click Rebuild Link Databases
  6. Select Master and Core only, and click Rebuild
  7. Next up is a deployment of the Marketing Definitions. Still in the Control Panel click Deploy marketing definitions
  8. From the shown modal make sure everything is selected and click Deploy
  9. Return to the Launchpad and open the Content Editor and perform a full site republish
  10. Open a new browser and hit your site to be welcomed by the new SC9 base site,
    Sitecore 9 Install - Homepage


Sitecore Install Framework

Sitecore Installation Framework (SIF)

This is the first in my series breaking down the installation of Sitecore Experience Platform 9. I’ve tried to chunk the required steps, allowing you to take your time moving through the installation. The serires will conclude with how I suceeded in installing everything in 15 steps.


The Sitecore Install Framework (SIF) enables users to deploy and configure a Sitecore environment using a standard configuration design that can be extended through custom PowerShell functions.

It is based on a combination of Microsoft PowerShell commands and JSON based configuration files.

Installation of SIF is provided in two flavors, a manual process and a MyGet feed based process via PowerShell.

You can find SIF at

SIF Install

As I prefer to script for repeatability and ease of sharing with my dev team, this guide will be based on installing SIF via the MyGet feed approach.

Setup PowerShell to interact with the Sitecore MyGet feed

  1. Open a PowerShell command prompt, ensure you are running it as Admin
  2. Register the connection to MyGet feed, at the prompt enter
    Register-PSRepository -Name SitecoreGallery -SourceLocation

    SIF - Register Sitecore Gallery

  3. Install the SIF module, at the prompt enter
     Install-Module SitecoreInstallFramework
  4. PowerShell will ask if untrusted scripts can be ran, enter ‘A’ and hit Enter.
    SIF - Accept Untrusted Scripts
  5. Before performing any other steps, and each time before you use the module, you will want to perform a check and update of the module via
     Update-Module SitecoreInstallFramework
  6. Confirming everything installed correctly is as easy as running the following command, at time of writing the current version is 1.1.0
    Get-Module SitecoreInstallFramework -ListAvailable

    SIF - Available Versions

You should now be ready to continue forward leveraging SIF to install and manage your Sitecore 9 Experience Cloud instance.

Sitecore MVP 2018

Sitecore Most Valuable Professional Technology Award 2018

I am very excited that Sitecore has recognized me once again as a leader in the community by awarding me the Sitecore Most Valuable Professional Techonology Awarad for 2018!


A big shout-out to all the other winners but especially my co-worker Rob Reilley, better known in the community as Sitecore Runner, for being recognized as a Sitecore Technology MVP 2018!!! Be sure to check-out his work last year and all the goodies he has planned for the upcoming year, Follow at @reillyweb and SitecoreRunner blog.

The past year I know my presences has been a little quieter due to new demands this type of honor placed on me. But this gives me reason to re-asses and hopefully better engage over the course of the new year, looking for to the new ways we take Sitecore Experience Platform to new heights!

A Master Key to Your Content

Once in a while I find myself in a situation where workflow hasn’t been completed but users have begun content entry or cleanup. Normally these users also have not been setup as site admins, but with some level of custom accesses. This causes the editors to spend time dealing with locking and unlocking items for editing. At times they’ll not even realize and they locked the item, and you start to get a trail of items edited then forgotten.

What’s an admin to do?

Without too much work you can turn-on the gutter icon for ‘Locked Items’, then drill through the tree visual identifying and jotting down what’s locked and who.

Locked Items Gutter Setting

But that’s tedious (and a bit error prone). As with all cool administrative tasks in Sitecore we are best to turn our attention to Sitecore PowerShell Extensions (SPE) in the marketplace

The SPE ships with function that gives us the ability to see and react to locked items on our site.


Step 1 – Import Function

By default the function Get-LockedChildItem is not callable. You must first ‘import’ it into your console or ISE session.

Import-Function Get-LockedChildItem

 Import-Function Get-LockedChildItem

If you don’t perform an import of the function, then you’ll receive a red error message like the following

Get-LockedChildItem : The term ‘Get-LockedChildItem’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Step 2 – Get a Report

Before performing any sort of automation on our content tree, we should always produce a report that provides some context of what may get changed. In this case we want to get a listing of all items that are locked

Get-LockedChildItem -Recurse | Show-ListView

Here we are using the ‘Recurse’ flag to walk the entire tree. The collection of items locked are then piped to the very nice Show-ListView, allowing for easy review and export.

Get-LockedChildItem as a Report

We can also run the report for specific users via the -LockedBy parameter

Get-LockedChildItem -Recurse -LockedBy 'sitecore\editor' | Show-ListView

Step 3 – Time to Free the Content

Once we understand who has what locked we can start performing some mass freeing of content with the -Unlock parameter. To unlock everything, we run

Get-LockedChildItem -Recurse -Unlock

If we want to perform some hand picking of section of the site, we can either open the console to a certain node of the tree and run the above or define the start point with -Path parameter. This will unlock all the children of the item defined by path, even providing a nice output of what was unlocked.

Get-LockedChildItem -Recurse -Unlock -Path {85E0AF8C-ED9F-4CDA-BFB2-084015E17634}
Get-LockedChildItem -Recurse -Unlock -Path /sitecore/content/Coffeehouse/Home/About-Us

Unlock for a path

Finally, if we want to unlock for a specific individual we can re-use the -LockedBy parameter,

Get-LockedChildItem -Recurse -Unlock -LockedBy 'sitecore\editor'

Not a Replacement for workflow (i.e. the Disclaimer)

Being able to execute unlocking of content on a mass scale is helpful, but this shouldn’t be the replacement for properly planned and built workflow on your site.

Load Test from the Cloud

Building a any application, but especially high traffic websites on Sitecore one of the final steps before launch is to tune ensure any caching mechanisms have been properly tuned to support the needs of the organization.

One of the difficulties my teams always have is finding a server or two or three with enough available horse power to pound on out site. Running from a simple local machine is good enough for about 2 minutes until it begins heating the entire office.

But this headache and a more reasonably temperature office exists. How did we achieve this utopian level? Through the cloud of course…Visual Studio Team Services to be specific, by the way it’s free to register and take advantage of even.

Visual Studio Team Services provides a number of different tools and services, many for free such as GIT repos, CI, team and task management. One of the services provided is the ability to run scaled load testing from the cloud. Depending on your needs, you have the opportunity to run four types of tests from VSTS, Visual Studio Test, HTTP Archive Based Test, URL Based Test, Apache jMeter Test.

Load Test Options

Two things I found great about the service is, A) I get a decent number of free testing units (called Virtual User Minutes) to perform my testing, and B) I don’t have to purchase a high level MSDN or Visual Studio license. Why? Because it supports my tool of choice Apache’s jMeter.

As easy as 1, 2, 3

I can build and even pre-test my jMeter test scenarios on my local or internal hardware to confirm it generates the proper simulated traffic. After this is as easy as 1,2,3,4..and maybe a 5th step.

  1. Login to Visual Studio Online
  2. Click over to the Load Test screen
  3. Create a new test of type jmeter from the selector
  4. Upload the jmx file representing you developed jMeter scenario
    Load Test Options
  5. Upload your jmx file that defines your test run. Note, that the name of the file is the name the test will be referenced in the other screens.
  6. Set yout number of agents, length of run, and region the test should run from.
  7. Click Run
    Load Test Setup
  8. Smile and sip your coffee as the data pours into convenient charts and table.

Not Accessible to the World, yet?

If your site is sitting behind a firewall and only has internal DNS, with some additional setup you can still leverage the power of the cloud to perform your test, Testing private/intranet applications using Cloud-based load testing.

Testing Sitecore

For testing Sitecore load check-out this pre-started jMeter test provided by Sitecore themselves One thing to note if you would also like to test out or populate out xAnalytics data you will want to disable robots detection via the following patch config. Robots detection needs disabled as the tester does not trigger page events as required by xAnalytics for identifying a ‘human’ user. (Just be sure to turn it back on before site launch.)

    Ignore requests and do not write information to the Analytics 
        database when the visitor       
        classification identifies the visitor as a robot.   
    Default: true
 -- >
<setting name="Analytics.Robots.IgnoreRobots">
    <patch:attribute name="value">false</patch:attribute>

If data still isn’t properly collecting you may also need to tweak the robot’s timeout value to allow the session to run longer.

        The ASP.NET Session Timeout for auto detected robots.
        When the automatic robot detection identifies a session as 
        being a robot, the ASP.NET Session Timeout 
        is set to this value (in minutes).  
    Default: 1  
-- >
<setting name="Analytics.Robots.SessionTimeout">
    <patch:attribute name="value">5</patch:attribute>

Its that simple, and now there is no longer any reason to avoid even basic site load tests for Sitecore or any other application.

During my exploration of leveraging this cloud based load testing I found the following links to be informative: