Add field into content type SharePoint 2013 using csom PowerShell

Once everything is deployed on production environment, and during implementing updates many a times we come across situations to add a column into existing content type. Instead of doing it manually below client side PowerShell function can be extremely handy

Try{
#Loading SharePoint Client side namespaces
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}
catch {
Throw "Unable to load SharePoint Client runtime"
}
function AddField-InContentType()
{
param(
[Parameter(Mandatory=$true)][string]$url,
[Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
[Parameter(Mandatory=$true)][string]$ContentTypeName,
[Parameter(Mandatory=$true)][string]$FieldInternalName
)
begin{
try
{
#Get Client Object
#
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$Context.Credentials = $Credentials
#Load web, fields and site objects
#
$web = $Context.Web
$fields = $Context.Site.RootWeb.Fields;
$site = $context.Site
$Context.Load($web)
$Context.Load($site)
$Context.Load($fields)
$Context.ExecuteQuery()
}
catch
{
Write-Host "Error while getting context. Error -->> " + $_.Exception.Message -ForegroundColor Red
}
}
process{
try
{
#Check whether site column exists in site collection columns
#
Write-Host "Check if the site column" $FieldInternalName "is exist or not" -ForegroundColor Cyan
try
{
$field = $fields.GetByInternalNameOrTitle($FieldInternalName)
$Context.Load($field)
$Context.ExecuteQuery()
Write-Host "Site column" $FieldInternalName "exist" -ForegroundColor Cyan
}
catch
{
Write-Host "Site column" $FieldInternalName " does not exist in the list of site collection columns" -ForegroundColor Cyan
return
}
#Getting content types from the root site
#
$contentTypes = $Context.Site.RootWeb.ContentTypes
$Context.Load($contentTypes)
$Context.ExecuteQuery()
#Getting specified content type in which we need to add a column
#
$contentType = $contentTypes | Where {$_.Name -eq $ContentTypeName}
#Get Fields from the content type
#
$fieldCollection = $contentType.Fields
$Context.Load($fieldCollection);
$Context.ExecuteQuery();
#Check if field already exists in content type or not
#
$IsFieldExists = $false
foreach($fld in $fieldCollection)
{
Write-Host $fld.get_InternalName()
if($fld.get_InternalName() -eq $FieldInternalName){
$IsFieldExists = $true
}
}
if($IsFieldExists -eq $false)
{
#Get all the columns associated with content type
#
$fieldRefCollection = $contentType.FieldLinks;
$Context.Load($fieldRefCollection);
$Context.ExecuteQuery();
#Add a new column to the content type
#
Write-Host "Adding site column " $FieldInternalName "to the content type" -ForegroundColor Cyan
$fieldReferenceLink = New-Object Microsoft.SharePoint.Client.FieldLinkCreationInformation
$fieldReferenceLink.Field = $field;
$contentType.FieldLinks.Add($fieldReferenceLink);
$contentType.Update($true)
$Context.Load($contentType)
$Context.ExecuteQuery()
Write-Host "Field added successfully" -ForegroundColor Green
}
else
{
Write-Host "Site Column " $FieldInternalName " already exists in content type" -ForegroundColor Cyan
}
}
catch
{
Write-Host ("Error while adding field in contet type. Error -->> " + $_.Exception.Message) -ForegroundColor Red
}
}
end{
$Context.Dispose()
}
}
$credentials = Get-Credential
$Url = 'http://YourSite.com'
AddField-InContentType $Url $credentials "Your Content Type Name" "YourSiteColumn"

Create Groups, Term Sets and Terms in a Term Store using CSOM PowerShell in SharePoint 2013

Term store is an important part of a site which can be used extensively to utilise groups, term sets and terms of it.

A group is a set of term sets that all share common security requirements.
Following function creates a group in term store

Try{
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}

catch {
	Throw "Unable to load SharePoint Client runtime"
}

function Create-NewGroup() {
    [CmdletBinding()]

	param(
        [Parameter(Mandatory=$true)][string]$MMSbaseurl,
        [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$false)][int]$lcid
    )

begin{
    
    Write-Host "Preparing for term store...."
    try{
       	$Context = New-Object Microsoft.SharePoint.Client.ClientContext($MMSbaseurl)
    }
    catch {
    	Write-Host "Error:-->> Unable to create ClientContext at " $MMSbaseurl
	}
    
   try
    {
        Write-Host "Binding to Term set through managed metadata services for ($MMSbaseurl) "
        $Context.Credentials = $credentials
        $MMS = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($Context)
        $Context.Load($MMS)
        $Context.ExecuteQuery()

        Write-Host "Retrieving Term Stores"
        $TermStores = $MMS.TermStores
        $Context.Load($TermStores)
        $Context.ExecuteQuery()

    
        Write-Host "Binding term store"
	    $TermStore = $TermStores[0]
        $Context.Load($TermStore)
        $Context.ExecuteQuery()


        Write-Host "Creating new group"
        $NewGroup = $TermStore.CreateGroup("New Group", [System.Guid]::NewGuid().toString())
        $Context.Load($NewGroup)
        $Context.ExecuteQuery()

        Write-Host "Group created successfully" -ForegroundColor Cyan
        
	}
    catch{
        Write-Host "Error -->>>> " $_.Exception.Message -ForegroundColor Red
    }
       
}
end{
	$Context.Dispose()
}   

}

