Get all sites of a specific template with PowerShell

The following script gets all the sites of a specific template in a web application and writes the URLs on the screen and saves them in a text file. In this example it searches for all team sites (WebTemplateId=1). To get the sites of another OOTB or custom template use the ID or the name of that template.

All sites are checked no matter the level because SPSite.AllWebs gets the collection of all Web sites that are contained within the site collection, including the top-level site and its subsides.

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$webTemplateId = 1
$filePath = C:\AllSites.txt
$webApplication = Get-SPWebApplication http://webApplicationUrl
$sites = $webApplication.Sites
foreach ($site in $sites)
{
    try
    {
        foreach ($web in $site.AllWebs)
        {
            try
            {
                if ($web.WebTemplateId -eq $webTemplateId) # or use ($web.WebTemplate -eq "STS")
                {
                    Write-Host $web.Url
                    $web.Url | Out-File -FilePath $filePath -Append -Width 256
                }
            }
            finally
            {
                $web.Dispose();
            }
        }
    }
    finally
    {
        if($site -ne $null)
        {
            $site.Dispose();
        }
    }
}

Here are the values of WebTemplateId and the name of out-of-the-box templates in SharePoint 2010. Most of them have the same value for SharePoint 2013 too.

ID Name
0 GLOBAL#0 Global template
1 STS#0 Team Site
1 STS#1 Blank Site
1 STS#2 Document Workspace
2 MPS#0 Basic Meeting Workspace
2 MPS#1 Blank Meeting Workspace
2 MPS#2 Decision Meeting Workspace
2 MPS#3 Social Meeting Workspace
2 MPS#4 Multipage Meeting Workspace
3 CENTRALADMIN#0 Central Admin Site
4 WIKI#0 Wiki Site
9 BLOG#0 Blog
15 SGS#0 Group Work Site
16 TENANTADMIN#0 Tenant Admin Site
2764 ACCSRV#0 Access Services Site
2764 ACCSRV#1 Assets Web Database
2764 ACCSRV#3 Charitable Contributions
2764 ACCSRV#4 Contacts Web Database
2764 ACCSRV#6 Issues Web Database
7 BDR#0 Document Center
14483 OFFILE#0 (obsolete) Records Center
14483 OFFILE#1 Records Center
40 OSRV#0 Shared Services
3100 PPSMASite#0 PerformancePoint
3200 BICenterSite#0 Business Intelligence Center
20 SPS#0 SharePoint Portal Server Site
21 SPSPERS#0 SharePoint Portal Server
22 SPSMSITE#0 Personalization Site
30 SPSTOC#0 Contents area Template
31 SPSTOPIC#0 Topic area template
32 SPSNEWS#0 News Site
39 CMSPUBLISHING#0 Publishing Site
53 BLANKINTERNET#0 Publishing Site
53 BLANKINTERNET#1 Press Releases Site
53 BLANKINTERNET#2 Publishing Site with Workflow
33 SPSNHOME#0 News Site
34 SPSSITES#0 Site Directory
36 SPSCOMMU#0 Community area template
38 SPSREPORTCENTER#0 Report Center
47 SPSPORTAL#0 Collaboration Portal
50 SRCHCEN#0 Enterprise Search Center
51 PROFILES#0 Profiles
52 BLANKINTERNETCONTAINER#0 Publishing Portal
54 SPSMSITEHOST#0 My Site Host
56 ENTERWIKI#0 Enterprise Wiki
90 SRCHCENTERLITE#0 Basic Search Center
90 SRCHCENTERLITE#1 Basic Search Center
2000 SRCHCENTERFAST#0 FAST Search Center
61 visprus#0 Visio Process Repository

Modifying a sealed choice field using PowerShell

To modify a sealed field it must be first “unsealed” by setting Sealed property to False. This can be done using PowerShell.

For demonstration purposes let’s say we have a list List1 which contains a sealed choice field ChoiceField1 with three choices Choice #1, Choice #2, Choice #3, and the default choice is Choice #1.

