Home » Commands » Build a Custom Command in Sitecore PowerShell Extensions

Build a Custom Command in Sitecore PowerShell Extensions

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

In my Sitecore PowerShell Extensions presentation at the Sitecore User Group Conference 2014, I showed the audience how easy it is to build custom commands for Sitecore PowerShell Extensions, and thought it would be a good idea to distill what I had shown into a blog post for future reference. This blog post embodies that endeavor.

During my presentation, I shared an example of using the template method pattern for two commands using the following base class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;

using Sitecore.Data.Items;

using Cognifide.PowerShell.PowerShellIntegrations.Commandlets;

namespace Sitecore.Sandbox.SPE.Commandlets.Data
{
    public abstract class EditItemCommand : BaseCommand
    {
        protected override void ProcessRecord()
        {
            ProcessItem(Item);
            if (!Recurse.IsPresent)
            {
                return;
            }
            
            ProcessItems(Item.Children, true);
        }

        private void ProcessItems(IEnumerable<Item> items, bool recursive)
        {
            foreach (Item item in items)
            {
                ProcessItem(item);
                if (recursive && item.Children.Any())
                {
                    ProcessItems(item.Children, recursive);
                }
            }
        }

        private void ProcessItem(Item item)
        {
            item.Editing.BeginEdit();
            try
            {
                EditItem(item);
                item.Editing.EndEdit();
            }
            catch (Exception exception)
            {
                item.Editing.CancelEdit();
                throw exception;
            }

            WriteItem(item);
        }

        protected abstract void EditItem(Item item);

        [Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
        public Item Item { get; set; }

        [Parameter]
        public SwitchParameter Recurse { get; set; }
    }
}

The class above defines the basic algorithm for editing an Item — the editing part occurs in the EditItem() method which must be defined by subclasses — and all of its descendants when the Recurse switch is supplied to the command. When the Recursive switch is supplied, recursion is employed to process all descendants of the Item once editing of the supplied Item is complete.

The following subclass of the EditItemCommand class above protects a supplied Item in its implementation of the EditItem() method:

using System;
using System.Management.Automation;

using Sitecore.Data.Items;

namespace Sitecore.Sandbox.SPE.Commandlets.Data
{
    [OutputType(new Type[] { typeof(Sitecore.Data.Items.Item) }), Cmdlet("Protect", "Item")]
    public class ProtectItemCommand : EditItemCommand
    {
        protected override void EditItem(Item item)
        {
            item.Appearance.ReadOnly = true;
        }
    }
}

Conversely, the following subclass of the EditItemCommand class unprotects the passed Item in its EditItem() method implementation:

using System;
using System.Management.Automation;

using Sitecore.Data.Items;

namespace Sitecore.Sandbox.SPE.Commandlets.Data
{
    [OutputType(new Type[] { typeof(Sitecore.Data.Items.Item) }), Cmdlet("Unprotect", "Item")]
    public class UnprotectItemCommand : EditItemCommand
    {
        protected override void EditItem(Item item)
        {
            item.Appearance.ReadOnly = false;
        }
    }
}

The verb and noun for each command is defined in the Cmdlet class attribute set on each command class declaration.

I then registered all of the above in Sitecore using the following configuration file:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <powershell>
      <commandlets>
            <add Name="Sitecore Sandbox Commandlets" type="*, Sitecore.Sandbox" />
      </commandlets>
    </powershell>
  </sitecore>                                                                                    
</configuration>

Since everything looks copacetic — you got to love a developer’s optimism 😉 — I built and deployed all of the above to my Sitecore instance.

Let’s take this for a spin!

I selected my home Item knowing it is not protected:

not-protected-home

I then looked to see if it had an unprotected descendant, and found the following item:

not-protected-page-three

I then ran a script on the home Item using our new command to protect an item, and supplied the Recurse switch to protect all descendants:

protect-item-command-powershell-ise

As you can see, the home Item is now protected:

protected-home

Its descendant is also protected:

protected-page-three

Let’s now unprotect them. I ran a script on the home Item using our new command to unprotect an item, and supplied the Recurse switch to process all descendants:

unprotect-item-command-powershell-ise

As you can see, the home Item is now unprotected again:

not-protected-again-home

Its descendant is also unprotected:

not-protected-again-page-three

If you have any thoughts or ideas around improving anything you’ve seen in this post, or have other ideas for commands that should be included in Sitecore PowerShell Extensions, please drop a comment.

I would also like to point out that I had written a previous blog post on creating a custom command in Sitecore PowerShell Extensions. You might want to go check that out as well.

Until next time, have a scriptastic day! 🙂


6 Comments

  1. gorhal says:

    I really like how you use the Template method pattern. It’s beautiful.

  2. Love the article as always! Thanks Mike – the fact you’re enjoying it and having you as part of the PSE group, means A LOT!

  3. […] Build a custom command in Sitecore PowerShell Extensions – similar tutorial from Mike. […]

Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.