Experience Sitecore ! | All posts tagged 'PowerShell'

Experience Sitecore !

More than 200 articles about the best DXP by Martin Miles

Sitecore 9 is out there

So, finally, what we all have been waiting for, has happened - Sitecore 9 has been announced and released. To be honest, as an MVP, I already have had an access to a beta of the version 9 of Sitecore since late July. but after an official release, we now can publically talk about that.

So, what has been new:

Runtime for Sitecore 9 is .NET Framework 4.6.2 and most of Sitecore 9 NuGet libraries are built against that version of the framework.

The installation process is the first you meet when trying to play with the platform. And it's worth saying that installation process has been totally reworked. So, welcome Sitecore Install Framework - Powershell modules for install and uninstall and a set of JSON config files that store steps for installing Sitecore. Each of these JSON files relies on a part of installation: xConnect, Solr and Sitecore itself. No SIM support (yet) available, unfortunately.

I mentioned xConnect - that is a new component and probably the largest architectural change for the platform - a framework that allows you to read and write analytics data to xDB and search providers, keeping collections, processing, search (Solr) and reporting behind itself. Previously we have had 4 different APIs used to deal with xDB contact, depending on its state, so that entire method full of if /else clauses looked monstrous. Since now we do not do direct xDB calls and operate using XConnectClient. That allows updating contacts from any channel at any time and automatic indexing of data. Sitecore XP introduces client certificate authentication in order to communicate with xConnect server, that is a Windows service. Also, a good thing is that this framework is well documented.

SQL Server 2016 becomes the only storage for all Sitecore databases - content data, xDB, marketing, processing, reporting etc. If you are desperate to keep Mongo - nothing to worry about it is still possible to do, or you may store in the cloud with Microsoft Azure SQL or Azure DocumentDB.

Solr is now search provider by default, and it is also required for installation by Sitecore Installation Framework. Sitecore 9.0 supports version 6.6.2 and sorry not for having version 7.+ of Solr. It is commonly used to install Solr as a windows service, using nssm as the easiest.

Sitecore Services Client (SSC) has got the ability to create oData REST service and API key management for securing access to APIs, that would be good for interacting with VUE or React JS.

Those who struggled with Web Forms for Marketers module previously will enjoy new Sitecore Forms, featuring completely redesigned UX with drag and drop, easy styling, built analytics. Also, there is a multipage wizard for creating complex "split" forms. One can even create a form template and instantiate forms from it! Also, there is form and field metrics showing the corresponding performance.

One more long waited feature is Dynamic Placeholders, now built into the platform, so that it may be called as @Html.Sitecore().DynamicPlaceholder("name"/*, some optional parameters*/). In general purpose, dynamic placeholders allow the use of the same placeholder key multiple times in the same rendering and across multiple renderings in the same placeholder. We have evidenced multiple implementations, so now good to have a universal standard.

Marketing Automation tool is much better reworked. It provides a new way to create automated online campaigns in Sitecore. With a user-friendly drag-and-drop interface, Marketing Automation provides an extensible set of tools to processes contact enrollment in campaigns and activities. The Marketing Automation Engine is a stand-alone service that is responsible for enrolling contacts in plans and activities

Express Migration Tool is already familiar to us. Since version 9 that it supports upgrades to 9 from almost any legacy version of Sitecore.

Welcome, SPEAK 3, built on Angular 4, now using proper architecture. It is now reworked according to best industry standards, pulls data from Sitecore Services Client and unlike previous versions, it is item unaware. That means no more struggle with Rocks and lack of documentation. There is already a demo project you may download and rework.

What previously caused pain for both developers, administrators, DevOps was way too much complicated configuration. Sitecore is a truly flexible platform, but the flexibility has hidden cost of every flexible component being registered via configuration, boosting compiled config up to hundreds of thousands of lines. That was taken into consideration and we were given configuration Roles and Layers. Now it becomes possible to configure whether a particular setting or config node should be patched for a specific server role using role:require attribute. An instance can be in one of the following roles: ContentDelivery, ContentManagement, Processing, Reporting, Standalone. Apart from roles, there is also a different level of configuration - the also layers: Sitecore, modules, custom - simple, flexible, allows less patching. With layers one can switch off an entire layer, it can be handy for Sitecore support providing a diagnostics, to disable anything apart from Sitecore to make ensure platform itself is working well.

What is else new regarding Sitecore 9?
JSS Framework is staging. Also coming soon Sitecore Commerce 9 with a proper inventory and support for federated authentication, SXA and Azure PaaS, CRM connectors for SalesForce and Dynamics for xConnect.

PowerShell Module issue - got a NullReferenceException when trying to open PowerShell ISE

Today I downloaded the latest (v.3.1 for Sitecore 8_001) PowerShell module and decided to play around one concept I hoped to push forward. But unfortunately, as soon as I opened ISE window, I got a NullReferenceException.

