hand_controlling_puppet_figure_400_clr_14285I?ve been meaning to write this article for quite a while since the functionality to remote into the Sitecore environment exists in the module at least for at least a couple of versions now and the recent email from one of the Sitecore PowerShell Extensions users convinced me this cannot wait any longer.

When would I remote into my Sitecore instance?

You would probably need this as part of your Continuous Integration or installation scripts. If you need to manipulate Sitecore data from your deployment script remoting is the right solution for you.

How is that special?

We have a a number of web services that could somewhat achieve this functionality for even longer but I didn?t consider those sufficient since a real remoting functionality cannot be limited to just passing text results from the scripts passed but rather should enable the script writers to achieve true interactions between scripts running locally and the scripts that are being executed on the server.

To enable remoting on your Sitecore instance you don?t really have to do anything the web services are already deployed when you install Sitecore PowerShell Extensions. On your local machine all you need to do is include the commandlets in the script that you can find at the following path in your Sitecore instance if you’re using SPE versions older than 2.8:

master:/system/Modules/PowerShell/Script Library/Functions/Remoting

or here in 2.8 and newer:

master:/system/Modules/PowerShell/Script Library/Platform/Functions/Remoting

When you execute the script You will get 4 new commandlets at your disposal:

Set-SitecoreConfiguration
Invoke-SitecoreScript
Upload-SitecoreFile
Download-SitecoreFile

The first commandlet allows for setting the configuration used for connecting to the server by the remaining 3 commandlets e.g. :

Set-SitecoreConfiguration ?SitecoreHost 'http://hostname' `
    -User 'admin' ?Password 'b'

Subsequently after your configuration is set you can invoke a script blocks to run on the server using the Invoke-SitecoreScript like e.g.:

$childrenOfPath = "master:\"
Invoke-SitecoreScript ?Command { Get-ChildItem $params.scPath }`
    -Params @{ scPath = $childrenOfPath } |
    Format-Table Name, Id, TemplateName -AutoSize

Ok so what has just happened above?

  • I?ve defined a local variable $childrenOfPath and assigned it the path that I want to get children of
  • In the script invoking commandlet
    • I?ve assigned the value of the $childrenOfPath variable to the scPath element of the Params that are being passed to the server.
    • The script block in braces following the ?Command parameter will be executed on the server.
    • The values of ?Params parameter gets assigned to $params variable on the server prior to script block execution and therefore the script block can make use of the value passed by recalling it with use of $params.scPath
    • Finally I?m formatting the objects returned as the result of the script execution displaying only the item?s Name, Id and Template Name

What you should be getting as a result of the invocation should look somewhat like this:

Name          ID                                     TemplateName
----          --                                     ------------
content       {0DE95AE4-41AB-4D01-9EB0-67441B7C2450} Main section
layout        {EB2E4FFD-2761-4653-B052-26A64D385227} Main section
media library {3D6658D8-A0BF-4E75-B3E2-D050FABCF4E1} Main section
system        {13D6D6C6-C50B-4BBD-B331-2B04F1A58F21} Main section
templates     {3C1715FE-6A13-4FCF-845F-DE308BA9741D} Main section

So what?s the big deal?

Well the Hashtable passed to the server following the ?Params parameter contains objects that you send to the server. In case of the above line I’m sending a string (as the path to items I want to list) but the good news is that you can actually send any objects to the server not only strings. Those objects are then fully usable by the remote server in the script I?m executing! Another interesting thing is that the result of the Invoke-SitecoreScript is also sent back as objects. So you can send structured data back and forth from your Continuous integration scripts and enable really rich interactions easily. Just be mindful that all of those go through serialization and deserialization so if you send large objects it might take some time for them to go through the process.

What else can I do?

To pass blobs of data like files it?s probably not very efficient to use the serialization through sending objects ? therefore the remaining 2 commandlets deal with uploading and downloading files.

You can upload a file by calling the following commandlet (after you’ve invoked the Set-SitecoreConfiguration of course):

Get-Item C:\image.png | Upload-SitecoreFile -RemotePath "Path\an_image.png"

Which will:

  • Fetch your local local C:\image.png file using the Get-Item commandlet and
  • Send it to your Sitecore instance to /sitecore/media library/Path/an_image.png path using the Upload-SitecoreFile commandlet.

Or do the opposite by calling the Download-SitecoreFile commandlet like:

Download-SitecoreFile -File C:\image.png -RemotePath Path\an_image.png

Which will fetch the blob stored in the Sitecore /sitecore/media library/Path/an_image.png item and save it under the local C:\image.png path.

The above 2 commandlets also support ?Database and ?Language parameters if you need to download or upload a file that is language specific or a database different than master.

Happy remoting!

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



This entry (Permalink) was posted on Friday, October 10th, 2014 at 7:45 pm and is filed under Best Practices, Continuous Deployment, PowerShell, Sitecore, Software Development, 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.