$credentials = Get-Credential
Create-NewGroup "http://yoursite" $credentials 1033

Term sets can be utilised as a hub of navigation links which can be used in Global and Current navigation of a SharePoint site. Further more apart from navigational, term sets can be utilised to bind it with a managed meta data field. So just in theory I believe in a decent sized project term sets plays an important role, and their creation as well as deployment on production environment becomes crucial.

Below is the CSOM PowerShell function which can be used to create a term set.

#Loading SharePoint client assemblies
Try{
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}
 
catch {
    Throw "Unable to load SharePoint Client runtime"
}
 
 
 
function Create-TermSet() {
    param(
        [Parameter(Mandatory=$true)][string]$baseurl,
        [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$false)][string]$TermSetName,
        [Parameter(Mandatory=$false)][int]$lcid
    )
 
    begin {
         
        #Getting the context of the site which will enable us to take further actions
        try {
            $Context = New-Object Microsoft.SharePoint.Client.ClientContext($baseurl)
        }
        catch {
     
            Write-Output "Error:-->> Unable to create ClientContext at " $baseurl " Base URL : "
            Throw "Unable to create ClientContext at " +  $baseurl  +  " Base URL : "
        }
 
         
        try
        {
            #Now in order to deal with any of the term or term set related things we need to get the taxonomy session of Managed MetaData Services
            #
            Write-Host "Binding to Term set through Managed MetaData Services for ($baseurl) "
            $Context.Credentials = $credentials
             
            $MMS = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($Context)
            $Context.Load($MMS)
            $Context.ExecuteQuery()
 
            #Retrieve Term Stores
            #
            Write-Host "Retrieving Term Stores"
            $TermStores = $MMS.TermStores
            $Context.Load($TermStores)
            $Context.ExecuteQuery()
 
            #Bind to Term Store
            #
            Write-Host "Binding term store"
            $TermStore = $TermStores[0]
            $Context.Load($TermStore)
            $Context.ExecuteQuery()
     
            #Now once we get hold of Term Store, we need to decide under which group we want to create a Term Set, so bind to groups
            #
            Write-Host "Binding term store Groups"
            $Groups = $TermStore.Groups
            $Context.Load($Groups)
            $Context.ExecuteQuery()
        }
        catch{
 
            Write-Host "Error -->>>> " $_.Exception.Message
            Throw "Unable to bind term store"
        }
 
        #For a site there is a default site collection group. Here we find it and store it in $siteCollectionGroup
        #
        Write-Host "Find site collection term store"
         
        #The Site Collection Group has default format of name such as 'Site Collection - yoursite.com'
        #Creating the temp default group name using replace function for comparison in later line of code
        #If you don't want to use this default group or its not available on your site, you can use some existing one and replace name in below variable, or else create a new group
        #
        $tempGroupName = $baseurl.Replace("http://","Site Collection - ").Replace(":","-").Replace("/","-").ToLower()
         
        foreach($Group in $Groups) {
 
            if (($Group.IsSiteCollectionGroup -eq $true) -and (($Group.Name.ToLower()) -eq $tempGroupName))
            {   
                $siteCollectionGroup = $Group
                Write-Host "Term store found."
                break
            }
        }
 
 
        try
        {
            #Load site collection group
            if($siteCollectionGroup -ne $null)
            {
                Write-Host "Bind to site collection group"
                $Context.Load($siteCollectionGroup)
                $Context.ExecuteQuery()
            }
 
            #A check is always important whether a Term Set already exists or not, to avoid error.
            #
            $TermSetsForChk = $siteCollectionGroup.TermSets
            $Context.Load($TermSetsForChk)
            $Context.ExecuteQuery()
            $ChkTermSet = $TermSetsForChk | Where-Object {$_.Name -eq $TermSetName} 
 
            if($ChkTermSet -eq $null)
            {
                Write-Host "Term set does not exists." -ForegroundColor Cyan
 
                Write-Host "Creating TermSet"
             
                $TermSet = $siteCollectionGroup.CreateTermSet($TermSetName,[System.Guid]::NewGuid().toString(),$lcid)
                $Context.Load($TermSet)
                $Context.ExecuteQuery()
                Write-Host "Term set created successfully" -ForegroundColor Cyan
                
            }
            else
            {
                Write-Host "Term set already exists" -ForegroundColor Cyan
            }    
             
        }
        catch {
            Write-Host "Error -->>>> Unable to create term set :  " $_.Exception.Message
            Throw "Unable to create term set"
        }
 
    }
 
    end{
        $Context.Dispose()
    }
 
}
 
