SharePoint automation with PowerShell

I spent a lot of time automating SharePoint when the company I work for installed SharePoint Portal Server 2003, so I was quite disappointed when SharePoint version 3 was released without PowerShell support – after all, Exchange 2007 managed it and it’s part of the Office 2007 Server suite, so why didn’t the other server products?

On a positive note though, I did find that stsadm.exe had been extended to now support a lot more operations:

[C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN]
3> .\stsadm.exe –help

Usage:
stsadm.exe -o <operation> [<parameters>]
stsadm.exe -help [<operation>]

Operations:


activatefeature
addalternatedomain
addcontentdb
addpath
addpermissionpolicy
addsolution
addtemplate
adduser
addwppack
addzoneurl
authentication
backup
backuphistory
binddrservice
blockedfilelist
canceldeployment
changepermissionpolicy
copyappbincontent
createadminvs
creategroup
createsite
createsiteinnewdb
createweb
databaserepair
deactivatefeature
deleteadminvs
deletealternatedomain
deleteconfigdb
deletecontentdb
deletegroup
deletepath
deletepermissionpolicy
deletesite
deletesolution
deletetemplate
deleteuser
deleteweb
deletewppack
deletezoneurl
deploysolution
deploywppack
disablessc
displaysolution
email
enablessc
enumalternatedomains
enumcontentdbs
enumdeployments
enumgroups
enumroles
enumservices
enumsites
enumsolutions
enumsubwebs
enumtemplates
enumusers
enumwppacks
enumzoneurls
execadmsvcjobs
export
extendvs
extendvsinwebfarm
forcedeletelist
getadminport
getproperty
getsitelock
geturlzone
import
installfeature
listlogginglevels
localupgradestatus
managepermissionpolicylevel
migrateuser
provisionservice
refreshdms
refreshsitedms
registerwsswriter
removedrservice
removesolutiondeploymentlock
renameserver
renameweb
restore
retractsolution
retractwppack
scanforfeatures
setadminport
setapppassword
setconfigdb
setlogginglevel
setproperty
setsitelock
setworkflowconfig
siteowner
spsearch
spsearchdiacriticsensitive
syncsolution
unextendvs
uninstallfeature
unregisterwsswriter
updateaccountpassword
updatealerttemplates
updatefarmcredentials
upgrade
upgradesolution
upgradetargetwebapplication
userrole

For information about other operations and parameters,
use “stsadm.exe -help” or “stsadm.exe -help <operation>”

But how useful are these commands? Consider the example of enumsites – this command lists all Site Collections or a given Web Application.

PowerShell Basics – Running Scripts

One of the comments I had on a post I did last week was about how to run scripts. It’s a fair point, somebody new to PowerShell will find it a little odd that they can’t just run a script found on the Internet – I find it reassuring.

On a newly installed PowerShell system, running a script will result in something like the following:

[D:\PsScripts]
1> & D:\PsScripts\test-scriptExecution1.ps1
File D:\PsScripts\test-scriptExecution1.ps1 cannot be loaded because the execution of scripts is disabled on this syste
m. Please see “get-help about_signing” for more details.
At line:1 char:38
+ D:\PsScripts\test-scriptExecution1.ps1 <<<<

Understanding the Execution Policy

The reason for this is the Execution Policy in place on the machine prevents all scripts from running by default. There are 4 Execute Policies defined in PowerShell, according to the help files, they are:

  • Restricted – Does not load configuration files or run scripts. “Restricted” is the default.
  • AllSigned – Requires that all scripts and configuration files be signed by a trusted publisher, including scripts that you write on the local computer.
  • RemoteSigned – Requires that all scripts and configuration files downloaded from the Internet be signed by a trusted publisher.
  • Unrestricted – Loads all configuration files and runs all scripts. If you run an unsigned script that was downloaded from the Internet, you are prompted for permission before it runs.

To control execution policies, PowerShell ships with a couple of cmdlets Get-ExecutionPolicy and Set-ExecutionPolicy. They basically do what they say on the tin:

Goodbye Windows Live Spaces – Hello CaptainLiteral.NET!

I’m moving my blog away from Windows Live Spaces to CaptainLiteral.NET, so if anybody has subscribed to my feed, then you’d best update it to point at http://feeds.feedburner.com/CaptainLiteral. I’ve also set-up a FeedBurner thing for my RSS, so people won’t be hit by changes in the future.

Why Captain Literal? The guys as work call me Captain Literal because lunchtime conversations’ can go something like this:
Dan: “You can’t reboot a computer on a plane, it’ll crash,” followed by a hand movement to indicate that a plane would fall from the sky.
Mark (aka Captain Literal): “That’s why life-critical systems such as planes have multiple fail-safe’s on them. The space shuttle for example has multiple computers and they all vote on what’s going to happen. You could reboot one of those with no problems and the shuttle wouldn’t spiral off into outer-space.”
So that’s it, I have been nick-named Captain Literal and now Mark really is CaptainLiteral.NET.

