Wednesday, October 4, 2017

Move/Copy subsite to another site collection using PowerShell

Using SharePoint Server 2010;


Requirement:
We have a requirement to migrate SharePoint 2010 to SharePoint 2016. The existing SharePoint server 2010 have a subsite which has more subsites on it and the size is huge. We want to copy or move this subsite to a new site collection before we migrate the entire content to SP2016.

Note: Make sure you backup the existing content database and delete the subsite manually after verify the copy.


Solution:
Following powershell script is used to copy the subsite to new site collection which:
  1. Create a new content database
  2. Create a new site collection and attach to the new content database
  3. Export the subsite
  4. Import the subsite to the new site collection


PowerShell Script:

param
(
 $webApp = "http://sp2010-prasath:3333", #Web Application  URL
 $DBServer = "sp2010-prasath", #Database Server to create new content DB
 $DBName = "WSS_Content_Projects", #Content DB Name
 $subSiteURL = "http://sp2010-prasath:3333/Projects/", #Subsite URL
 $backupPath = "C:\\Sub Site Backup\\SandboxSubsSite.cmp", #Backup file
 $newSCURL = "http://sp2010-prasath:3333/sites/projects", #New site collection URL
 $SCOwner = "sp2010-prasath\spadmin", #Site Collection Administrator Account
 $errMessage = ""
)


Try
{
#Create new content database
$errMessage = "creating new Content Database"
$scGUID = New-SPContentDatabase $DBName -DatabaseServer $DBServer -WebApplication $webApp -ErrorAction Stop
Write-host "Content Database has been created successfully!"


#Create new site collection in the new content database
$errMessage = "creating new Site Collection"
$template = Get-SPWebTemplate "STS#0"  -ErrorAction Stop
$newSite = New-SPSite -Url $newSCURL -OwnerAlias $SCOwner -Template $template -ContentDatabase $scGUID.Id -ErrorAction Stop
Write-host "Site Collection has been created successfully!"


#Export/Backup existing subsite
$errMessage = "exporting subsite"
$export = Export-SPWeb -Identity $subSiteURL -Path $backupPath -IncludeUserSecurity -IncludeVersions all -HaltOnError -Force -ErrorAction Stop
Write-host "Subsite export successful"


#Import subsite to new site collection
$errMessage = "importing subsite to new Site Collection"
Import-SPWeb $newSCURL -Path $backupPath -ErrorAction Stop
Write-host "Import successful"
}
Catch
{
Write-host "Error occurred while" $errMessage
Write-host "Error Message:" $_.Exception.Message
}


Run the script in PowerShell

subsite to site collection

Friday, September 22, 2017

Storage Metrics using PowerShell

Using SharePoint Server 2010, 2013;

Introduction

Storage Metrics in the Site Collection Administration page can be used to access the storage consumed by all your sub-sites and libraries. The same can also be retrieved using Power Shell cmdlet. The following script retrieves storage information of each subsites as the default feature has no option to filter the metrics data. Additional information like node level of the subsite, last modified date, Percentage consumed from total content size and storage size in KB/MB/GB is displayed. All these information are exported to a CSV format file which can be used to filter the data through excel. The script is tested in both SharePoint Server 2010 and 2013. This would be helpful in case if we are planning for a migration from SharePoint 2010 or SharePoint 2013 and we want to know the size of each subsites in a site collection. We used this to report to list down all the subsites with size as we want to do the migration after splitting the subsites to different site collection as the overall size of site collection went up beyond recommended size.

Code

#Get Size of sites and subsite in a SharePoint Site Collection
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")


#Get the size of a site
function GetWebSize($Web)
{
[long]$subtotal = 0

$subtotal = GetFolderSize -Folder $Web.RootFolder
$RecyclebinSize=0
foreach($RecycleBinItem in $Web.RecycleBin)
   {
           $RecyclebinSize += $RecycleBinItem.Size
   }
 
return $subtotal + $RecyclebinSize
}