#Setting up parameters
#
$baseurl = "http://yoursite.com"
$credentials = Get-Credential
$TermSetName = "Any name"
$lcid = 1033
 
#Call function
#
Create-TermSet $baseurl $credentials $TermSetName $lcid

Now once term set is created we would like to have terms inside it. A very simple function to create terms inside term set is written below.

#Loading SharePoint client assemblies
#
Try{
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}

catch {
	Throw "Unable to load SharePoint Client runtime"
}

function Create-NewTerm() {
    [CmdletBinding()]

	param(
        [Parameter(Mandatory=$true)][string]$MMSbaseurl,
        [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$true)][string]$GroupName,
        [Parameter(Mandatory=$true)][string]$TermSetName,
        [Parameter(Mandatory=$false)][int]$lcid
    )

begin{
    
    Write-Host "Preparing for term store...." -ForegroundColor Cyan
    try{
       	$Context = New-Object Microsoft.SharePoint.Client.ClientContext($MMSbaseurl)
    }
    catch {
    	Write-Host "Error:-->> Unable to create ClientContext at " $MMSbaseurl -ForegroundColor Red
	}
    
   try
    {
        Write-Host "Binding to Term store through managed metadata services for ($MMSbaseurl) " -ForegroundColor Cyan
        $Context.Credentials = $credentials
        $MMS = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($Context)
        $Context.Load($MMS)
        $Context.ExecuteQuery()

        Write-Host "Retrieving Term Stores" -ForegroundColor Cyan
        $TermStores = $MMS.TermStores
        $Context.Load($TermStores)
        $Context.ExecuteQuery()

    
        Write-Host "Binding term store" -ForegroundColor Cyan
	    $TermStore = $TermStores[0]
        $Context.Load($TermStore)
        $Context.ExecuteQuery()


        Write-Host "Binding term store Groups" -ForegroundColor Cyan
	    $Groups = $TermStore.Groups
	    $Context.Load($Groups)
	    $Context.ExecuteQuery()

        foreach($Group in $Groups) {
            if ((($Group.Name.ToLower()) -eq $GroupName.ToLower()))
		    {	
                $SelectedGroup = $Group
                Write-Host "Group found." -ForegroundColor Cyan
                break
		    }
	    }

        $Context.Load($SelectedGroup)
	    $Context.ExecuteQuery()


        Write-Host "Bind to term set" -ForegroundColor Cyan
        $TermSets = $SelectedGroup.TermSets
        $Context.Load($TermSets)
	    $Context.ExecuteQuery()

        foreach($TermSet in $TermSets) {
            if ((($TermSet.Name.ToLower()) -eq $TermSetName.ToLower()))
		    {	
                $SelectedTermSet = $TermSet
                Write-Host "Term set found." -ForegroundColor Cyan
                break
		    }
	    }

        $Context.Load($TermSet)
	    $Context.ExecuteQuery()

        #Term creation
        #
        $NewTerm = $TermSet.CreateTerm("New Term", $lcid, [System.Guid]::NewGuid().toString())
        $Context.Load($NewTerm)
	    $Context.ExecuteQuery()
        Write-Host "New term created successfully" -ForegroundColor Cyan

	}
    catch{
        Write-Host "Error -->>>> " $_.Exception.Message -ForegroundColor Red
    }
}
end{
	$Context.Dispose()
}   

}

