Making SharePoint 2010 PowerShell Scripts Backward-Compatible with 2007


Recently I received an e-mail from one of my ICC SharePoint team-mates asking for some PowerShell code to create and then delete a lot of list items. Like 20000. Well, I already had code to create the list items – so it was easy to add a single line to call the delete() method immediately after the item was added.

I provided the updated function to my teammate, only to find out later that they wanted to do this in MOSS 2007 – not SP2010. Oops! I hadn’t considered that, I assumed since they were asking me for PowerShell code that they were dabbling in a 2010 environment. Not the case. However, this particular person is one of our better SharePoint Developers and quickly modified the code to work in MOSS.

After having that discussion, it became clear to me that it would be REALLY cool to create PowerShell Scripts and Functions that would work both in V4 as well as V3. And the journey began..

After some experimentation, googling, trial & error – it became apparent that this isn’t rocket science. In SharePoint 2010 we use the following PowerShell cmdlet to add the SharePoint Snap-in:

Add-PSSnapIn Microsoft.SharePoint.PowerShell

There’s no equivalent for MOSS environments, but we can load the SharePoint assemblies by using the following line of code:

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

Once we’ve done that, we can do other things such as get the farm build version and tell us what version we’re working with:

function Get-SPFarmBuildVersion {
# using the [microsoft.sharepoint.administration.spfarm] line to get the local farm regardless of version #
# this works in 2007 and 2010 #
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$farmBuild = $farm.BuildVersion.ToString()

      if ($farmBuild.StartsWith("12")) {
      Write-Host "This is WSS or MOSS"
      } 
      
      elseif ($farmBuild.StartsWith("14")) {
      Write-Host "This is SP2010"
      }

}

How cool is that!?

Now that we know that simple tidbit, we can easily create our scripts and functions with backward compatibility in mind by doing something like if/elseif as seen above. Developers may chime in with a better way, I’m sure there are better – perhaps more elegant approaches to this same theory – but this works for me for now.

Anyhow, back to the story – my developer friend Aaron wanted to create list items in MOSS using PowerShell. Here’s the code to do that – and it’s backwards compatible!

function Add-MultipleListItems {
[CmdletBinding()]
Param(
[string]$ListName=(Read-Host "Please enter the name of the list you wish to add to."),
[string]$Amount=(Read-Host "Please enter a number of list items to create."),
[string]$Choices=(Read-Host "Please enter choices separated by semicolons, enclosed in double quotes."),
[string]$ListItem=(Read-Host "Please enter a string for the title of each list item (Example: Added by Powershell)"),
[string]$WebUrl=(Read-Host "Please enter a URL of a SharePoint site (Example: http://intranet)")
)

$choicesForCategory = $Choices -split ";"

$assemblies = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$farm = [Microsoft.SharePoint.Administration.SPFarm]::Local
$farmBuild = $farm.BuildVersion.ToString()
	
	if ($farmBuild.StartsWith("14")) {
		Start-SPAssignment -Global
		$mylist = (Get-SPWeb -identity $webUrl -AssignmentCollection $StartSpAssignment).Lists[$listName]
		Write-Host "Creating $amount list items in $listName" -ForegroundColor Green
		$i = 1
		do 
		{
		    $newItem = $mylist.Items.Add()
		    $newItem["Title"] = $listItem
		    $newItem["Category"] = $choicesForCategory | Get-Random
		    $newItem.Update()
		    $i++
		}
		while ($i -le $amount)

		Write-Host "Finished!" -ForegroundColor Green
		Stop-SPAssignment -Global
	}
	elseif ($farmBuild.StartsWith("12")) {
		$SPWeb = Get-SPWeb $webUrl
		$mylist = $SPWeb.Lists[$listName]
		Write-Host "Creating $amount list items in $listName" -ForegroundColor Green
		$i = 1
		do 
		{
		    $newItem = $mylist.Items.Add()
		    $newItem["Title"] = $listItem
		    $newItem["Category"] = $choicesForCategory | Get-Random
		    $newItem.Update()
		    $i++
		}
		while ($i -le $amount)
		$SPWeb.dispose()
		Write-Host "Finished!" -ForegroundColor Green
	}
}

If you read this line by line, you’ll notice that they are fundamentally identical. Really the only difference is in V3 we don’t get any cmdlets, so we don’t have Start-SPAssignment and Stop-SPAssignment. This just means we have to make sure we’re disciplined to use dispose() methods for any SPWeb and SPSite objects.

With all that in mind, my goal from here on out is to try and make any and all PowerShell code backwards compatible.

RD

Advertisements

First 2010 Implementation Complete! (Well, sort of)


As of 11/3/2010, my first “real” 2010 implementation is complete for my current client. This implementation was a small farm consisting of a SQL database server and a single SharePoint server (both VMs).

The SharePoint 2010 VM is Windows Server 2008 R2 with 8GB of RAM and it is an Enterprise license.

The migration was from MOSS 2007 Enterprise and I utilized the database attach method for the migration piece. In total, there were 3 content databases, 2 web applications and 76 site collections with a few hundred subwebs.

So far so good and the migration itself was very smooth.

Now the real fun begins, utilizing the new 2010 functionality!

Copy SharePoint Navigation across Site Collections


Have you every been tasked with consistent top-level navigation across Site Collections? Sure you have, we all have! Have you heard about the Gary Lapointe STSADM Extensions? I just recently found out about them, and I’m glad I did…

Without Gary’s extensions, you must manually enter the navigation on each site collection; no fun. With Gary’s extensions, you can copy the navigation from a source site collection to as many destination site collections as your heart desires.

This recently saved me a TON of time and since it’s an STSADM command, it can easily be scripted, scheduled, etc. The possibilities are truly endless.

I only used one of Gary’s 144 commands (gl-copynavigation), so I’m sure there is a ton of stuff that these can do that I don’t know of. Have you used these before? Tell me your success stories!

Gary LaPointe:
http://stsadm.blogspot.com/2007/08/stsadm-commands_09.html

CSS version 3 adds some cool functionality!


If you don’t do much with theming and cascading style sheets, you probably don’t know or care that CSS 3 is coming fast. Some browsers already support it (Firefox 3.x, Safari), some don’t (IE); but the feature-set in CSS 3 is something that will make designers and developers very happy.

Here are the features I’ve played with so far in my demo environment:

Border-radius

Box-shadow

Text-shadow

Opacity

Pretty cool stuff, here’s a screenshot of the page I’ve been messing with (viewed in Firefox 3.5.9):

Add simple, one-column list search functionality to SharePoint


Awhile back I was working with a client who needed to manage a simple, two-column custom list. The task was simple, manage company acronyms. The list took no time to create as I imported it from the source spreadsheet, it was two columns; Acronym and Acronym Meaning.

The cool, easy solution was this:

1. Create a new page
2. Add 3 Web Parts to the page, List View (viewing the Acronym list), Form Web Part and Content Editor Web Part.
3. Configured the Form Web Part to connect to the List View WP on the Acronym column.
4. Configured the CEWP with a link to Add A New Acronym (in case the acronym they were searching for didn’t exist)

The final product allowed a user to enter an acronym (AD for example) and it would pull back the appropriate acronym, i.e.:

AD – Active Directory

Quick, simple solution for employees to quickly search acronyms.