Determining When to Use Windows PowerShell or to Write Code (Wrox)

Summary: Explore how to determine when to use Windows PowerShell or to write code. Learn how to use Windows PowerShell, how to combine Windows PowerShell with code, and when it is best to write traditional code solutions.

Wrox logo

Wrox SharePoint Books

Applies to: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

Author: Raymond Mitchell

Editors: WROX Tech Editors for SharePoint 2010 Articles

Contents

  • Introduction to Determining When to Use Windows PowerShell or to Write Code

  • Understanding Windows PowerShell

  • Windows PowerShell for SharePoint Administration and Automation

  • Writing Code and Windows PowerShell

  • When Code Is Better

  • Conclusion

  • About the Author

  • Additional Resources

Introduction to Determining When to Use Windows PowerShell or to Write Code

Windows PowerShell is a very powerful scripting environment that brings you the power of the .NET Framework to the command line. Because Windows PowerShell replaces the deprecated STSADM command-line tool, it is a very important tool for SharePoint administrators and developers. In addition, because Windows PowerShell can use the power of .NET, the line between Windows PowerShell and code is blurry at best. Use this article to learn how to use Windows PowerShell, how to combine Windows PowerShell with code, and when it is best to write traditional code solutions.

At the end of the day, the choice to write code or to use Windows PowerShell is not very straightforward. The decision largely depends on the comfort level and the skillset of the solution developer. It is important to understand how you can use Windows PowerShell on its own and together with code to create solutions.

Understanding Windows PowerShell

As a SharePoint professional, your first exposure to Windows PowerShell might have been with the SharePoint Management Shell, the command line tool that resembles a traditional DOS prompt. This environment is actually a customized Windows PowerShell environment that enables you to quickly interact with SharePoint by including the Microsoft.SharePoint.PowerShell module. You can also add this module to any Windows PowerShell session by using the PSSnapin command.

Add-PSSnapin Microsoft.SharePoint.PowerShell

You can use the module to run cmdlets that are custom-built to work with the SharePoint Object Model. However, this isn’t the only way to work with SharePoint objects in Windows PowerShell. You can also directly load the Microsoft.SharePoint.dll into your scripting environment, which is what you must do to work with SharePoint 2007 in Windows PowerShell. To load the .dll, use the Assembly class in the System.Reflection namespace. In this case, use the LoadWithPartialName static method.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

Even though this approach works today, the LoadWithPartialName method is obsolete. There are many existing code examples that use the approach, but the more proper way is to load the assembly by using the Load static method.