#Get and Set credentials
$credentials = Get-Credential

#Call Function
#
Create-NewTerm "http:YourSite.com" $credentials "New Group" "New Term Set" 1033

Replacing all occurrences of a string in JavaScript

Every now and then when we write JavaScript replace function we tend to forget that there can be scenarios where a string will occur more than once and for that we need a small tweak to achieve.

Simple replace:

var str = 'This is a test string for someone to test.';
var newStr = str.replace('test','actual');
var withoutSpaceStr = str.replace(' ','-');

The above replace function will replace only first occurrence of a string.
Output will be below:

  1. newStr will contain This is a actual string for someone to test.
  2. withoutSpaceStr will contain Thisis a test string for someone to test.

 

Replace All:

var str = 'This is a test string for someone to test.';
var newStr = str.replace(/test/g,'actual');
var withoutSpaceStr = str.replace(/ /g,'-');

The above replace function will now replace all occurrences of a string
Output will be below:

  1. newStr will contain This is a actual string for some to actual.
  2. withoutSpaceStr will contain This-is-a-test-string-for-someone-to-test.

 

Happy JavaScripting 🙂

Upload a custom sharepoint list template and create a custom list based on it using PowerShell

Many a times we have custom SharePoint list templates, based on that we create lists manually. Imagine you have a list template and want to create a list based on that on some site. Manual steps include uploading .stp file into list template gallery and then create a custom list. All such stuff can be achieved using following function.

Note: This function is a server object model, and needs to be run on the server where SharePoint is installed.

  1. $rooturl: its the url of the root web
  2. $listCreationUrl is the url in which you would want to create a list
  3. $credentials, no explanation needed 🙂
  4. $listName: Name of the list as you wish
  5. $listTemplateFileUrl: file path where the list template .stp file is located on your machine
  6. $listTemplateName: Important, What ever name was given while saving list as a template.

 

function UploadAndCreate-CustomListTemplate()
{
param(
        [Parameter(Mandatory=$true)][string]$rooturl,
        [Parameter(Mandatory=$true)][string]$listCreationUrl,
        [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$true)][string]$listName,
        [Parameter(Mandatory=$true)][string]$listTemplateFileUrl,
        [Parameter(Mandatory=$true)][string]$listTemplateName
        
    )

    try
    {
        # Adding the PowerShell Snapin
        Add-PSSnapin “Microsoft.SharePoint.PowerShell”

        # Get the SiteURL
        $site = get-spsite($rooturl)

        # Get the root web
        $web = $site.RootWeb

        # Get the list template gallery
        $spLTG = $web.getfolder(“List Template Gallery”)

        # Get the list template gallery Collection
        $spcollection = $spLTG.files

        # Get the custom list template file
        $Templatefile = get-item $listTemplateFileUrl

        # Add the custom list template file to gallery
        $titleHashTbl = @{}
        $titleHashTbl.Add("Title", $listTemplateName)
        $folderListTemplate = "_catalogs/lt/" + $listTemplateName + ".stp"
        $spcollection.Add($folderListTemplate, $Templatefile.OpenRead(),$titleHashTbl,$true)
        Write-Host “Custom Template Uploaded to List Template Gallery Successfully”
        
        Write-Host “Creating the List based on the Template”
        # Get the custom list templates
        $CustomlistTemplates = $site.GetCustomListTemplates($web)

        #Create the custom list using template
        $site = Get-SPWeb $listCreationUrl
        $site.Lists.Add($listName, $listName, $CustomlistTemplates[$listTemplateName])
        Write-Host "Based on the template List Created"
    }
    catch
    {
        Write-Host ("Error while creating list. Error -->> " + $_.Exception.Message) -ForegroundColor Red
    }

}

