In this post I explain how to use PowerShell to create a full SharePoint (2010 or 2013) training site or testing site environment. This is the process I used to prepare for a recent SharePoint training course where I needed each of my users to have their own site collection in my environment. I was expecting 30 participants and each site collection needed to have a few features activated, have three sub sites, have permissions set and be prepopulated with some sample documents. I knew right away that I was too lazy to do all the work manually for every training class hosted by our company. And, I couldn't guarantee that I would do it exactly right every time, so I reverted back to my old friend PowerShell for help.

I'll walk you through each section of the script below. I've also compiled the entire script together at the end of this post to make it easy for you to copy and paste. On a side note, this process could also be used to create testing environments where you want the set up to be exactly the same every time. You could also get fancy with site columns and content types, but we were going to cover that in my course so I didn’t want it set up beforehand.

Step-by-Step Instructions:

First, we are going to create an array with our site collection titles and set a base URL variable. You could easily just slap an incrementing number at the end instead of doing this, however, I wanted to leave it open to include the participants name as the site collection name. I want them all to be located under the /sites managed path, so that’s the purpose of the $baseURL variable.

$siteArray = ("Student1", "Student2", "Student3", "Student4", "Student5", "Student6", "Student7", "Student8", "Student9", "Student10", "Student11", "Student12", "Student13")
$baseURL = ""



Next, we’ll loop through each item in our site array to create the site collections and set the options.

foreach($site in $siteArray)

OK, so now we can construct the URL for our site collection and get it created.

     $siteURL = $baseURL + "/" + $site
     New-SPSite $siteURL -Name "Training Sites - $site" -OwnerAlias "contoso\administrator"  
     -ContentDatabase "SP10_Content_Training" -Template "STS#0"



For my training, I need the publishing infrastructure and workflows features activated.

Enable-SPFeature -Identity "f6924d36-2fa8-4f0b-b16d-06b7250180fa" -Url $siteURL #publishing infrastructure
Enable-SPFeature -Identity "0af5989a-3aea-4519-8ab0-85d91abe39ff" -Url $siteURL #workflows



I want the global navigation to include sub sites, which I’ll create in a few minutes, so set that now.

$web = Get-SPWeb $siteURL
$pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$pubWeb.Navigation.GlobalIncludeSubSites = $true



I want to have some sub sites, so let's create those now using a couple of arrays again to hold our values.

$subSiteArray = ("hr", "finance", "rd")
$subSiteArrayNames = ("Human Resources", "Finance", "Research and Development")
foreach($subSite in $subSiteArray)
    $subURL = $siteURL + "/" + $subSite
    New-SPWeb -url $subURL -Template "STS#0" -Name $subSiteArrayNames[$i] 
-Addtoquicklaunch -UseParentTopNav



Now, I need to get some sample documents in my site to work with. This code will grab all the files in the c:\documents folder and upload them to the Shared Documents library.

$docLib = $web.GetFolder("Shared Documents");
$files = get-childitem "C:\Users\Administrator\Documents\Scripts\Build Training 
Write-Host "Retrieved files..."
foreach($file in $files)
    $bytes = get-content $file.FullName -encoding byte
    $docLib.Files.Add($file.Name,$bytes, $true) > $null
    Write-Host "Added $file.Name successfully..."

We have our site collection, sub sites and documents so it's time to add permissions. I’m going to create an owners group and a visitors group. I’ll just let it put me in the owners group, then add all domain users to the visitors group.

$web.SiteGroups.Add("$site Owners", $web.Site.Owner, $web.Site.Owner, “Use this group 
to grant people full control permissions to the $web site”)
$ownerGroup = $web.SiteGroups["$site Owners"]
$ownerGroup.AllowMembersEditMembership = $true
#Give the owners group rights to the site and allow members to edit membership
$ownerGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment($ownerGroup)
$ownerRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Full Control"]
#Create a Visitors Group
$web.SiteGroups.Add("$site Visitors", $web.Site.Owner, $web.Site.Owner, “Use this 
group to grant people read permissions to the $web site”)
$visitorGroup = $web.SiteGroups["$site Visitors"]
#Give the Visitors group rights to the site
$visitorGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment
$visitorRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Read"]
#Give all domain users read rights to the site collection
New-SPUser -UserAlias "contoso\domain users" -Web $siteURL -Group "$site Visitors"