Before I go out on a rant and document why I’m moving away from Spaces, I first need to thank Ashleigh (http://www.nakedcleaner.com) for firstly, hosting CaptainLiteral.NET. Secondly, for forcing me to setup CaptainLiteral.NET. And thirdly, for spending time last night actually setting up CaptainLIteral.NET – thanks Ashleigh.

And now for the fun bit – why am I leaving Windows Live Spaces?

Live Spaces has some things that merely annoying – these are the things that one can live with. But it also has some things that are very annoying – things that, when realised, encourage you to drop Windows Live Spaces and go look for some other blog provisioning service or friend to host for you.

Contact Form

Fill in the form below, and I will get back to you. 

(required)
(required)

 

Sudoku Vs PowerShell

I’ve been obsessed since Adrian (ps1.soapyfrog.com) posted his Sudoku solving PowerShell script a couple of weeks ago. When I first read his post on the subject, I pulled down his script and ran it - at the time he didn’t know how long it would take to solve the harder of the two puzzles he posted - after about an hour PowerShell had crashed on my computer! Since then Adrian has posted saying that his script takes 1.2 days to solve his harder puzzle!

Having peeked at his script I quickly discovered that it works on a brute-force principle (i.e. if you don’t know what number you should have in a square, guess), this seemed to work well for the easier of his samples (solved in less than a second). I decided that I’d see if I could do better and learn a few things along the way. And so started my obsession with implementing a speedy Sudoku solver in PowerShell – this shouldn’t have taken two weeks, but work, life and a couple of other things got in the way. I swear, I don’t know how people play with technology and constantly post about it.

To start with, I had no idea how to solve a Sudoku puzzle with a computer, yet alone in PowerShell – Enter a trusty search engine to the rescue. I quickly found Andrew’s Sudoku solver. Now, what’s interesting about Andrew’s site is that he not only solves Sudoku, he shows you step by step how to do it and he’s published over 30 different strategies for solving Sudoku, complete with pictures. J

PowerShell Community Extensions and x64

PowerShell Community Extensions is a great addition to PowerShell that supplements the out-of-the box set of cmdlets. However, it doesn’t work out-of-the-msi on an x64 platform.

When installing, I opted to use the Shared Profile, but got the following when I tried to run PowerShell:

Windows PowerShell
Copyright (C) 2006 Microsoft Corporation. All rights reserved.
Add-PSSnapin : Windows PowerShell snap-in Pscx is not installed on the machine.
At C:\Documents and Settings\Mark\MyDocs\WindowsPowerShell\profile.ps1:38 char:13
+ Add-PSSnapin <<<< Pscx

Transcript started, output file is C:\Documents and Settings\Mark\MyDocs\WindowsPowerShell\Transcripts\20070102.1
43613.7364.txt
[C:\Documents and Settings\Mark]
1> Get-PSSnapin
Name : Microsoft.PowerShell.Core
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains Windows PowerShell management cmdlets used to manage components
of Windows PowerShell.
Name : Microsoft.PowerShell.Host
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains cmdlets used by the Windows PowerShell host.
Name : Microsoft.PowerShell.Management
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains management cmdlets used to manage Windows components.

Name : Microsoft.PowerShell.Security
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains cmdlets to manage Windows PowerShell security.

Name : Microsoft.PowerShell.Utility
PSVersion : 1.0
Description : This Windows PowerShell snap-in contains utility Cmdlets used to manipulate data.

[C:\Documents and Settings\Mark]
2> Get-PSSnapin -Registered

Name : PowerGadgets
PSVersion : 1.0
Description : Generates Charts, Gauges and Maps Gadgets from Windows PowerShell data

Well the snap-in isn’t registered on my system, let’s try PowerShell (32bit):

PowerShell System Uptime

I just needed to know how long it was since my box was last rebooted. Windows Vista has a nice feature where this is now a property of the Performance tab in Task Manager. But alas, there’s no such nice functionality in Windows 2K3. Usually I end up in PerfMon to get the number of seconds the box has been up and then in calculator to convert this into real time.

Enter PowerShell to the rescue:

function GLOBAL:Get-SystemBootupTime([String]$computer=”localhost”) {
  $wmiOsInformation = Get-WmiObject -computer $computer -class Win32_OperatingSystem
  $wmiOsInformation.ConvertToDateTime($wmiOsInformation.LastBootUpTime)
}

function GLOBAL:Get-SystemUptime([String]$computer=”localhost”) {
  $wmiPerfOsSystem = Get-WmiObject -computer $computer -class Win32_PerfFormattedData_PerfOS_System
  $wmiPerfOsSystem.SystemUpTIme
}

# Get System Bootup time
PS C:\> Get-SystemBootupTime
21 December 2006 17:16:02

# Get system uptime in seconds
PS C:\> Get-SystemUptime
1016328

Not bad, I can now see the system uptime in seconds, but I want the result formatted

function GLOBAL:Get-SystemUptimeFormatted([String]$computer=”localhost”) {
  $wmiPerfOsSystem = Get-WmiObject -computer $computer -class Win32_PerfFormattedData_PerfOS_System
[TimeSpan] $systemUptime = New-TimeSpan -seconds $wmiPerfOsSystem.SystemUpTIme
  [String]::Format(”{0:G}”, $systemUptime)
}

PS C:\> Get-SystemUptimeFormatted
11.18:53:16

Job done! As a developer, I tend towards using .NET all over, so I’ve probably missed some rather subtle ways of achieving the formatting with PowerShell.

You can get a lot of other useful information from the WMI classes that could be the focus of other functions:

PS C:\> $computer = “localhost”
PS C:\> $wmiOsInformation = Get-WmiObject -computer $computer -class Win32_OperatingSystem
PS C:\> $wmiOsInformation SystemDirectory : C:\WINDOWS\system32
Organization : My Org
BuildNumber : 3790
RegisteredUser : Me
SerialNumber : xxxxx-xxx-xxxxxxx-xxxxx
Version : 5.2.3790