Unseal the field

Below is the script to first “unsealed” the field

	Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue
	$web = Get-SPWeb -Identity "http://weburl"
	$list = $web.GetList($web.Url + "/Lists/List1")
	$field = $list.Fields.GetField("ChoiceField1")
	$field.Sealed = $false
	$field.Update()

Change the choices order

To change the choices order from Choice #1, Choice #2, Choice #3 to Choice #2, Choice #3, Choice #1 run the script below

	$web = Get-SPWeb -Identity "http://weburl"
	$list = $web.GetList($web.Url + "/Lists/List1")
	$field = $list.Fields.GetField("ChoiceField1")
	$field.Choices.Remove("Choice #1");
	$field.Choices.Remove("Choice #2");
	$field.Choices.Remove("Choice #3");
	$field.Choices.Add("Choice #2")
	$field.Choices.Add("Choice #3")
	$field.Choices.Add("Choice #1")
	$field.Update()

Change the default choice

To change the default choice from Choice #1 to Choice #3 run the script below

	$web = Get-SPWeb -Identity "http://weburl"
	$list = $web.GetList($web.Url + "/Lists/List1")
	$field = $list.Fields.GetField("ChoiceField1")
	$field.DefaultValue = "Choice #3"
	$field.Update()

Seal the field back

	$web = Get-SPWeb -Identity "http://weburl"
	$list = $web.GetList($web.Url + "/Lists/List1")
	$field = $list.Fields.GetField("ChoiceField1")
	$field.Sealed = $true
	$field.update()
	$web.Dispose()

For every script above I used new $web so every script is ready for use. You can get one $web and combine pieces of the above scripts.

Getting document by file name with PowerShell using CAML

Getting one document from a document library by specifying the document’s name is possible by using CAML. With this method the looping through all the documents is avoided.

Here is a sample script to get the document with name ‘Doc1.docx’ from a document library:

$web = Get-SPWeb -Identity http://weburl
$list = $web.Lists["ListName"];
$query = New-Object Microsoft.SharePoint.SPQuery
$caml ='<Where><Eq><FieldRef Name="FileLeafRef"/><Value Type="File">Doc1.docx</Value></Eq></Where>'
$query.Query = $caml
$query.RowLimit = 1
$items = $list.GetItems($query)
$item = $items[0]

Backup documents from document library with PowerShell script

This is a PowerShell script to download all documents from a document library to the file system.
If $majorVersionsOnly is FLASE it will download the latest version of all the documents including the documents with no published versions.
If $majorVersionsOnly is TRUE it will download all documents that have published versions(their last major version will be downloaded). For example if Document1.docx’s latest version is 4.2 with $majorVersionsOnly=$true the script will download version 4.0 of Document1.docx. With $majorVersionsOnly=$false the script will download version 4.2 of Document1.docx.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$siteUrl = 'http://....'
$listUrl = 'http://....'
$folderPath = 'C:\\....'
$majorVersionsOnly = $true;

Function GetFileBinary([Microsoft.SharePoint.SPListItem]$_item)
{
    $_binary = $null;
    $_lastVersion = $_item.Versions[0].VersionLabel;
    $_splitted = $_lastVersion.Split('.');
    $_lastMajor = [int]$_splitted[0];
    $_lastMinor = [int]$_splitted[1];

    if ($majorVersionsOnly)
    {
        if ($_item.HasPublishedVersion)
        {
            if ($_lastMinor -eq 0)
            {
                $_binary = $_item.File.OpenBinary();
            }
            else
            {
                $_fileVersions = $_item.File.Versions;
                $_fileVersion = $_fileVersions.GetVersionFromLabel($_lastMajor.ToString() + ".0");
                $_binary = $_fileVersion.OpenBinary();
            }
        }
    }
    else
    {
        $_binary = $_item.File.OpenBinary();
    }

    return $_binary;
}
  
