A PowerShell script to automate the creation of SharePoint site collections

I must admit it. I’ve never really done anything with PowerShell.
Sure, the Macaw Solutions Factory is largely based on PowerShell, but I usually just use that as-is, or make minor changes to existing scripts.
So starting to work with PowerShell for SharePoint is all new. I read a PowerShell book over the summer holidays to get a little bit of an understanding about PowerShell, but as everyone knows, reading about it is very different from actually using it and doing it hands on. So last week I took my first baby steps in using SharePoint and PowerShell. If you’re a seasoned PowerShell user this post is probably not for you, but if you are, like me, just starting to get familiar with PowerShell you might find the information in here useful.

The goal was to create site collections for everyone in our department. The urls of the site collections are the first names/account names of my team members and of course I didn’t want to type in the same lines 25 times.

  1 $snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
  2 
  3 if ($snapin -eq $null)
  4 {
  5     cd 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\POWERSHELL\Registration'
  6     .\SharePoint.ps1
  7 }
  8 
  9 $users = "john", "paul", "mirjam"
 10 
 11 foreach ($user in $users)
 12 {
 13     New-SPSite -Url "http://iws.macaw.nl/sites/$user" -OwnerAlias "DOMAIN\$user" -Name "Portal" -Template "STS#0" 
 14     Write-Output "Site created for $user" 
 15 } 

Before we can use the SharePoint PowerShell cmdlets we need to load the Microsoft.SharePoint.PowerShell snapin. We can accomplish this by loading the SharePoint.ps1 file or by adding the directly. If you try to add a snapin that is already added PowerShell will throw an error telling you that. Even though the script will continue after throwing the error without problems I didn’t like seeing the error, so I build in a test that checks if the snapin was already added. There might be a better way to test this, but I couldn’t find one, so I ended up filtering the collection of registered snapins on snapins with the name “Microsoft.SharePoint.PowerShell”. If the resulting collection contains an item (has more than 0 items in it) the snapin is already registered.

[Update]: I adjusted the “if” statement according to the statement Leon posted in the comments (thanks Leon!). This test first gets the snapin where the name of the snapin equals Microsoft.SharePoint.PowerShell. It adds the results to the @snapin variable. Next the if statement checks whether there is actually a snapin in the @snapin variable, or whether it is NULL. As you can see in Leon’s script you can also choose to add the Microsoft.SharePoint.PowerShell snapin directly, but there is some other magic in the SharePoint.ps1 file and since I didn’t know what that was for I decided to just load the .ps1 file completely.

Next I define an array of users. There are far more spiffy ways to do this, like for instance reading the names from a file, but I decided that this would do for now.

Now we can loop through all users in the array and create a new site for each user. The urls of each site are http://iws.macaw.nl/sites/[[username]], so the url of my site is http://iws.macaw.nl/sites/mirjam. Note how I use double quotes around the url. Because I use double quotes PowerShell replaces the variable name $user by its contents and uses that in the string. If you use single quotes PowerShell will leave the string alone and the url would be http://iws.macaw.nl/sites/$user. The same principle is used for the owneralias and the output stating that the site for this user was created.

I hope this helps people. If you have improvements or additions to the script feel free to post them in the comments!