SharePoint Create Sites based on Site Collection with Powershell

In SharePoint 2010 and 2013 it is possible to create Site Collections by the UI, using C# Coding or Powershell. In one of our scenarios we had to prepare a web application in which each site collection should get its own Content Database and each site collection should be based on a site collection which already exists in the webapplication as a site collection.

Normally you have to save this site as template, download it, create a new site, upload the template and then you’re done. But that’s not the things administrators, users or developers like to do. We all would like to use a cool Powershell script.

So we created a Powershell Script as function, which does the job using some parameter.
Let’s see the steps it takes:

  1. Check if Content Database exist and create the new one
  2. Create a site collection with the same template in the new content database
  3. Export the template from site collection
  4. Import the template into new site collection
  5. Change the title of the web

Let’s see the code.

[sourcecode language=”csharp”]

Param(
[Parameter(Mandatory=$true)][string]$SiteUrl,
[Parameter(Mandatory=$true)][string]$Title,
[Parameter(Mandatory=$false)][string]$DBName,
[Parameter(Mandatory=$true)][string]$Owner,
[Parameter(Mandatory=$false)][string]$SecondaryOwner,
[Parameter(Mandatory=$false)][string]$DatabaseServer
) #end param
#Define standard values
$TemplateSite = “https:/servername/sites/sitecollectionTemplate”
$TemplateSaveLocation = “C:\TemplateTemp\sitecollection.cmp”

#Add SharePoint PowerShell Snapin
if((Get-PSSnapin | ? {$_.Name -eq “Microsoft.SharePoint.PowerShell”}) -eq $null)
{
Add-PSSnapin Microsoft.SharePoint.PowerShell
}
#############################################
#Function Check-Webapplication              #
#############################################
Function Check-WebApplication($url)
{
#Check if a webapplication exists to create the site in
try
{
$wa = Get-SPWebApplication $Url -ErrorAction “Stop”
Write-Host (“Found webapplication {0}” -f $wa.Url) -ForegroundColor Green
return $wa
}
catch
{
Write-Host (“A webapplication {0} does not exist in this farm” -f $waUrl) -ForegroundColor Red
exit
}
}
#############################################
#End Function Check-Webapplication          #
#############################################

#############################################
#Function Check-Contentdatabase             #
#############################################
function Check-Contentdatabase($name, $dbserver)
{
#Check if the contentdatabase already exists
$db = Get-SPContentDatabase -ErrorAction “Stop” | ? {$_.Name -eq $name}
if($db)
{
if($db.Sites.Count -lt $db.MaximumSiteCount)
{
Write-Host (“Found contentdatabase {0} with sitecount {1} and a maxsitecount of {2}” -f $db.Name, $db.CurrentSiteCount, $db.MaximumSiteCount) -ForegroundColor Green
}
else
{
Write-Host (“Contentdatabase {0} is full it contains {1} of {2} sites” -f $db.Name, $db.CurrentSiteCount, $db.MaximumSiteCount) -ForegroundColor Red
exit
}
}
else
{
if($dbserver)
{
Write-Host (“Creating contentdatabase {0} on server {1}” -f $DBName, $dbserver) -ForegroundColor Green
$db = New-SPContentDatabase -WebApplication $wa -Name $DBName -DatabaseServer $dbserver -MaxSiteCount 1 -WarningSiteCount 0
}
else
{
Write-Host (“Creating contentdatabase {0}” -f $DBName) -ForegroundColor Green
$db = New-SPContentDatabase -WebApplication $wa -Name $DBName -MaxSiteCount 1 -WarningSiteCount 0
}
return $db
}
}
#############################################
#End Function Check-Contentdatabase         #
#############################################

#############################################
# Function Create-Folder                    #
#############################################
function Create-Folder([string]$Loc)
{
if($Loc -ne $null)
{
$LocPath = Split-Path $Loc -Parent
if(!(Test-Path $LocPath))
{
New-Item $LocPath -ItemType Directory
return “new”
}
else
{
return “old”
}
}
}
#############################################
#End Function Create-Folder                 #
#############################################

