Scripting STSADM with PowerShell
(Update: I had forgotten to specify the -apidtype parameter for the extendvs command. That’s fixed now.)
For this article, I’m assuming at least a vague familiarity with PowerShell. If you have no idea what I’m talking about, there are plenty of resources on TechNet, and some great tutorials by our CTO, Jouni Heikniemi to get you started.
Recently I found myself in a phase of development, where I would try out some modifications to content types, notice that they weren’t what I wanted, and then re-do the entire web application from scratch to make sure my next modifications would be picked up by SharePoint. As you can probably imagine, doing that via the administrative interface got old quickly, so I decided I’d do my best to automate the process.
While SharePoint 2010 ships with a wide variety of PowerShell cmdlets for your scripting pleasure, those SharePoint 2007 installations aren’t going anywhere in some time. This is also a good way to get comfortable with PowerShell, if you don’t have any 2010 projects to work with.
First off, let’s set up some variables and aliases to ease our job:
$webAppUrlWithPort = "${webAppUrl}:80"
$appPoolUser = "TESTDOMAIN\username"
$appPoolPass = "password"
$dbName = "SharePoint_${env:computername}_Content_TestWebApp"
$ownerEmail = "nobody@example.com"
$siteCollectionUrl = "$webAppUrl/siteCollection"
set-alias STSADM "${env:commonprogramfiles}\Microsoft Shared\Web Server Extensions\12\BIN\STSADM.EXE"
Now we’ve got most of the information we need for the various commands we’re about to run. Next up, call STSADM to create the web application:
STSADM -o extendvs `
-url "$webAppUrlWithPort" `
-sethostheader `
-ownerlogin "$appPoolUser" `
-owneremail "$ownerEmail" `
-databaseserver "$env:computername" `
-databasename "$dbName" `
-apidtype ConfigurableID `
-apidname "TestWebApp app pool" `
-apidlogin "$appPoolUser" `
-apidpwd "$appPoolPass" `
-donotcreatesite
iisreset
(Pay attention to the backticks at the end of each line – it’s the PowerShell escape character, and it must be the last character on a line in order to work as a line continuation character.)
As nice as this is, it’s not exactly earth-shattering. In fact, all this could be done just as well with a BAT file. So why bother with PowerShell?
The first problem comes when we want to run this more than once. If I create the site and it already exists, things might get ugly. Then again, if I try to delete it and it doesn’t exist, I’ll get an error message. But where there is a shell, there is a way. STSADM has a habit of returning most of its interesting information as XML, and as it happens, PowerShell is rather adept at handling XML:
I’m invoking the STSADM command “enumalternatedomains”, which lists the web applications we’ve got. It returns a bunch of XML tag soup, but the [xml] cast parses the STSADM output and gives us an object that reflects the structure of the XML document.
Here I’m walking the child items of the XML we got, filtering out only the ones where the URL matches the site we’re trying to create. Now we have a clue as to whether we’ve got something to delete:
echo "Removing old app instance"
STSADM -o unextendvs `
-url "$webAppUrlWithPort" `
-deletecontent `
-deleteiissites
iisreset
}
Now that we’ve got a web application up and running, let’s add a managed path and create a site collection:
STSADM -o addpath `
-url "$siteCollectionUrl" `
-type explicitinclusion
echo "Creating $siteCollectionUrl"
STSADM -o createsite `
-url "$siteCollectionUrl" `
-lcid 1033 `
-owneremail "$ownerEmail" `
-sitetemplate "TestWebApp.Publishing#1" `
-ownerlogin "$appPoolUser"
And finally, if we need to activate features:
STSADM -o activatefeature `
-name "TestWebApp.MasterPages.Default" `
-url "$webAppUrl"
(Note: I’ve tried to consistently quote all the string arguments I’m passing to STSADM, even when it isn’t strictly necessary. For the most part, you could do without the quotes. Also, if you’re wondering why I sometimes say “${webAppUrl}” instead of “$webAppUrl”, the former form is necessary when the variable is inside a string, and directly followed by a character that could be part of the variable name.)
We didn’t go deep into PowerShell here yet, merely spicing up a bunch of STSADM calls with some niceties – but this is just the beginning. In the near future, I’m going to show you how to implement your own PowerShell commands for manipulating things like master pages. Stay tuned!
Popularity: 10% [?]
[...] my previous entry on SharePoint and PowerShell I promised I’d show you how to implement custom commandlets for Master Page manipulation. [...]
Very helpful! Managed to script together a Migrate Users script with this so that it migrates all users meeting a certain criteria instead of manually one user at a time.
Thanks for sharing!
For some strange reason this method does not work in Sharepoint 2010 Powershell. The parameters supplied to stsadm alias are handled as null values and the script throws exception:
Command line error.
The command line is:
stsadmalias –o migrateuser –oldlogin “$AccountName” –newlogin “$NewAccountName”
where stsadmalias is the alias for stsadm, $AccountName and $NewAccountName are two string parameters set correctly before this line. What may I be missing?