$rootUrl = "http://somesite.com"
$url = "http://somesite.com" #Or http://somesite.com/subsite
$credentials = Get-Credential
$listName = "Some List" 
$listTemplateFileUrl = "d:\whatever"
$listTemplateName = "List Template Name"


UploadAndCreate-CustomListTemplate $rootUrl $url $credentials $listName $listTemplateFileUrl $listTemplateName

Update Title or any field of a SharePoint Publishing Page using CSOM PowerShell

Once a publishing page is created we may find a requirement to update for changing a title or any of the field on a page like description. If we have many such pages we can push a update PowerShell script to achieve it.

Assuming page is in a publishing site, we can use the below function.

 

Try{
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}

catch {
	Throw "Unable to load SharePoint Client runtime"
}

function Update-PublishingPage()
{
    param(
        [Parameter(Mandatory=$true)][string]$siteurl,
        [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$false)][string]$PageName,
        [Parameter(Mandatory=$false)][string]$Title
    )
    try
    {

        $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteurl)
	    $ctx.Credentials = $credentials

        	    
	    $Pages = $ctx.Web.Lists.GetByTitle('Pages')
	    $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
	    $camlQuery.ViewXml = '<View><Query><Where><Eq><FieldRef Name="FileLeafRef" /><Value Type="Text">'+ $PageName +'</Value></Eq></Where></Query></View>'
	    $Page = $Pages.GetItems($camlQuery)
	    $ctx.Load($Page)
	    $ctx.ExecuteQuery()
	    
	    $file = $Page.File
	    $file.CheckOut()
	    $ctx.Load($file)
	    $ctx.ExecuteQuery()
	    
	    
        $Page.Set_Item("Title", $Title)
        $Page.Update()
	    $Page.File.CheckIn("check in comment", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)
	    $Page.File.Publish(" ")
	    #$Page.File.Approve(" ")
	    $ctx.Load($Page)
	    $ctx.ExecuteQuery()
	    Write-Host "Update Page Title Complete" -ForegroundColor Green
    }
    catch
    {
        Write-Host ("Error while updating page. Error -->> " + $_.Exception.Message) -ForegroundColor Red
    }
}

$credentials = Get-Credential
Update-PublishingPage "http://somesite.com" $credentials "somepage.aspx" "Some Friendly Title"

Check if SharePoint List exists using CSOM PowerShell

Often while writing PowerShell deployment scripts we want to check whether a list exists exists before creating it. Below is a small example of it.

 

#Load SharePoint client assemblies
#
Try{
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
    Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}

catch {
	Throw "Unable to load SharePoint Client runtime"
}

function Check-ListExists()
{
    param(
        [Parameter(Mandatory=$true)][string]$url,
        [Parameter(Mandatory=$true)][System.Net.NetworkCredential]$credentials,
        [Parameter(Mandatory=$true)][string]$listName
    )

    begin{
        try
        {
            #Get Client Object
            $context = New-Object Microsoft.SharePoint.Client.ClientContext($url)
            $context.Credentials = $credentials
            $web = $context.Web 
            $lists = $web.Lists
            $context.Load($web) 
            $context.Load($lists)   
            $context.ExecuteQuery()
        }
        catch
        {
            Write-Host ("Error while getting context. Error -->> " + $_.Exception.Message) -ForegroundColor Red
        }
    }
    process{
        try
        {
            $list = $web.Lists | where{$_.Title -eq $listName}
            if($list)
            {
                #Execute if list exists
                Write-Host "List " $listName " exists" -ForegroundColor Green
                return $true
            }
            else
            {
                #Execute if list does not exists
                Write-Host "List " $listName " does not exists" -ForegroundColor Green
                return $false
            }
        }
        catch
        {
            Write-Host ("Error while checking for list. Error -->> " + $_.Exception.Message) -ForegroundColor Red
        }
    }
    end{
     $context.Dispose()
    }
}