I thought that could possibly be related to my Sitecore instance. Thus I have installed a new copy of Sitecore 8.0.4 using Sitecore Instance Manager. Then tried to install package at that instance and magically worked there. So, two instances with the same Sitecore version, same PowerShell module, but different results... hm-m...

Then I assumed that ISE is trying to run some default script and probably that fact for some reason causes the exception. So, what are difference between two instances? I thought that initial ISE script might be rely on home item, and the one may be hardcoded, while my first sitecore instance has several website roots, but none of them is called Home. Worth of checking that idea. Just as the quickest, I have duplicated one of my webroots within /sitecore/content node and set a copy with the name Home. And voila - it magically worked for me!

Mass update of field value for all existing items of certain template - two ways of achieving result

Given: I have multiple already existing items of a specific template across my content tree. Template has some field that I want to update with a new value for all existing items, within some node I can specify.

Use cases for that scenario are really universal - you may use that for various purposes. What comes into my head, at a first glance, is the situation when you would like to assign some template to a workflow but already have multiple existing items of that template (just to remind - setting a field value at Standard Values will apply for all new, but not existing items of that particular template). In that case you need assign a workflow to each existing item individually.

Another good example is when you have a folder with multiple items, growing in amount with time flow. Then you may decide to make a folder bucketable, but those existing items require to set a Bucketable checkbox for each existing item individually. I have described that case in one of my previous blog posts - "Understanding Buckets: adding new items to buckets correctly". So let's pick up second case and try to solve it.

Solution: So, what are possible ways of achieving that goal? Not so much of them, there are just two options.

1. Straightforward option - use C# code. With C# task may be achieved by a recursive method, that accepts an item, verifies if the one is of desired template and if yes - updates the field and does the same for all item's children if any. Here is an example of such method and example of call :

private void UpdateAllFieldsRecursively(Item parentItem, string templateName, string fieldName, string newValue)
    if (parentItem != null)
        using (new SecurityDisabler())
            foreach (Item childItem in parentItem.Children)
                if (childItem.Fields[fieldName] != null && childItem.TemplateName == templateName)
                    using (new EditContext(childItem))
                        childItem[fieldName] = newValue;

                if (childItem.HasChildren)
                    UpdateAllFieldsRecursively(childItem, templateName, fieldName, newValue);

// and below there is the call to recursive mehod
const string parentNode = "/sitecore/content";
var database = Sitecore.Context.Database;
var parentItem = database.GetItem(parentNode);

UpdateAllFieldsRecursively(parentItem, "Article", "Bucketable", "1");

The code above works out perfectly and does exactly what we want from it, however there are certain disadvantages: first of all you need to run the code in some context - call if from some existing class, for example. Second - as that is C# code - it must be re-compiled and re-deployed. And if you may need to amend small change into the code - will have to re-compile and re-deploy again. But, luckily, there is a much better and faster alternative:

2. PowerShell Module. That module integrates into the platform and offers unprecedentedly ultimate possibilities and power over Sitecore instance and databases. After installation there is PowerShell console and more advanced PowerShell ISE, where you may create and test scripts. They are executed immediately without any of prerequisites like rebuilt DLL with a code at your bin folder. So, here is a script that does exactly the same as previous C# code:

cd 'master:/sitecore/content'
Get-ChildItem -Recurse . | Where-Object { $_.TemplateName -match "Article" -and $_.Fields["Bucketable"] -ne $null } | ForEach-Object {
    $_.Fields["Bucketable"].Value = "1";

PowerShell script above does exactly the same - iterates Sitecore tree for "Article" templates, starting recursively from /sitecore/content node and if anything found - updates the filed value.

Hope this code helps!

Sitecore 8: re-indexing errors out and module installation never ends without MongoDB running

What is happening? we got a commonly met point of frustration since recent - imagine, you have just installed an instance of Sitecore 8 and are trying to install some useful modules, for example Web Forms for Marketers 8.0 or PowerShell Module. And all you get is never-ending progress box dialog.

However that occurs not only while installing a module, but also when trying to rebuild indexes via built-in Developer toolbar interface. Same story, but at least this time it tries to tell us something with View all messages section, unfortunately unsuccessfully - there are no any error messages seen once you expand this box.

Why is it happening? Going through log files made me thinking there is something with xDB, it looks like sitecore tries to perform write operation into Mongo, but is not able to do. And because Sitecore 8 is now using modern client-based SPEAK interface instead of outdated SheerUI, the back-end where in fact an error occurs is not able to notify client about that (I believe is it not yet implemented and would be fixed with future updates).

How to fix? Let's install and run MondoDB. After default windows installation, the easiest way of running Mongo would be just running its server with dbpath parameter to where DB placed. I say the easiest because there is a better alternative to run MongoDB as Windows service application, so that it will run on system start up.

So, as soon Mongo is up and running, let's test our assumption and try to re-build Lucene indexes again:

And bingo! It now works well! Hope this solution helps.