$web = Get-SPWeb -Identity $siteUrl
$list = $web.GetList($listUrl)
$items = $list.Items
ForEach ($item in $items)
{
    $binary = GetFileBinary($item);
    $folderPathToSave = $folderPath + "\\" + $item.Name;
    if ($binary -ne $null)
    {
        $stream = New-Object System.IO.FileStream($folderPathToSave,[System.IO.FileMode]::Create,[System.IO.FileAccess]::ReadWrite);
        $writer = New-Object System.IO.BinaryWriter($stream);
        $writer.Write($binary);
        $writer.Close();
    }
}
     
$web.Dispose()

Add, Modify or Delete List Event Receivers with PowerShell

Developing and troubleshooting custom SharePoint solutions always involves checking, adding, modifying or deleting event receivers. When working on production servers usually we don’t have all the tools that we have in our own VMs. In those cases we can use PowerShell or write inline code in an application page and put it in the LAYOUTS folder in SharePoint Root.

Below are some PowerShell commands to check, add, modify and remove list event receivers.

It goes without saying that you should be very careful when working with event receivers as with everything else in SharePoint. Save the original state with a back up, or at least make sure you know which event receivers are there with all their properties before modifying anything. That way you can get everything back in the original state.

Checking event receivers:

After getting the list in PowerShell you can just run $list.EventReceivers and it will show all the event receivers will all their properties.

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://....
$list = $web.GetList($web.Url + '/Lists/' + “list name”)
$list.EventReceivers

To save the result in a text file for future reference execute the following command:

$list.EventReceivers | Out-File -filepath "D:\EventReceivers.txt"

Add EventReceiver

To add an event receiver you need to know the full assembly name (you can get that from GAC) and the class name that contains the event receivers

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://....
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemAdding" #or any other type, like ItemDeleting, ItemAdded, ItemUpdating ...
$assembly = "YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5eff...(here goes assebly's token"
$class = "Your Class"

$list.EventReceivers.Add($type, $assembly, $class)

$web.Dispose()

Modify Event Receiver

For example, to change an after event EventReceiver from asynchronous to synchronous

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://...
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemAdded" #or any other type, like ItemDeleting, ItemAdding, ItemUpdating, ...

$numberOfEventReceivers = $list.EventReceivers.Count

if ($numberOfEventReceivers -gt 0)
{
 for( $index = $numberOfEventReceivers -1; $index -gt -1; $index–-)
 {
 	$receiver = $list.EventReceivers[$index] ;
 	$name = $receiver.Name
 	$typ = $receiver.Type ;

 if ($typ -eq $type)  #or you can check ($name -eq "event receiver's name") if you have more then one event receivers of the same type
 {
 	$receiver.Synchronization = "Synchronous"
	$receiver.Update()
	Write-Host "Event receiver " $name " is changed to Synchronous"
 }
 }
}
else
{
 	Write-Host " There is no EventReceiver of type " $type " registered for this list "
}

$web.Dispose()

Delete Event Receivers

Run the following to delete a specific event receiver (in this example ItemDeleting event receiver)

Add-PSSnapin Microsoft.SharePoint.PowerShell –erroraction SilentlyContinue

$web = Get-SPWeb -Identity http://...
$list = $web.GetList($web.Url + "/Lists/" + “list name”)

$type = "ItemDeleting" #or any other type, like ItemDeleting, ItemAdding, ItemUpdating, ...

$numberOfEventReceivers = $list.EventReceivers.Count

if ($numberOfEventReceivers -gt 0)
{
   for( $index = $numberOfEventReceivers -1; $index -gt -1; $index–-)
   {
      $receiver = $list.EventReceivers[$index] ;
      $name = $receiver.Name
      $typ = $receiver.Type ;

      if ($typ -eq $type)  #or you can check ($name -eq "event receiver's name") if you have more then one event receivers of the same type
      {
         $receiver.Delete()
         Write-Host "Event receiver " $name " is deleted"
      }
   }
}
else
{
   Write-Host " There is no EventReceivers of type " $type " registered for this list "
}

$web.Dispose()