$credentials = Get-Credential
Check-ListExists "http://somesite.com" $credentials "Some List"

CSOM PowerShell to create a SharePoint publishing page with custom or OOB page layout

To create a publishing page using either Out of the box or a custom page layout following is the code.

There are 2 things you need to keep in mind to follow the below function

  1. If you are using OOB page layout, then we are using CAML query to get page layout as an item
  2. If you are using a custom page layout, then we are using a path to get page layout as an item. In below example the custom page layout is assumed to be in custom folder.
#Load SharePoint Client Assemblies 
Try{
 Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll'
 Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'
 Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Publishing.dll'
 Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Taxonomy.dll'
}

catch {
 Throw "Unable to load SharePoint Client runtime"
}


function Create-PublishingPage() 
{

 param(
 [Parameter(Mandatory=$true)][string]$siteurl,
 [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials,
 [Parameter(Mandatory=$false)][string]$PageTitle,
 [Parameter(Mandatory=$false)][string]$PageName,
 [Parameter(Mandatory=$false)][string]$PageLayoutName,
 [Parameter(Mandatory=$false)][bool]$isCustomPageLayout
 )

 try
 {
 

 # Authenticate with site.
 #
 $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteurl) 
 $ctx.Credentials = $credentials

 
 if($isCustomPageLayout -eq $false)
 {
   # Get the page layout item 
   #
   $rootWeb = $ctx.Site.RootWeb
   $mpList = $rootWeb.Lists.GetByTitle('Master Page Gallery')
   $camlQuery = New-Object Microsoft.SharePoint.Client.CamlQuery
   $camlQuery.ViewXml = '<View><Query><Where><Eq><FieldRef Name="FileLeafRef" /><Value Type="Text">'+$PageLayoutName+'</Value></Eq></Where></Query></View>'
   $items = $mpList.GetItems($camlQuery)
   $ctx.Load($items)
   $ctx.ExecuteQuery()
   $pageLayoutItem = $items[0]
   $ctx.Load($pageLayoutItem)
 }
 else
 {
   # Get custom page layout and convert it to list item
   #
   $PageLayoutName = "/_catalogs/masterpage/Custom Page Layouts Folder/" + $PageLayoutName
   $items = $ctx.Site.RootWeb.GetFileByServerRelativeUrl($PageLayoutName)
   $ctx.Load($items)
   $pageLayoutItem = $items.ListItemAllFields
   $ctx.Load($pageLayoutItem)
 
 }

 # Get publishing web object
 #
 $web = $ctx.Web
 $pubWeb = [Microsoft.SharePoint.Client.Publishing.PublishingWeb]::GetPublishingWeb($ctx, $web)
 $ctx.Load($pubWeb)
 
 # Get pages library.
 #
 $pagesList = $ctx.Web.Lists.GetByTitle('Pages')
 
 
 # Create page information instance, update properties, 
 # add it, check it in, publish it, and approve it.
 # 
 $pubPageInfo = New-Object Microsoft.SharePoint.Client.Publishing.PublishingPageInformation
 $pubPageInfo.Name = $PageName.Replace(" ", "-") + ".aspx"
 $pubPageInfo.PageLayoutListItem = $pageLayoutItem 
 $pubPage = $pubWeb.AddPublishingpage($pubPageInfo)

 $pubPage.ListItem.File.CheckIn("", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)
 $pubPage.ListItem.File.Publish("")
 $pubPage.ListItem.File.Approve("")

 $ctx.Load($pubPage) 
 $ctx.ExecuteQuery()

 # Page added. Now retrieve list item, check it out, 
 # update title and page content, and check back in.
 #
 $listItem = $pubPage.get_listItem()
 $ctx.Load($listItem)
 $ctx.ExecuteQuery()

 $file = $listItem.File
 $file.CheckOut()
 $ctx.Load($file)
 $ctx.ExecuteQuery()

 $listItem.Set_Item("Title", $PageTitle)
 $listItem.Update()
 $listItem.File.CheckIn("", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)
 $listItem.File.Publish("")
 $listItem.File.Approve("")
 $ctx.Load($listItem)
 $ctx.ExecuteQuery()

 Write-Host 'New page ' $PageName ' created successfully' -ForegroundColor Cyan
 }
 catch
 {
   Write-Host ("Error while creating page. Error -->> " + $_.Exception.Message) -ForegroundColor Red
 }
 
}

