Sitecore PowerShell Console cheat sheet – Part 1

I’m realizing time and time again that the learning curve for PowerShell can be steep without a proper guidance. While most people I talk to are very excited about the concept they become discouraged after a having some tries and not realizing its full potential. Therefore I decided it’s worth spending some time introducing some basic principles to help scripting alleviate some of the initial pains.

I have gathered some literature available for free about the topic of PowerShell in general you might want to read, but I also think that a distillation of the basic concepts is really important so you can have some quick wins while you begin your PowerShell journey.

A great deal of this post is a port of my older post for similar console for EPiServer, but since the differences are significant enough to confuse Sitecore developers if I sent them to the original version, I’ve decided to create a proper Sitecore cheat sheet.   Most of this is based on the Microsoft’s Windows PowerShell Quick Reference however despite the sharing scripting runtimes the nature of the both shells are pretty different (although the differences are not as vast as one might think).

Windows PowerShell PowerShell Console for Sitecore
Interactive – command can ask for confirmations and can be aborted. User can be solicited to provide input. Batch – all commands are being executed in one go, the script has no chance to ask questions, go or no-go decisions have to be solved within the script.
Supports command line arguments for running scripts. All arguments are defined directly within the script or derived from context automatically.
Can access any file depending on the rights of the user. Can only access files the web application identity can write to. Cannot access files on user’s machine but rather operates on the server’s file system. Cannot operate with elevated privileges.

That said, I considered that enough of the Reference document is irrelevant in the Sitecore scenario that it’s beneficial for the users of the console to have a bespoke cheat sheet created especially for the purpose of this plugin.

The content & samples of the original cheat sheet has been adjusted to more closely reflect scenarios usable for an Sitecore admin or developer.

How to get help

Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.

Read the rest of this article »

Posted in Code Samples, Downloadable, PowerShell, Sitecore, Software Development, Solution, Web applications
1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5.00 out of 5)
Loading...
| 6 Comments »

Sitecore PowerShell Console cheat sheet ? Part 1

I?m realizing time and time again that the learning curve for PowerShell can be steep without a proper guidance. While most people I talk to are very excited about the concept they become discouraged after a having some tries and not realizing its full potential. Therefore I decided it?s worth spending some time introducing some basic principles to help scripting alleviate some of the initial pains.

I have gathered some literature available for free about the topic of PowerShell in general you might want to read, but I also think that a distillation of the basic concepts is really important so you can have some quick wins while you begin your PowerShell journey.

A great deal of this post is a port of my older post for similar console for EPiServer, but since the differences are significant enough to confuse Sitecore developers if I sent them to the original version, I?ve decided to create a proper Sitecore cheat sheet.   Most of this is based on the Microsoft?s Windows PowerShell Quick Reference however despite the sharing scripting runtimes the nature of the both shells are pretty different (although the differences are not as vast as one might think).

Windows PowerShell PowerShell Console for Sitecore
Interactive ? command can ask for confirmations and can be aborted. User can be solicited to provide input. Batch ? all commands are being executed in one go, the script has no chance to ask questions, go or no-go decisions have to be solved within the script.
Supports command line arguments for running scripts. All arguments are defined directly within the script or derived from context automatically.
Can access any file depending on the rights of the user. Can only access files the web application identity can write to. Cannot access files on user?s machine but rather operates on the server?s file system. Cannot operate with elevated privileges.

That said, I considered that enough of the Reference document is irrelevant in the Sitecore scenario that it?s beneficial for the users of the console to have a bespoke cheat sheet created especially for the purpose of this plugin.

The content & samples of the original cheat sheet has been adjusted to more closely reflect scenarios usable for an Sitecore admin or developer.

How to get help

Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.

Read the rest of this article »

Sitecore PowerShell Console cheat sheet ? Part 1

I?m realizing time and time again that the learning curve for PowerShell can be steep without a proper guidance. While most people I talk to are very excited about the concept they become discouraged after a having some tries and not realizing its full potential. Therefore I decided it?s worth spending some time introducing some basic principles to help scripting alleviate some of the initial pains.

I have gathered some literature available for free about the topic of PowerShell in general you might want to read, but I also think that a distillation of the basic concepts is really important so you can have some quick wins while you begin your PowerShell journey.