#Extract Web Application Url from SiteUrl
$waUrl = $SiteUrl.Substring(0, $SiteUrl.IndexOf(“/”, $SiteUrl.IndexOf(“:”)+3))
#Check if a webapplication exists to create the site in
$wa = Check-WebApplication $waUrl

#Check if a contendatabase name was specified
if($DBName)
{
#Check if the contentdatabase already exists
$db = Check-Contentdatabase $DBName -dbserver $DatabaseServer
$newdb = $true
}
else
{
$newdb = $false
Write-Host (“No Database specified, checking available databases”) -ForegroundColor Yellow
$availableDBs = Get-SPContentDatabase -WebApplication $wa | ? {$_.CurrentSiteCount -lt $_.MaximumSiteCount} | sort @{Expression={$_.CurrentSiteCount / $_.MaximumSiteCount}}
if($availableDBs)
{
if($availableDBs.GetType().Name -ne “SPContentDatabase”)
{
$db = $availableDBs[0]
}
else
{
$db = $availableDBs
}
Write-Host (“Found database{0} to store the site in” -f $db.Name) -ForegroundColor Green
}
else
{
Write-Host (“There are no databases to store the site in”) -ForegroundColor Red
return
}
}
try
{
#Create the site collection
Write-Host (“Creating Site Collection {0}” -f $SiteUrl) -ForegroundColor Green
New-SPSite -URL $SiteUrl -OwnerAlias $Owner -SecondaryOwnerAlias $SecondaryOwner -ContentDatabase $db -Language 1031 -Template STS#1 -ErrorAction “Stop”
Write-Host (“Site Collection {0} Created Sucessfully” -f $SiteUrl) -ForegroundColor Green

Write-Host (“Exporting Site Collection”) -ForegroundColor Green
$FolderStatus = Create-Folder $TemplateSaveLocation
Export-SPWeb -identity $TemplateSite -path $TemplateSaveLocation -force -includeusersecurity
Write-Host (“Exported Site Collection Sucessfully”) -ForegroundColor Green

#Import the site to the new site collection
Write-Host (“Importing into new Site Collection”) -ForegroundColor Green
Import-SPWeb -Identity $SiteUrl -Path $TemplateSaveLocation -includeusersecurity -force
Write-Host (“Imported Sucessfully”) -ForegroundColor Green

if($TemplateSaveLocation -ne $null)
{
if($FolderStatus -eq “new”)
{
$FolderPath = Split-Path $TemplateSaveLocation -Parent
Remove-Item $FolderPath -Recurse -Force
}
else
{
Remove-Item $TemplateSaveLocation
Remove-Item “$($TemplateSaveLocation).export.log”
Remove-Item “$($TemplateSaveLocation).import.log”
}
}

#Change Title of Website
Write-Host (“Changing Title of the site to {0}” -f $Title) -ForegroundColor Green
$Web = Get-SPWeb $SiteUrl
$Web.TitleResource.SetValueForUICulture(1031, $Title)
$Web.Update()

}
catch
{
Write-Host (“Could not create sitecollection”) -ForegroundColor Red
if($newdb)
{
Write-Host (“Removing contentdatabase {0}” -f $db.Name) -ForegroundColor Yellow
Remove-SPContentDatabase $db
}
}

[/sourcecode]

That’s it. Pretty cool. You can use the script and expand it. Just call the script with the parameters and it will do the job.

The article or information provided here represents completely my own personal view & thought. It is recommended to test the content or scripts of the site in the lab, before making use in the production environment & use it completely at your own risk. The articles, scripts, suggestions or tricks published on the site are provided AS-IS with no warranties or guarantees and confers no rights.

About Karsten Schneider 312 Articles
Consultant for Microsoft 365 Applications with a strong focus in Teams, SharePoint Online, OneDrive for Business as well as PowerPlatform with PowerApps, Flow and PowerBI. I provide Workshops for Governance & Security in Office 365 and Development of Solutions in the area of Collaboration and Teamwork based on Microsoft 365 and Azure Cloud Solutions. In his free time he tries to collect tipps and worthy experience in this blog.

Be the first to comment

Leave a Reply