Command Line Kentico

4 Mar 2010 Global Administrator 1 comments

The key thing which makes Powershell different is that unlike most shells, which accept and return text, PowerShell is built on top of the .NET Framework, and accepts and returns .NET Framework objects. Just imagine being able to pass around native .net objects, and being able to call methods and access properties on those objects, directly from the command line.

The basic unit of work within PowerShell is the cmdlet (pronounced “command-let”), a simple, single-function command-line tool built into the shell. PowerShell includes more than one hundred of these cmdlets, giving you access to not only the file system, but to complex stores such as the registry, the IIS metabase, and digital signature certificate stores.

Over the next few issues of Kentico Developer, we will be demonstrating how you can easily expose Kentico API functionality via Powershell, by rolling your own re-usable library of Cmdlets, allowing for the command line management and automation of Kentico.

Getting Started

In order to develop your own Powershell Cmdlets you’ll need to install the Windows SDK. You won’t need to do this if you are simply looking at using Powershell, only if you are looking at developing your own cmdlets. Don’t worry, the process is relatively painless. Various flavours of the SDK can be found at http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx

You’ll also need Visual Studio and access to a Kentico database to work with while debugging.

We run Visual Studio Express Editions (Visual Studio SQL Server 2008 Express and Visual Studio C# 2008 Express) which are freely available, and this works well if you’re looking for a basic setup for the very cool price of free.

Downloads of Visual Studio Express Editions can be found at http://www.microsoft.com/exPress/

Setting up the Project

OK, so let’s get into it. First, you’ll need to create a new Class Library within Visual Studio named KenticoCmdlets.

Next you’ll need to add several required references.

A Powershell Cmdlet will require both System.Management.Automation and System.Configuration.Install.

You’ll need to browse to find System.Management.Automation. It comes with the Windows SDK and should be found under %programfiles%\Reference Assemblies\Microsoft\Windows Powershell\v1.0

You’ll find System.Configuration.Install registered as a .net library.

Pulling in the Kentico API

For Powershell to be able to work with the Kentico API, you’ll need to add references to the Kentico DLLs. I find the best way to do this is to browse to a local installation of Kentico. This will mean that right from the start, your Powershell Cmdlets will be using the same version of the DLLs that your site is using.

You can either selectively add the DLLs you know you’ll need, or if you’re just getting started and don’t yet know your way around the Kentico API, adding anything beginning with CMS is a safe bet.

Your first Cmdlet

Now that we’ve set up the project we can begin coding our first Cmdlet.

Add a new Class named GetSites to your project, and import the classes that you know you’ll need right off the bat – you can add more as you go. The image below highlights the set I typically begin with.

The next piece is important, as this is where I find most people come unstuck. Declare the Class GetSites as public, and inherit from Cmdlet. It sounds simple I know, but if things go awry, come back and check this before digging further.

Next we add code to the Cmdlet, by simply overriding ProcessRecord(). If you let intellisense fill in the blanks, it’ll prepare the code for you.

Insert your code – in this case, we’re simply calling the API function SiteInfoProvider.GetAllSites().

Notice that I’ve added a line of code though which programatically sets the database connection string. If you’re already working with Kentico, you’ll know that this is something you’d expect to find within a web.config file, or an app.config. I’ve added this because although I’m not going to do it now, I’ll add a parameter to the Cmdlet in future, which will allow you to pass a connection string from the command line.

Set the connection string to the same connection string you use in your web.config.

Finally, add the Cmdlet attribute to the GetSites class, and we’re done.

That’s it! This is now a complete Cmdlet. The next pieces are all about packaging finished Cmdlets for distribution, and configuring your debugging environment.

Adding a snapin

Think of a snapin as an installer, used to package Cmdlets for distribution. We’ll add one now by simply adding another class to the project.

In this case we will be adding a snapin for our one and only Cmdlet, but it is possible to add several related Cmdlets within a single snapin, allowing an end user to add several Cmdlets to Powershell with a single import.

Installing the class library

You should now be able to build your class library with no errors, so that it can be installed and registered with Powershell.

A Cmdlet class library is installed using InstallUtil, which you can tap into easily by starting the command shell you’ll find installed with the Windows SDK. There’s nothing funky about this command shell apart from the fact that the tools that come with the SDK are already included in the path and you won’t have to browse for them.

Windows 7 users should take note of the fact that the command shell will need to be executed in the context of an administrator so that it has the necessary permissions to make changes to your system. You can do this by right clicking on the command shell menu item and selecting Run as Administrator.

From within the command shell, navigate to the directory that your class library compiled to, and install it by invoking install –I as shown below.

Now, open Powershell – you’ll find it in the Start menus under Accessories – and check that your Cmdlets successfully installed by using the get-pssnapin Cmdlet with –registered as a parameter. This lists all installed libraries. You should see KenticoCmdlets listed.

Configuring the debugger

From within the Powershell session you still have open, import the snapin we created, by invoking the add-pssnapin Cmdlet with GetSites as a parameter.

What you’ve just done, is pull in any Cmdlets associated with the snapin, allowing them to be used form the command line.

We’re going to cheat a little though. So that you don’t have to type this every time you kick off the debugger, we’re going to export the console - an XML file which records imported snapins. Then, if we tell the debugger to use this console, the snapins will come pre-loaded.

To export the console, invoke the export-console Cmdlet passing the path of the file that will be created. Console files are saved with an extension of psc1.

Now it is simply a matter of telling Visual Studio that when debugging this particular class library we’d like it to use Powershell as the external application making the calls, and that when it starts Powershell it should use the console we just exported.

This is done by bringing up the properties of the project and clicking the debug tab. Select Start external program, and browse to the Powershell executable. Then enter –PSConsoleFile <consolefilepath.psc1> in the command line arguments.

There’s a trick to this though, in that Visual Studio Express Editions do not allow for the invoking of an external program during debugging. Thankfully, a little hack gets us around this limitation.

The settings in the debug tab are saved out to a file with the same name as the project, but with a .user extension. For example we’d be saving to a file named KenticoCmdlets.csproj.user. Since Visual Studio will not allow us to do this via the IDE, we simply have to do it via good old trusty notepad.

If a file with this name already exists, edit it. If it doesn’t, create it. The contents of the file – as it should appear - appear below.

Debugging

Now, try adding a breakpoint in the code, kicking off a debug session by hitting f5, and invoking our cmdlet from within the resulting Powershell by issuing the command get-sites. Check out the CmdletAttribute if you’re wondering why the command is get-sites.

Once you’ve confirmed that the breakpoint is hit, let it run, and take a look at the output.

What you’re seeing is a DataSet, the results of the Kentico API function SiteInfoProvider.GetAllSites(). The cool thing is that because we are using Powershell, and because Powershell works with objects, we can work with the DataSet directly as shown below.

Neatening up your results

However, an alternative way of doing things is to return Kentico SiteInfo objects, rather than rows of data, making the results easier to work with. Try exiting the debugging session, making the changes below, and once again hitting f5 to start debugging.

What you’ll find now is that you can use the following syntax which is much cleaner, easier to read, and a hell of a lot easier to write. More importantly, once you have further Cmdlets you can begin to pass the objects between these Cmdlets.

Next steps

It’s simple to begin tacking on more and more Cmdlets, adding more and more capabilities. Although each Cmdlet does very little by itself, it’s the piping capabilities of Powershell which make them so powerful.

For example, the Cmdlet we have just put together enumerates sites, returning an array of SiteInfo objects. If we were to create a simple stop-site Cmdlet and a start-site Cmdlet, we would be able to restart all of our sites using the following.

get-sites | foreach-object {
    stop-site $-
    start-site $_
}

Over the next few issues of Kentico Developer, we will be building upon what is in essence just a simple demonstration, exposing more and more of the Kentico API within Powershell, and building up more and more complex examples.

We’ll also be adding parameters to all Cmdlets, something I really wanted to include here, but that we left out due to a lcak of space and in the interests of simplicity.

The resulting class library will be made available on the Kentico marketplace, and I hope that with the input and feedback we receive we will be able to make it a very worthwhile management toolset.

Further Reading

Powershell Syntax, Tutorials, and Guidelines

Windows SDK

MSDN – Windows Powershell

Windows PowerShell Blog

Trackback URL: http://www.kenticodeveloper.com/trackback/cfd8f7aa-5b4d-4b6b-9b64-fe5b48a9bdd4/Command-Line-Kentico.aspx

Comments
Richard
I totally didn't notice the fact that I was using tiny useless screenshots online! Sorry about that. I'll upload larger versions this afternoon.
3/9/2010 12:44:14 PM

Leave comment Subscribe
Name:

E-mail:

Your URL:
Comments:

Enter security code:
 Security code