A great deal of this post is a port of my older post for similar console for EPiServer, but since the differences are significant enough to confuse Sitecore developers if I sent them to the original version, I?ve decided to create a proper Sitecore cheat sheet.   Most of this is based on the Microsoft?s Windows PowerShell Quick Reference however despite the sharing scripting runtimes the nature of the both shells are pretty different (although the differences are not as vast as one might think).

Windows PowerShell PowerShell Console for Sitecore
Interactive ? command can ask for confirmations and can be aborted. User can be solicited to provide input. Batch ? all commands are being executed in one go, the script has no chance to ask questions, go or no-go decisions have to be solved within the script.
Supports command line arguments for running scripts. All arguments are defined directly within the script or derived from context automatically.
Can access any file depending on the rights of the user. Can only access files the web application identity can write to. Cannot access files on user?s machine but rather operates on the server?s file system. Cannot operate with elevated privileges.

That said, I considered that enough of the Reference document is irrelevant in the Sitecore scenario that it?s beneficial for the users of the console to have a bespoke cheat sheet created especially for the purpose of this plugin.

The content & samples of the original cheat sheet has been adjusted to more closely reflect scenarios usable for an Sitecore admin or developer.

How to get help

Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.

Read the rest of this article »

Continuous deployment in Sitecore with PowerShell

A few days back a budy from our Sitecore team has alerted me to this interesting question on StackOverflow which asks for automation of content promotion from one Sitecore instance to another. He suggested – and rightly so ? that the PowerShell Console could be used in that scenario. While this was always possible by simply writing it as a PowerShell code the latest version of the console added a few commandlets making building packages much easier.

The easiest approach is to build the package visually in the package designer, save it and then simply use the console to read it and generate the installation zip like:

get-package "powershell console.xml" `
  | Export-Package -FileName "PowerShell Console.zip" -Zip

That?s fine in most cases but if you have some more complex scenarios or want to generate some custom packages ? you might want to generate packages directly in PowerShell.

To Create a Package you simply use:

$package = new-package "Test Package";

Now that you have that package you might want to add some files and items to it.

Let’s add for example our item templates by querying the master database and creating a dynamic item source:

$TemplatesSource = get-childitem "master:/templates/Cognifide" `
  | New-ItemSource "Cognifide Templates";

And subsequently add it to our new package:

$package.Sources.Add($TemplatesSource);

While that by itself is fairly useful, the really cool part is that you have a full flexibility of PowerShell at your disposal when you create a source with static items. Let?s say you want to add all items of template ?Article Template? that reside anywhere under your ?home? node ? now that would require quite a bit of clicking in the Package Designer, but is trivial with the PowerShell Console:

$ArticlesSource = get-childitem master:/content/home/about-us/* -recurse `
  | where-object { $_.TemplateName -match "ArticleTemplate" } `
  | New-ExplicitItemSource "Cognifide Articles";

$package.Sources.Add($ArticlesSource);

You can specify any automation or filter you can think of to your Get-ChildItem, and you really don?t have to skimp on the number of data sources ? after all you can re-generate your package at any time!

Similarly you can do this to the files on disk. Let?s say ? you want to add all .aspx, .ascx and .ashx files, just to make sure your deployment features all the latest code and for the sake of this example let?s assume your UI elements are located in the Layouts folder under your web application:

$LayoutsPath = $AppPath+"layouts\*"
$Layouts = get-childitem $LayoutsPath -include "*.as?x" -recurse -force `
  | New-ExplicitFileSource "My Layouts";
$package.Sources.Add($Layouts);

Easy enough? now let?s add everything that is within the bin folder as a dynamic file source:

$BinFolder = New-FileSource "Bin Folder" -Root "/bin"
$package.Sources.Add($BinFolder);

That is it really? you may want to specify your package metadata which you would do like:

$package.Metadata.Author = "Auto generated " + `
  [DateTime]::Now.ToShortDateString();
$package.Metadata.Comment = "Isn't it cool?!";
$package.Metadata.Publisher = "Cognifide";

and then save it for later opening in package designer:

$package | Export-Package -FileName "test package.xml"

alternatively you can open such package as specified earlier

get-package "test package.xml"

if you ever wanted to add more sources to it or export as a zip file to be imported with the assets in your target environment:

$package | Export-Package -FileName "test package.zip" -Zip

? now on your target machine you need to upload your package to the Data\Packages folder. But then to install it all it takes is:

Import-Package "test package.zip"

Obviously all of it can be hooked to ribbon, context items, or be scheduled? but I get ahead of myself…

So how does it all relate to continuous deployment?

All of this can be completely automated, all you need to do is create a Script item as described in one of my previous posts and call the PowerShell execution URL referencing your script from your CruiseControl server or whichever continuous integration product you use in a fashion similar to:

http://myhost/Console/Layouts/PowerShellResults.aspx?scriptId={1680E211-BD28-49BE-82FB-DA7232814C62}&scriptDb=web

You need to deal with the fact that you are most probably not logged in with your continuous delivery environment ? in this case probably best approach is to use the web database or the script item my turn out to be unavailable to you and the script will not execute.

Now in your source environment your script will create the package and upload it to an FTP server (there is plenty of ways to do this from PowerShell? you can find a couple of samples on Stack Overflow) and subsequently call a second part of the script on the target server.

On the Target server ? a complementary script will be executed in the similar fashion ? by the originating server and if you don?t have direct access to the file on the FTP server you?ve just uploaded ? you can download it and import the package.

Now if you integrate the script with a ribbon in Content Editor on the source server (like described in the previous post) you can have a one-click-deployment solution on your dev machine, but then the REALLY cool part would be to integrate it with the context menu (as described in this post) and be able to push parts of the site to production with a single click! Not to mention your nightlies can really be nightlies if you do it using the scheduled tasks integration.

Extending Sitecore ribbon with PowerShell scripts

Sitecore is built from the grounds up with extendibility in mind. Be that plugging into any place in its internal pipelines or any aspect of its User eXperience, therefore when I?ve managed to extend it?s context menu, I expected to have no problems whatsoever doing the same to its ribbon. Mind you I was right?

Using the PowerShell Console Module it took me less than 10 minutes total to add a nice piece of functionality that I thought was missing ? Publish items I have modified.

ContextScriptsRibbon

Similarly to extending context menu ? first I?ve created the script I wanted to execute that will take the current item and it?s sub-items and publish them by adding a new script item using the /sitecore/templates/Cognifide/PowerShell Script template in the core database. I?ve put it in the same place I store all my my scripts – in the /sitecore/content/Applications/PowerShell Console/Scripts branch but feel free to store them anywhere in the tree.

  • Filled in the Script body part with my script.
  • I decided I want to see the publishing results as I want to verify if the items I expected got published.

ContextScriptRibbonBody

Now the UI integration bits?

Since I wanted it nicely integrated with the publish button – I?ve created a Publish My Items item of template /sitecore/templates/System/Menus/Menu item within the /sitecore/content/Applications/Content Editor/Menues/Publish/ branch in the core database, set it?s icon and reference the script item in the Message field using the following pattern:

item:executescript(id=$Target,script={0937769B-998D-4580-B9FE-730C4CDABECD},scriptDb=core)

where the script guid is the ID of your script and the scriptDb is the database the script is located in.

ContextScriptsRibbonBinding

That?s it really. You can download the solution but I would strongly recommend you try the manual approach ? it?s really exciting to see the puzzles click in.

The solution requires the Sitecore PowerShell Console from Cognifide, available for free from Sitecore Shared Source site.

Sample scripts for Sitecore PowerShell Console

Find out about your configuration:

List your available site providers. You will use the name provided in the "Name" column in place of where I use "cms" in the later samples.

get-psdrive `
  | where-object { $_.Provider.ToString() -eq "CmsItemProvider"} `
  | format-table Name, Root

Sample scripts for working with pages:

For the same of brevity I?m assuming your location is already somewhere within a Sitecore tree (e.g. you did something akin to cd master:\content prior to executing the following scripts.

List all properties & fields available for a particular page (including Sitecore properties defined in the item template).

get-childitem | get-member -memberType property*

List all items in the CMS of which template name contains "Article"

get-childitem -recurse `
  | where-object { $_.TemplateName -match "Article" } `
  | format-table DisplayName, Name, TemplateName

List all subitems and how many days ago were they modified

get-childitem -recurse `
  | format-table -auto Name, `
  @{Label="Days since modified"; Expression={ `
  [datetime]::Now.Subtract($_.__Updated).Days} }

Delete all pages that have not been modified for the last 365 days.

get-childitem -recurse `
  | where-object {[datetime]::Now.Subtract($_.__Updated).Days -gt 365 } `
  | remove-item

List all items Updated over the last 24 hours and who changed them.

get-childitem -recurse `
  | where-object { $_.__Updated -gt [datetime]::Now.AddDays(-1) } `
  | format-table -property DisplayName, "__Updated By", {$_.Paths.Path}

List all pages that have their "Text" field filled in.

get-childitem -recurse `
  | where-object { $_.Text -ne $null } `
  | format-table -property DisplayName, {$_.Paths.Path}

Make a nice reviewer’s comment on all pages with their "Text" property filled in.

get-childitem -recurse `
  | where-object { $_.Text -ne $null } `
  | foreach-object { $_.ReviewersComment = "Great job providing content!" }

Add a warning to the beginning of "Text" property for all pages that have not been saved for the last 180 days.

get-childitem -recurse `
  | where-object {`
  [datetime]::Now.Subtract($_.__Updated).Days -ge 180 `
  -and $_.Text -ne $null }
  | foreach-object {$_.Text = "<p style='color:red'>Old content. Review pending!</p>" + $_.Text }

Replace a string in a property on all pages with another string (in this sample – removing the warning the last sample added).

$old_content = "<p style='color:red'>Old content. Review pending!</p>"
$new_content = "";
get-childitem -recurse `
  | where-object {$_.Text -match $old_content} `
  | foreach-object {$_.Text = $_.Text.Replace($old_content, $new_content) }

Display the 10 most recently changed pages ordered in the reverse chronological order or changes. Display the page name, who changed it and when as well as the page status.

get-childitem -recurse `
  | sort-object -property __Updated -descending `
  | select-object -First 10 `
  | format-table -property DisplayName, "__Updated By", __Updated

Sample scripts for working with Media Library / files:

Removes all .xml files from the ?Old Xml Files? in Media library.

cd "master:\media library\Old Xml Files"
get-childitem -recurse `
  | where-object { $_.Extension -match "xml" } `
  | remove-item

Copy all files from the "staging" folder to the "production" folder in Media Library.

Copying files within media library is done as follows. This can also be done for items in the content branch.

copy-item "master:\media library\staging\*" "master:\media library\production\"

The aim of the PowerShell console for Sitecore is to create a command line interface to your data so you can automate and aggregate mundane tasks as well as create statistics and a discoverability layer on top of your content.

Have you ever found yourself:

  • having to make a mundane change to a large number of pages?
  • in need of getting statistics field or template usages?
  • being curious of e.g. what’s the oldest page on your site?
  • in need to find out how many authors really create your content and how active they are?
  • having to copy or move a large number of files from one folder to another?
  • renaming or deleting files in your file store en-masse?
  • publish pages that match some specific feature rather than a whole branch?

sharp_toolIf the answer to any of those (and more) is something akin to “yes I did!”, I believe you might find my little plugin useful.

The idea is to create a scripting environment to work within Sitecore process, being able to make native calls to Sitecore API and modify content on a per-property level. The goal was to make it familiar to your IT and developers so they can reuse their skillset with it or if they rather learn it here, this knowledge will benefit them in the long run as clearly PowerShell is becoming an industry standard. The plugin’s aim is to manipulate not just sites, but files and pages on a large scale or perform statistical analysis of your content using  a familiar and well documented query language. The console allows you to execute and test scripts interactively, but also gives the admin means of exposing scripts to end users within context menus and in the ribbon. I’m sure in the long run I’ll come up with more applications. Scripted pipeline processors? Scripted renderings? Scripting campaigns statistics and engagement workflow steps? You name it…

Read the rest of this article »

PowerShell Console for Sitecore ? what can it do for me?

The aim of the PowerShell console for Sitecore is to create a command line interface to your data so you can automate and aggregate mundane tasks as well as create statistics and a discoverability layer on top of your content.

Have you ever found yourself:

  • having to make a mundane change to a large number of pages?
  • in need of getting statistics field or template usages?
  • being curious of e.g. what?s the oldest page on your site?
  • in need to find out how many authors really create your content and how active they are?
  • having to copy or move a large number of files from one folder to another?
  • renaming or deleting files in your file store en-masse?
  • publish pages that match some specific feature rather than a whole branch?

sharp_toolIf the answer to any of those (and more) is something akin to ?yes I did!?, I believe you might find my little plugin useful.

The idea is to create a scripting environment to work within Sitecore process, being able to make native calls to Sitecore API and modify content on a per-property level. The goal was to make it familiar to your IT and developers so they can reuse their skillset with it or if they rather learn it here, this knowledge will benefit them in the long run as clearly PowerShell is becoming an industry standard. The plugin?s aim is to manipulate not just sites, but files and pages on a large scale or perform statistical analysis of your content using  a familiar and well documented query language. The console allows you to execute and test scripts interactively, but also gives the admin means of exposing scripts to end users within context menus and in the ribbon. I?m sure in the long run I?ll come up with more applications. Scripted pipeline processors? Scripted renderings? Scripting campaigns statistics and engagement workflow steps? You name it?

Read the rest of this article »

PowerShell Console for Sitecore ? what can it do for me?

The aim of the PowerShell console for Sitecore is to create a command line interface to your data so you can automate and aggregate mundane tasks as well as create statistics and a discoverability layer on top of your content.

Have you ever found yourself:

  • having to make a mundane change to a large number of pages?
  • in need of getting statistics field or template usages?
  • being curious of e.g. what?s the oldest page on your site?
  • in need to find out how many authors really create your content and how active they are?
  • having to copy or move a large number of files from one folder to another?
  • renaming or deleting files in your file store en-masse?
  • publish pages that match some specific feature rather than a whole branch?

sharp_toolIf the answer to any of those (and more) is something akin to ?yes I did!?, I believe you might find my little plugin useful.

The idea is to create a scripting environment to work within Sitecore process, being able to make native calls to Sitecore API and modify content on a per-property level. The goal was to make it familiar to your IT and developers so they can reuse their skillset with it or if they rather learn it here, this knowledge will benefit them in the long run as clearly PowerShell is becoming an industry standard. The plugin?s aim is to manipulate not just sites, but files and pages on a large scale or perform statistical analysis of your content using  a familiar and well documented query language. The console allows you to execute and test scripts interactively, but also gives the admin means of exposing scripts to end users within context menus and in the ribbon. I?m sure in the long run I?ll come up with more applications. Scripted pipeline processors? Scripted renderings? Scripting campaigns statistics and engagement workflow steps? You name it?

Read the rest of this article »

We had a situation in the company this week which required us to deliver the whole EPiServer virtual path provider file structure to the client ? zipped. Easy enough? go to the EpiServer VPP directory and? well? ok? hmm? so the path provider is versioning and as a consequence the physical organization of files on the disk does not make any sense for a human trying to browse it.

Fine! So let?s create a native provider and do a copy and paste within the file manager?. hmm an exception complaining about the provider incompatibility?

Naturally, my knee-jerk reaction is ? let?s do it with the PowerShell? which I recall was doing something like this in it?s previous version? The example I?ve tested and placed in the ?Samples? tab was:

cd VPP:\
cd \Documents\
get-childitem -recurse |
    copy-item -destination \DocumentsNonVersioningVPP\

This worked well but flattened the directory structure ? in other words useless for our client.

I?ve tried what should work in a plain PowerShell:

cd VPP:\
copy-item -path vpp:\Documents\*
          -destination vpp:\DocumentsNonVersioningVPP\
          -recurse -force

Now that didn?t work at all, and turned out to be a bug in my PowerShell plugin?s PSDrive provider. Unfortunately when I attempted to fix it by implementing the copy in the naive way ? using UnifiedDirectory?s  Copy method I?ve run into the same exception about incompatibility between the classes that I?ve seen when trying to copy the files form the file manager.

Mmmkay? I?ll just implement the recursion myself? Read the rest of this article »