swiss-chocThere is a lot of new stuff in the imminent 2.0 release of the PowerShell Console for Sitecore. Some of it is fairly obvious like the improved console window, some of it not so much. The aim of the console has always be to enable Sitecore developers to extend the CMS in new exciting ways. For this to happen it had to become a mini-platform on its own. So far you could use it to add scripts to ribbons and menus, write scripted tasks and execute scripts just by launching them from a URL call.

That’s extending Sitecore with PowerShell but what about PowerShell itself?

One of the coolest features introduced in 2.0 is the ability to write your own commandlets. Sure you could always use PowerShell to do it and write commandlets in script. But then the caveat was that you had to attach such commandlets to your own scripts (or put them in the initial script that would have to execute prior to the console). Now I’m talking about writing the real commandlets, just like those that come with the PowerShell console itself. Starting from 2.0 the console does not default to only attach commandlets that come with it, but can also scan other assemblies to attach your commandlets. To add your own all you have to do is well.. write them but then… all you have to do is to use the standard Sitecore include mechanism to enable the console to find them.

Including my own commandlets into Sitecore PowerShell Console

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <powershell>
      <commandlets>
	<add type="*, Cognifide.PowerShell" name="Cognifide_PowerShell_Commandlets" />
      </commandlets>
    </powershell>
  </sitecore>
</configuration>

Where the type parameter is just a regular Sitecore type reference with a slight twist – you can use wildcards in it. So with the above example, the console will scan the Cognifide.PowerShell assembly and allow you to use all the commandlet classes that are tagged appropriately.

How to write a commandlet?


Fortunately there is a lot of documentation on that subject from both Microsoft and community a few good starters:

But overall all you need to do is to write a class that inherits from the Cmdlet class and implement one or more of the methods:

and PowerShell will take care of all of the pipeline processing, parameter handling, binding and so on, you only implement the logic you want your commandlet to perform.

If you want to make your life even easier the Sitecore Console introduces a Cognifide.PowerShell.Shell.Commands.BaseCommand class that does some of the common tasks you might want to perform like getting the CurrentDrive (Windows Drive or Sitecore Database), learning if your script context is within one of the database (master:\ etc.) IsCurrentDriveSitecore or learning the current full path CurrentPath or getting a Wildcard to verify if a name matches a user-provided wildcard GetWildcardPattern allowing you to write into pipeline only if your object matches a wildcard provided by the user WildcardFilter.

For example a commandlet that retrieves a user from Sitecore and puts it into pipeline looks like following

using System.Management.Automation;
using System;
using Sitecore.Security.Accounts;

namespace Cognifide.PowerShell.Shell.Commands
{
    [Cmdlet("Get", "User", DefaultParameterSetName = "Name")]
    public class GetUserCommand : BaseCommand
    {

        [Parameter(ValueFromPipeline = true, Position = 0)]
        public string Name { get; set; }

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

        protected override void ProcessRecord()
        {

            if (Current.IsPresent)
            {
                WriteObject(Sitecore.Context.User, false);
            }

            if (!String.IsNullOrEmpty(Name))
            {
                // from BaseCommand
                WildcardWrite(Name, UserManager.GetUsers(), user => user.Name); 
            }
            else
            {
                WriteObject(UserManager.GetUsers(),true);
            }
        }

    }
}

In this case the commandlet can be used in Powershell as a “Get-User” as defined in the Cmdlet attribute on the class while Current and Name are exposed as its parameters. This is quite cool seeing how you don’t have to do anything about Parsing or binding the arguments – PowerShell does all the plumbing for you. The Name parameter is bound to the pipeline input which means that you can feed the commandlets with multiple user names (e.g. from a CSV file) and it will turn those into User objects for its pipeline consumers.

The Current parameter in turn is interesting for other reasons – shows how to define a switch that can be checked for existense – in this case calling the commandlet like

Get-User -Current

Will add the currently logged in user ad the output of the commandlet pipeline by its mere inclusion in the command line.

Overall I would strongly encourage you to crack the PowerShell console assembly and see how the existing commandlets work and build your own based on that.

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 3.00 out of 5)
Loading...



This entry (Permalink) was posted on Tuesday, April 3rd, 2012 at 11:38 am and is filed under .Net Framework, ASP.NET, C#, PowerShell, Sitecore, Software, Software Development, Solution, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.