[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")

After you load the Microsoft.SharePoint.dll into your scripting environment, you can work with SharePoint objects such as SPSite, SPWeb, and SPList. You might want to include a few other classes also, including Microsoft.SharePoint.Administration, which lets you work with administrative objects such as SPFarm and SPContentDatabase.

The preceding static method examples demonstrate ways to make the SharePoint Object Model available to Windows PowerShell. You can also add your own classes to Windows PowerShell by using the LoadFile static method (similar to the preceding examples) and then specifying a path to your own DLL.

[System.Reflection.Assembly]::LoadFile("c:\development\your.dll")

There are also times when you might want to include actual .NET code (such as a helper class) in your Windows PowerShell scripts. This can be a great way to quickly test sample code that you find in the SDK or on a community resource site. In that scenario, you can actually add your own class (in this case, written in C#) in your Windows PowerShell script by using the Add-Type command.

Add-Type @'
public class CustomHelperObj
{
    public int maxWebsToCheck = 2;
    public bool checkWebForList(string listName) {
        return true;    // Fancy processing here
    }
}
'@

You can then consume your custom class in Windows PowerShell.

$obj = New-Object CustomHelperObj
$obj.checkWebForList("test");

With so many ways to extend Windows PowerShell with custom code, it can be difficult to know when to write code and when to remain in Windows PowerShell. Next, we’ll walk through some example scenarios that illustrate when writing code makes sense.

Before we leave this section, there’s an important point to make: Windows PowerShell is code. Because Windows PowerShell has access to the .NET Framework and all the power that is included with it, treat any scripts that you write in Windows PowerShell as code. Put your Windows PowerShell scripts in some form of source control, test scripts rigorously, and treat them with the same care that you give your traditional coding projects.

Windows PowerShell for SharePoint Administration and Automation

With the introduction of the SharePoint Management Shell, SharePoint administrators can use Windows PowerShell to work with SharePoint without first knowing the details of the SharePoint Object Model. SharePoint administrators use Windows PowerShell with SharePoint in the following ways:

  • Use STSADM-like cmdlets that execute a specific action.

  • Use cmdlets like Get-SPWeb that return a SharePoint object or objects.

In the first approach, administrators specify a command and then plug in parameters as they would with STSADM (the command-line administration tool for SharePoint 2007). For example, administrators might use the Backup-SPSite cmdlet.

Backup-SPSite https://server/site -Path c:\temp\site.bak

This lets administrators perform complex administrative tasks such as performing backup and restores, managing content databases, and managing custom feature and solution deployment without any knowledge of the SharePoint Object Model or class hierarchy.

The second approach uses cmdlets such as Get-SPWeb to get SharePoint objects for use in scripting, and can be combined with the first method.

$site = Get-SPSite https://server/site
Backup-SPSite $site -Path c:\temp\site.bak

SharePoint administrators can build on this by using the Windows PowerShell pipeline and looping techniques to create robust scripts to automate administrative tasks. For example, you can loop through all site collections for a given SPWebApplication instance and perform a backup of each site collection.

$webapp = Get-SPWebApplication https://server
$webapp.Sites | % { Backup-SPSite $_ -Path ('c:\temp\' + $_.ID + '.bak') }

These administrative tasks are where Windows PowerShell really shines. The ability of Windows PowerShell to make it easier to use SharePoint Object Model classes, without requiring administrators to work with complex object construction, is exactly why Windows PowerShell is so important. Even very complex automation scenarios are possible without having to build a traditional solution that uses custom code.

As the scenario becomes more complex, some experts might argue that the demand for a traditional solution grows as well, but even very complex migration scripts can be written by using only Windows PowerShell. You can create reusable Windows PowerShell functions for common scenarios. For example, the following function helps automate the creation of publishing pages on a SharePoint Server site.

function AddPage ([string] $webUrl, [string]$pageUrl, [string]$content, [string]$title, [Microsoft.SharePoint.Publishing.PageLayout]$layout)
{
     [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Publishing");
    $web = Get-SPWeb $webUrl;
    $pweb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web);
    $pages = $pweb.GetPublishingPages();
    $page = $pages.Add($pageUrl, $layout);
    $item = $page.ListItem;
    $item["Title"] = $title;
    $item["Page Content"] = $content;
    $item.Update();
    $item.File.CheckIn("");
    $item.File.Publish("");
}

You can combine a function like this with other functions that make database calls to automate site migrations or any number of other scenarios. The best part is that the SharePoint administrator wouldn’t have to be the one who writes the database-access function. As long as the SharePoint administrator is given a function that generates the output that they need, it can be written as a Windows PowerShell function or wrapped in a .NET class and accessed from there.

In the next section, we’ll talk more about combining code with Windows PowerShell.

Writing Code and Windows PowerShell

You can find several examples in which traditional code and Windows PowerShell are used together to develop a solution. One great example of mixing traditional code and Windows PowerShell is the deployment of a SharePoint List Event Receiver.

A SharePoint List Event Receiver enables you to respond to list item events, such as item added/adding, updated/updating, and so on. A developer typically writes an event receiver, which is a class that extends Microsoft.SharePoint.SPItemEventReceiver, but he or she might have to work with a SharePoint administrator to deploy the solution. Most tools that deploy Event Receivers deploy the Event Receiver to all Lists of a specific type (all Document Libraries, for example). In some cases, you must deploy the Event Receiver to a single list or library. By using Windows PowerShell, that deployment option becomes very manageable.

Use the following steps to deploy an Event Receiver:

  1. Deploy the custom class (wrapped in a .dll) to the server. This is typically done by deploying a SharePoint Solution (.wsp).

  2. After you deploy the .dll, you must add the Event Receiver to the SharePoint List for which you want to handle events.

In the following example, assume that you have already deployed the sample.receivers.dll file to the server. Now, by using Windows PowerShell, attach the Event Receiver to an existing list.

$web = Get-SPWeb https://server/site
$list = $web.Lists["Sample"];
$event = [Microsoft.SharePoint.SPEventReceiverType]::ItemAdded;
$assembly = "sample.receivers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9c5923e9-de52-33ea-88de-7ebc8633b9cc";
$class = "sample.receivers.CustomNotifications";
$list. EventReceivers.Add($event, $assembly, $class);

This example uses Windows PowerShell to add the Event Receiver to the specified SharePoint List. It could also use a SharePoint Feature and a Feature Receiver, but Windows PowerShell ensures that you have flexibility to add and remove Event Receivers as needed. This can be especially helpful during development or testing.

Another scenario in which Windows PowerShell can help is when you are writing a traditional code solution, but want to test the inner-workings of a class in the SharePoint Object Model. A great example of this is when you are working with a SharePoint Object Model class such as SPQuery.

An SPQuery object can be used to query a SharePoint List or Library for specific items. The SPQuery class is not very complex, and a quick look at the SharePoint software development kit shows how to use it and even gives examples. What it doesn’t show you (because it varies in every scenario) is the exact Collaborative Application Markup Language (CAML) to use in your query.

This example uses a <Contains> element to find all items that have 'Test' in the Title field of a NewsFeed List.

$web = Get-SPWeb https://server/site
$list = $web.Lists["NewsFeed"]
$q = New-Object Microsoft.SharePoint.SPQuery
$q.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'> Test </Value> </Contains></Where>";
$list.GetItems($q) | Format-Table Title, ID

Title                       ID
-----                        --
Test 1                    5
Test 2                    6
Test 3                    7
Test 4                    8
Test 5                    9
Test 6                    10

By starting in Windows PowerShell, you can test your CAML query before you add it to your application. You can also determine other potential issues by using Windows PowerShell to test your assumptions about how an object works. For example, if you change the Query attribute of an SPQuery object, any change to your query does not take effect unless you also re-initialize your SPQuery object.

$list.GetItems($q).Count
6
$q.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'> 3 </Value> </Contains></Where>";
$list.GetItems($q).Count
6
$q = New-Object Microsoft.SharePoint.SPQuery
$q.Query = "<Where><Contains><FieldRef Name='Title' /><Value Type='Text'> 3 </Value> </Contains></Where>";
$list.GetItems($q).Count
1

Such unexpected object behavior can be very difficult to troubleshoot when you build an application. By testing in Windows PowerShell first, you get an opportunity to determine the behavior at the command line.

During testing, using Windows PowerShell with SharePoint can be invaluable. You can use Windows PowerShell to quickly script the testing environment. The environment might include webs, sub-webs, lists, and list items, which would be cumbersome to create by hand.

$site = Get-SPSite https://server/site
$listTemplate = [Microsoft.SharePoint.SPListTemplateType]::GenericList
$root = $site.rootWeb;
$sub1 = $root.Webs.Add("Sub1")
   (1..12) | % {
        $sub1.Lists.Add("Test” + $_, "", $listTemplate)
   }

These are only some of the scenarios in which traditional code and Windows PowerShell are used together to create a solution.

In the next section, we examine scenarios where the focus is on writing code.

When Code Is Better

Obviously, Windows PowerShell won’t be a real option in some scenarios. For example, it is highly unlikely that you would create Custom Application Pages, Web Parts, or Web Services by using Windows PowerShell. Similarly, if you want to create a fancy user interface, Windows PowerShell is probably not for you.

One specific scenario that demands an all-code solution is actually a way to extend what you can do in Windows PowerShell. Just as the SharePoint team did for you with the Microsoft.SharePoint.PowerShell module, you can create your own cmdlets to use.

Building a custom cmdlet is beyond the scope of this article, but you can find some great resources available online as well as in the SharePoint SDK for creating your own SharePoint cmdlets. Several base classes are available to you when you create your custom cmdlet, including the following:

  • SPGetCmdletBase

  • SPSetCmdletBase

  • SPNewCmdletBase

  • SPRemoveCmdletBase

  • SPCmdlet

As you explore opportunities to create powerful cmdlets that interact with your SharePoint environment, remember that the ability to run Windows PowerShell scripts requires access to the server (either directly, via remote desktop, or via Windows PowerShell remoting). In many cases, that means elevated permissions. Scenarios often occur in which you want code to run without shell access on the server. Sandbox solutions are a great example of this because they do not require administrator rights to install or execute. SharePoint solutions also let you deploy customizations to multiple servers in a SharePoint farm, something Windows PowerShell cannot easily do.

Conclusion

This article explored how Windows PowerShell can use custom code, how Windows PowerShell can work side-by-side when you develop custom code solutions, and how you can build custom extensions to Windows PowerShell. Although the final decision to use Windows PowerShell or code is in the hands of the solution developer, this article tries to show the benefits of each approach as well as how the two methods can be used together to create a better solution.

About the Author

Raymond Mitchell is a Senior Consultant in Minneapolis, MN and has been working with SharePoint since 2001. He is a coordinator of and frequent speaker at the Minnesota SharePoint User Group and has also spoken at the Wisconsin, Iowa, Nebraska, and St. Louis SharePoint User Groups, as well as several SharePoint Camps/Saturdays. He blogs under the alias IWKID on Information Worker technologies including SharePoint and Office development.

The following were tech editors on Microsoft SharePoint 2010 articles from Wrox:

  • Matt Ranlett is a SQL Server MVP who has been a fixture of the Atlanta .NET developer community for many years. A founding member of the Atlanta Dot Net Regular Guys, Matt has formed and leads several area user groups. Despite spending dozens of hours after work on local and national community activities, such as the SharePoint 1, 2, 3! series, organizing three Atlanta Code Camps, working on the INETA board of directors as the vice president of technology, and appearing in several podcasts such as .Net Rocks and the ASP.NET Podcast, Matt recently found the time to get married to a wonderful woman named Kim, whom he helps to raise three monstrous dogs. Matt currently works as a senior consultant with Intellinet and is part of the team committed to helping people succeed by delivering innovative solutions that create business value.

  • Jake Dan Attis. When it comes to patterns, practices, and governance with respect to SharePoint development, look no further than Jake Dan Attis. A transplant to the Atlanta area from Moncton, Canada, Dan has a degree in Applied Mathematics, but is 100% hardcore SharePoint developer. You can usually find Dan attending, speaking at, and organizing community events in the Atlanta area, including code camps, SharePoint Saturday, and the Atlanta SharePoint User Group. When he's not working in Visual Studio, Dan enjoys spending time with his daughter Lily, watching hockey and football, and sampling beers of the world.

  • Kevin Dostalek has over 15 years of experience in the IT industry and over 10 years managing large IT projects and IT personnel. He has led projects for companies of all sizes and has participated in various roles including Developer, Architect, Business Analyst, Technical Lead, Development Manager, Project Manager, Program Manager, and Mentor/Coach. In addition to these roles, Kevin also managed a Solution Delivery department as a Vice President for a mid-sized MS Gold Partner from 2005 through 2008 and later also served as a Vice President of Innovation and Education. In early 2010 Kevin formed Kick Studios as a company providing consulting, development, and training services in the specialized areas of SharePoint and Social Computing. Since then he has also appeared as a speaker at numerous user group, summit, and conference type events across the country. You can find out more about Kevin on his blog, The Kickboard.

  • Larry Riemann has over 17 years of experience architecting and creating business applications for some of the world’s largest companies. Larry is an independent consultant who owns Indigo Integrations and does SharePoint consulting exclusively through SharePoint911. He is an author, writes articles for publication and occasionally speaks at conferences. For the last several years he has been focused on SharePoint, creating and extending functionality where SharePoint leaves off. In addition to working with SharePoint, Larry is an accomplished .Net Architect and has extensive expertise in systems integration, enterprise architecture and high availability solutions. You can find him on his blog.

  • Sundararajan Narasiman is a Technical Architect with Content Management & Portals Group of Cognizant Technology Solutions, Chennai, with more than 10 years of Industry Experience. Sundararajan is primarily into the Architecture & Technology Consulting on SharePoint 2010 Server stack and Mainstream .NET 3.5 developments. He has passion for programming and also has interest for Extreme Programming & TDD.

Additional Resources