Developers – ideas for extending PowerShell

I’m a big fan of PowerShell, especially in the context of SharePoint. The fact that it lets us write and run scripts to manage our farms in a fluid manner. In an IT role I can use PowerShell to do everything from rolling out new virtual machines to installing and configuring new SharePoint farms and sites. The vast majority of this is can be done with the out of the box PowerShell commands, like New-SPWebApplication and New-SPSite. Further more, the scripts that I run on my dev environment are the same scripts that can be run on UAT and Productions environments. When I think back even 12 months ago where so much of this was manual and had to be well documented things have come along way. In the same way as  a developer I can use PowerShell to aid my deployment and customisations and I can extend PowerShell to incorporate all of my bespoke solutions. I know some developers who view PowerShell as a IT technology and for a large part that’s true. A lot of PowerShell (outside of SharePoint) does do a lot around configuration – Exchange, IIS, Active Directory to name a few are all configurable via PowerShell. However I’d argue that since a lot of times with SharePoint developers don’t just develop – there’s a varying degree of configuration and administration which is often involved, that’s where PowerShell should become part of our tools because it offers a lot.

I’m going to take a look at how we can extend PowerShell with SharePoint and get it to do a lot of the manual tasks that we might otherwise have. Before you start writing PowerShell I’d recommend installing a PowerShell IDE/script editor. You can write your scripts in NotePad but a lot of these tools provide things like intellisense and debugging tools which help a lot. I tend to use PowerGUI, but there are several others out there that I know others use.

Extending out of the box and writing our own

When you use one of the standard PowerShell commands, like Get-SPSite, what that script does is call some precompiled SharePoint code. When it comes to writing custom PowerShell commands one option is that we can write our own commands in Visual Studio in C#, compile and then expose it to the PowerShell console. Share that custom module and your custom commands can be reused by others. Now that’s one option and a quick search online will give you plenty of examples of how to do this. Another option is you can create custom functions in scripts and re-use those. Arguably these are easier to create because there is not the overhead of using Visual Studio, producing the snappin and bringing it into PowerShell. However, with this approach you’re not writing C# which means there are some differences in the language and syntax which you have to familiarise yourself with. Let’s take a look – the following examples show one way of getting an SPSite object in both C# and PowerShell:

C# Example

SPSite site = new SPSite(http://examplesite);

PowerShell

$site = new-object Microsoft.sharepoint.spsite("http://examplesite")

A quick look will highlight some of the differences between the two, for example:

  • Variable names  start with $ in PowerShell
  • “new” keyword becomes “new-object”
  • No ; indicating the end of a command

Although we don’t always have to declare a type, PowerShell is still strongly typed and if you use a PowerShell editor like PowerGUI, then you’ll get some degree of intellisense. As a developer, once you get your head around some of these differences it’s fairly easily to read the PowerShell code and then it’s not too big a step to start writing it. Another advantage with PowerShell is that we can mix custom code with out of the box. The SPSite example is a good one because we can also use the PowerShell cmdlet to achieve the same thing:

 $site = Get-SPSite "http://examplesite" 

This means if there’s already an existing command out there then that can be re-used to save us writing our own but we can also use our own code alongside it to help enhance it. For example, you could write a function which takes an xml file and based on the contents uses New-SPWeb to create new sites. The parsing of the xml is handled by PowerShell, we could then write the foreach loop and possibly some reporting ourselves and then use New-SPWeb to create the sites that we want it to.

Let’s create a very simple function and demonstrate how that can be used.


function Get-SiteName([string]$siteUrl)
{
$site = Get-SPSite $siteUrl
if ($site)
{
return $site.RootWeb.Title
}
return [string]::empty
}

$siteName = Get-SiteName -siteUrl "http://examplesite"
Write-output "Your Root Web Title:  $siteName"

You can copy this text into a text file, save it with a ps1 extension and then you can run it and you should hopefully get the title of your root web. Now this is only a simple example of calling a function and passing some values, but it gives you the basics. When you define a function in this way the type declaration [string] is often optionally, in this example my function works the same if I declared the function as Get-SiteName($siteUrl). I prefer to include the variable type, not necessarily for functionality but it does help with code readability. If you’ve got a number of parameters being passed in, or you’re reusing someone elses functions then it helps!

This is just one example of how you can pass in parameters to a function and there’s another couple of common ways as well:


function Get-SiteName2 {
param ($siteUrl)
#same logic as before
}
Get-SiteName2 -siteUrl "http://examplesite"

function Get-SiteName3 {
$siteUrl = $args[0]
#same logic as before
}
Get-SiteName3 "http://examplesite"

The second example, Get-SiteName2, declares the parameters using the param keyword and parameters can be defined in the same way as in our first example. The third example uses arguments that are passed in automatically when the command is run (this is very similar to MS DOS). I tend not to use this approach because for me it’s a lot neater and clearer to use named parameters rather than positional. Consider the following:


Run-Query "Projects" "Adam" 10

Run-Query -list "Projects" -filterByAuthor "Adam" -returnTop 10

Both commands do the same thing, but the second is fair more readable and for someone picking up the code they’re fair more likely to understand what it is trying to do.

Calling additional ps1 files – Dot-notation

If you’re writing a number of functions your ps1 file can quickly become bloated and tricky to keep track off – especially if you’re combining the functions and calls. What I do is split my functions into one ps1 file and have a separate one which uses them. If we take the Get-SiteName example I might split it up as follows:

MyFunctions.ps1

function Get-SiteName([string]$siteUrl)
{
$site = Get-SPSite $siteUrl
if ($site)
{
return $site.RootWeb.Title
}
return [string]::empty
}

RunMe.ps1

. .\MyFunctions.ps1
$siteName = Get-SiteName -siteUrl "http://examplesite"
Write-output "Your Root Web Title:  $siteName"

All I then have to do is run RunMe.ps1 from the PowerShell console and it will run the code and output the response. The first line of RunMe.ps1 uses something call dot-notation and what does here is includes the content of that file that can be reused by this script. When it sees the call to Get-SiteName it is aware of the function because it has already been loaded. By comparison, if we reference MyFunctions like this .\MyFunctions.ps1 then that script would be executed instead.

I write a lot of custom PowerShell functions to help with deployments and so keeping them separate helps a lot. You can also reference a number of different script files and this all helps to keep the files neater and more readable. In fact, if you want to take your scripts a step further, there are options to annotate your functions so that you can provide things like help text, usage examples etc which can all again help.

So how far can you take things with PowerShell and SharePoint?

If you’re familiar with the SharePoint object model then you can do as much as you want to – I’d like to think if you can code it in C# then you can code it in PowerShell too. I’ve got a series of scripts that I re-use on projects which allow modifications to everything from creating content like lists and pages, to modifying config files. I need to roll a site to a new developer, then the scripts are there which will handle it with very little interaction from the developer. There’s a certain amount of reassurance knowing that the scripts you run are the same across each environment which should mean their setups are all identical. If you’re not a developer and you don’t want to learn how to code then look to see how you can exploit of the out of the box commands because they are still very powerful. It might also be worth getting on the good side of a SharePoint developer who can always help with any bespoke bits!

So the next time you head into Central Admin to make a configuration change, or the next time you roll out some content, have a think as to whether turning into a PowerShell script would help.

 

Extra PowerShell Resources

http://technet.microsoft.com/en-us/library/ee890105.aspx - The MSDN summary of the standard SharePoint cmdlet

http://blog.falchionconsulting.com/ - Gary Lapointe does some excellent work with PowerShell and is definitely worth a read

 

Leave a comment

  • (will not be published)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>