#Get the size of subsites of a site
function GetSubWebSizes($Web)
{
[long]$subtotal = 0
[long]$RecyclebinSize = 0
foreach ($subweb in $Web.GetSubwebsForCurrentUser())
{
[long]$webtotal = 0
$webtotal += GetFolderSize -Folder $subweb.RootFolder
foreach($RecycleBinItem in $subweb.RecycleBin)
{
$RecyclebinSize += $RecycleBinItem.Size
}
$subtotal += $RecyclebinSize
$subtotal += $webtotal
$subtotal += GetSubWebSizes -Web $subweb
}
return $subtotal+$RecyclebinSize
}

#Get the size of the folder
Function GetFolderSize($folder)
{
   [long]$filesize = 0;
   foreach ($file in $folder.Files)
   {
       $filesize += $file.TotalLength;
      
       foreach ($fileVersion in $file.Versions)
       {
           $filesize += $fileVersion.Size;
       }
   }
   foreach ($subfolder in $folder.SubFolders)
   {
       $filesize += GetFolderSize $subfolder
   }
          
   return $filesize;
}

#Gobal variable to storage the node level of a site/subsite.
$global:nodelevel = 1

#Function to get the node level of a subsite/site
Function GetNodeLevel($web)
{
if($web.ParentWeb -ne $null)
{
[int]$global:nodelevel++
GetNodeLevel $web.ParentWeb
}
$web.Dispose()
}

# Function to format in KB/MB/GB
function FormatBytes ($bytes)
{
   switch ($bytes)
   {
       {$bytes -ge 1TB} {"{0:n$sigDigits}" -f ($bytes/1TB) + " TB" ; break}
       {$bytes -ge 1GB} {"{0:n$sigDigits}" -f ($bytes/1GB) + " GB" ; break}
       {$bytes -ge 1MB} {"{0:n$sigDigits}" -f ($bytes/1MB) + " MB" ; break}
       {$bytes -ge 1KB} {"{0:n$sigDigits}" -f ($bytes/1KB) + " KB" ; break}
       Default { "{0:n$sigDigits}" -f $bytes + " Bytes" }
   }
}

#Set Site URL variable
$siteURL = Read-Host "Enter the Site Collection URL "


#Get the Site instance
$site = Get-SPSite $siteURL

#Get the total storage size of the size collection
$totalSize = $site.Usage.Storage
#Array to hold Storage data for all sites and subsites
$StorageDataCollection = @()
     
foreach($web in $site.AllWebs)
{
if($web -ne $null)
{
#Create an object to hold storage data
$StorageDataResult = New-Object PSObject

#Get the size of site and subsites.
$size = GetWebSize($web)
$size+= GetSubWebSizes($web)

#initialize the level variable
$global:nodelevel = 1
#Get the percentage of storage used by a specific web
$percentage = ($size/$totalSize).tostring("P0")

#Format the size in to KB/MB/GB
$formatSize = FormatBytes $size;
#To get the node level
$val = GetNodeLevel $web;
[string] $level = "" + $global:nodelevel
#Add the properties to show in the excel file.
$StorageDataResult | Add-Member -type NoteProperty -name "Site Name" -value $web.Title
$StorageDataResult | Add-Member -type NoteProperty -name "URL" -value $web.Url
$StorageDataResult | Add-Member -type NoteProperty -name "Size" -value $formatSize
$StorageDataResult | Add-Member -type NoteProperty -name "Last Modified Date" -value $web.LastItemModifiedDate
$StorageDataResult | Add-Member -type NoteProperty -name "Percentage" -value $percentage
$StorageDataResult | Add-Member -type NoteProperty -name "Node Level" -value $level

$StorageDataCollection += $StorageDataResult            
     }
 $web.Dispose()
}
     
#export the detailed storage information to a CSV file
$StorageDataCollection | sort-object "URL" | Export-csv "StorageMetricsReport.csv" -notypeinformation
Write-host "Site Storage Report has been generated!"

#dispose object

$site.dispose()      

Result

Run the script in PowerShell Execute the script in PowerShell

CSV file will be created at the location where the script file has been executed from.
Excel sheel view of Storage Metrics