PowerShell primer for SharePoint developers: Part 1

With SharePoint 2010 PowerShell if the preferred command line interface. In SharePoint 2013, a working knowledge is pretty much essential to get things like search up and running. Despite that, I’m often asked for assistance in preparing PowerShell scripts for SharePoint admin folks that really should know better, Bearing that in mind, it seems that there’s scope for a few posts on how to use PowerShell to manage SharePoint

Posts in this series:
  1. Getting started (this post)
  2. Using PowerShell with SharePoint

What is PowerShell?

PowerShell is a powerful scripting environment that leverages the flexibility of the .NET framework to provide command-line users with the capability to develop scripts and utilities that can automate administrative tasks. Unlike many command-line tools, PowerShell has been designed to deal with objects rather than plain text output. Most command line tools are effectively executables and as such can only read text based input from the command line while only being capable of return text based output to the console. PowerShell introduces the concept of a cmdlet (pronounced command-let). Cmdlets are PowerShell specific commands which are derived from the System.Management.Automation.Cmdlet class and are created using the .NET Framework. PowerShell uses an object pipeline to pipe the output of one cmdlet to the next cmdlet in a chain. This mechanism allows objects to be passed between functions simply.

There are many cmdlets available for use with PowerShell and users are free to create their own using tools such as Visual Studio. To make it easier to manage cmdlets, they are commonly packaged together as snap-ins. As a general rule a snap-in contains all of the cmdlets for managing a particular product or service. For example, the Microsoft.SharePoint.Powershell snap-in contains the out-of-the-box snap-ins for SharePoint 2010.

Getting help

When using legacy command-line tools, it can be difficult to remember the names of the various tools. There is no common standard for naming or passing parameters. For PowerShell cmdlets a verb-noun naming convention has been adopted. This makes it easier for users to guess the name of a command. By using the get-command cmdlet, it’s possible to get a list of the commands that are available. This command also accepts -verb or -noun as parameters for filtering the output. For example, we could enter the following command to retrieve a list of commands relating to the SPWeb object:

get-command -noun spweb

As well as a standard naming convention for cmdlets, PowerShell also imposes a standard convention for passing parameters. Parameters are always preceded with a hyphen. We can see this in the example above. It’s possible to view help for a particular cmdlet by passing the parameter –?

Tab expansion (or Intellisense if you’re a developer)

One really useful feature of the PowerShell command-line interface is the ability to use tab expansion. As developers, we’ve become used to having tools such as IntelliSense to remind us of our options when entering code. The same idea works with PowerShell. When entering a command name, if we enter part of the name and then repeatedly press the tab key we can cycle through the available commands matching our input. When entering parameters for a command if we enter the preceding hyphen we can also cycle through the list of available parameters. These two features combined with a standard naming convention make it relatively straightforward to pick up PowerShell scripting.

Using Objects

As mentioned PowerShell deals with objects rather than text. This means that we can often set or query properties or execute methods on the object that is returned by a particular cmdlet. For example, the following command returns an SPWeb object :

Get-SPWeb -Identity http://localhost

If we execute this command we’ll find that a URL is returned. This is the default output where no specific property has been called.

We can get a list of the available members for the resultant SPWeb object by passing the output of this command to the get-member command using the pipe character as follows:

Get-SPWeb -Identity http://localhost|get-member

Once we’ve found the property that we’re interested in we can either retrieve the value by placing parenthesis around the command or by assigning the output of the command to a variable and then querying the variable.

(Get-SPWeb -Identity http://localhost).Title

or

$web=Get-SPWeb -Identity http://localhost
    $web.Title

PowerShell variables are always prefixed with $ and persist for the duration of a session. We can examine the type of a variable by using the GetType method as shown:

$web.GetType()

If we need to view more than one property from an object or collection of objects we can use the select-object cmdlet to specify the properties that we require.

(Get-SPFarm).Service|Select-Object -Property TypeName,Status

This command will return a list of services on a farm along with their status. Another way to write the same command is:

(Get-SPFarm).Service|select TypeName,Status

This shortened command uses a technique known as aliasing. Many commonly used commands have simpler aliases and a full list can be retrieved using the following command:

Get-Alias

As well as being able to specify which properties are shown when displaying a collection of objects we can also filter which objects appear in the collection by using the Where-Object cmdlet. Again this cmdlet has an alias: where. Before we seen an example of this, we need to consider the properties that are available for this cmdlet. We have the following comparison operators:

Comparison Operator

Meaning

Example (returns true)

-eq

is equal to

1 -eq 1

-ne

Is not equal to

1 -ne 2

-lt

Is less than

1 -lt 2

-le

Is less than or equal to

1 -le 2

-gt

Is greater than

2 -gt 1

-ge

Is greater than or equal to

2 -ge 1

-like

Is like (wildcard comparison for text)

"file.doc" -like "f*.do?"

-notlike

Is not like (wildcard comparison for text)

"file.doc" -notlike "p*.doc"

-contains

Contains

1,2,3 -contains 1

-notcontains

Does not contain

1,2,3 -notcontains 4

As well as comparison operators, we can combine comparison by using the following logical operators:

Logical Operator

Meaning

Example (returns true)

-and

Logical and; true if both sides are true

(1 -eq 1) -and (2 -eq 2)

-or

Logical or; true if either side is true

(1 -eq 1) -or (1 -eq 2)

-not

Logical not; reverses true and false

-not (1 -eq 2)

!

Logical not; reverses true and false

!(1 -eq 2)

Using these two techniques we can create queries such as:

(Get-SPFarm).Services|Where {$_.TypeName -Like “*data*”}|Select TypeName, Status

Note the use of the $_ variable. This is a system defined variable which evaluates to the current object in the object pipeline, or in other words the output of the previous command. In situations where the previous command returns an enumerable collection the where command will iterate through the collection, therefore $_ will evaluate to an instance of an object in the collection rather than the entire collection.

Using Functions

As well as being able to execute command chains and utilize variables, we can also define functions using PowerShell. Functions work in the same way as in any other programming language, the only minor difference is that all uncaptured output within a function is returned to the caller. For example, we can create the following simple function:

function addNumbers($first,$second)
    { 

“Adding numbers” 

return $first + $second 

}

We can call this function by entering the command (note the method of passing named parameters):

addNumbers -first 1 -second 2

The resultant output will be:

Adding numbers
    3

This is expected. However, what isn’t expected is that if we examine the data type of the return value by piping the output to Get-Member we find that there are two return types, string and int32. In situations where we want to use our function in a chain this is not ideal. The reason this has happened is that the Adding Numbers message is uncaptured output, that is to say it isn’t assigned to a variable or passed to a cmdlet, and as a result it forms part of the output. We can prevent this from occurring by modifying the function as follows:

function addNumbers($first,$second)
    { 

Write-Host “Adding numbers” 

return $first + $second 

}

Summary

This post is a brief introduction to PowerShell, covering the fundamental differences between PowerShell and other scripting techniques. In the next post I’ll build on this basic knowledge to look at how we can perform specific SharePoint tasks using PowerShell.

This entry was posted in Development, PowerShell, SharePoint. Bookmark the permalink.