OK, so that does it. Now I can just run this script before each training class to crank out as many identical site collections as I need in less than five minutes. Work smarter, not harder.

As promised, here is the complete script for you:

   1:    #Add SharePoint PowerShell SnapIn if not already added
   2:    if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue)
         -eq $null) {
   3:    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
   4:    }
   6:    #Add items to this array for each site collection that is needed
   7:    $siteArray = ("Student1", "Student2", "Student3", "Student4", "Student5", 
         "Student6", "Student7", "Student8", "Student9", "Student10", "Student11", 
         "Student12", "Student13")
   8:    $baseURL = ""
  10:    #Loop through the array above and create the site collections
  11:    foreach($site in $siteArray)
  12:    {
  13:    $siteURL = $baseURL + "/" + $site
  14:    New-SPSite $siteURL -Name "Training Sites - $site" -OwnerAlias "
         contoso\administrator" -ContentDatabase "SP10_Content_Training" -Template "STS#0"
  16:    #Enable publishing infrastructure and workflows
  17:    Enable-SPFeature -Identity "f6924d36-2fa8-4f0b-b16d-06b7250180fa" -Url $siteURL 
         #publishing infrastructure
  18:    Enable-SPFeature -Identity "0af5989a-3aea-4519-8ab0-85d91abe39ff" -Url $siteURL 
  20:    #Set the top level site navigation to include subsites
  21:    $web = Get-SPWeb $siteURL
  22:    $pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
  23:    $pubWeb.Navigation.GlobalIncludeSubSites = $true
  24:    $pubWeb.Update()
  26:    #Create a few subsites to get content in the site
  27:    $subSiteArray = ("hr", "finance", "rd")
  28:    $subSiteArrayNames = ("Human Resources", "Finance", "Research and Development")
  30:    $i=0
  31:    foreach($subSite in $subSiteArray)
  32:    {
  33:    $subURL = $siteURL + "/" + $subSite
  34:    New-SPWeb -url $subURL -Template "STS#0" -Name $subSiteArrayNames[$i] -
         Addtoquicklaunch -UseParentTopNav
  35:    $i++
  36:    }
  38:    #Copy sample documents to the site collection
  39:    $docLib = $web.GetFolder("Shared Documents");
  40:    $files = get-childitem "C:\Users\Administrator\Documents\Scripts\Build Training 
  41:    Write-Host "Retrieved files..."
  43:    foreach($file in $files)
  44:    {
  45:    $bytes = get-content $file.FullName -encoding byte
  46:    $bytes=byte$bytes
  47:    $docLib.Files.Add($file.Name,$bytes, $true) > $null
  48:    Write-Host "Added $file.Name successfully..."
  49:    }
  51:    #Create an Owners Group
  52:    $web.SiteGroups.Add("$site Owners", $web.Site.Owner, $web.Site.Owner, “Use this 
         group to grant people full control permissions to the $web site”)
  53:    $ownerGroup = $web.SiteGroups["$site Owners"]
  54:    $ownerGroup.AllowMembersEditMembership = $true
  55:    $ownerGroup.Update()
  57:    #Give the owners group rights to the site and allow members to edit membership
  58:    $ownerGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment
  59:    $ownerRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Full Control"]
  60:    $ownerGroupAssignment.RoleDefinitionBindings.Add($ownerRoleDefinition)
  61:    $web.RoleAssignments.Add($ownerGroupAssignment)
  63:    #Create a Visitors Group
  64:    $web.SiteGroups.Add("$site Visitors", $web.Site.Owner, $web.Site.Owner, “Use this 
         group to grant people read permissions to the $web site”)
  65:    $visitorGroup = $web.SiteGroups["$site Visitors"]
  67:    #Give the Visitors group rights to the site
  68:    $visitorGroupAssignment = new-object Microsoft.SharePoint.SPRoleAssignment
  69:    $visitorRoleDefinition = $web.Site.RootWeb.RoleDefinitions["Read"]
  70:    $visitorGroupAssignment.RoleDefinitionBindings.Add($visitorRoleDefinition)
  71:    $web.RoleAssignments.Add($visitorGroupAssignment)
  73:    #Give all domain users read rights to the site collection
  74:    New-SPUser -UserAlias "contoso\domain users" -Web $siteURL -Group "$site Visitors"
  76:    $web.Update()
  77:    $web.Dispose()
  78:    }

If you would like more information on C5 Insight or this blog content, fill out our Contact form.