$credentials = Get-Credential

#Example for page with Custom Page Layout
#
Create-PublishingPage "http://somesite.com" $credentials "Some Page Title" "SomePageName" "YourCustomPageLayout.aspx" $true 

#Example for page with OOB Page Layout
#
Create-PublishingPage "http://somesite.com" $credentials "Some Page Title" "SomePageName" "ArticleLeft.aspx" $false

Create a SharePoint Site using CSOM PowerShell

Wow!!.. Finally after facing many challenges and gaining a decent knowledge about SharePoint 2013 using JSOM, CSOM PowerShell, I have many things to share to the SharePoint community by means of this blog.

Let me start by sharing a simple CSOM PowerShell function which creates a publishing site inside SharePoint Web Application.

To create a SharePoint site we need to keep following things in mind which SharePoint understands.

  1. Web template: SharePoint has many out of the box web templates, we should be sure which one to use for a publishing site.
  2. Permissions: The most important part, whether do we need to inherit parent site’s permission or not.

Following is the function which can be used to create a publishing site.

Function New-Site()
{
 param(
 [Parameter(Mandatory=$true)][string]$webappurl,
 [Parameter(Mandatory=$true)][string]$siteurl,
 [Parameter(Mandatory=$false)][string]$sitetitle,
 [Parameter(Mandatory=$false)][string]$sitedescription,
 [Parameter(Mandatory=$false)][string]$webTemplate,
 [Parameter(Mandatory=$false)][int]$lcid,
 [Parameter(Mandatory=$false)][bool]$UseSamePermissionsAsParentSite,
 [Parameter(Mandatory=$false)][System.Net.NetworkCredential]$credentials
 )

 try
 {
   $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($webappurl)
   $ctx.Credentials = $credentials
   $webCreationInformation = New-Object Microsoft.SharePoint.Client.WebCreationInformation
   $webCreationInformation.Url = $siteurl
   $webCreationInformation.Title = $sitetitle
   $webCreationInformation.Description = $sitedescription
   $webCreationInformation.UseSamePermissionsAsParentSite = $UseSamePermissionsAsParentSite
   $webCreationInformation.Language = $lcid 
   $webCreationInformation.WebTemplate = $webTemplate
   $newWeb = $ctx.Web.Webs.Add($webCreationInformation)
   $ctx.Load($newWeb) 
   $ctx.ExecuteQuery()

   if(!$?) {
     Throw "Unable to create new site"
   }
   Write-Host "Site created successfully." -ForegroundColor Green

 }
 catch
 {
   Write-Host("Error while creating site. Error -->> " + $_.Exception.Message) -ForegroundColor Red
 }
}

$webappurl = 'http://somewebapp.com'
$siteurl = 'SomeSite'
$sitetitle = 'Some Title'
$sitedescription = 'Some site description' 
$WebTemplate = "CMSPUBLISHING#0"
$Lcid = 1033
$UseSamePermissionsAsParentSite = $true
$credentials = Get-Credential

New-Site $webappurl $siteurl $sitetitle $sitedescription $WebTemplate $Lcid $UseSamePermissionsAsParentSite $credentials