Script to activate SharePoint feature on all site collection – Combine PnP and CSOM scripts

The prerequisite for this script is you need to be global admin on your tenant or you you have app installed with full permission on tenant scope

Let’s assume that your app have full permission on tenant scope, and you know the client id/client secret of your app

1. If your powersell script is not support for the execution policy, add this to your powershell windows first:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

2. Import SharePointPnPPowerShellOnline and Microsoft.Online.SharePoint.Powershell

Import-Module SharePointPnPPowerShellOnline -Scope “Local”
Import-Module Microsoft.Online.SharePoint.Powershell

Add-Type -Path “$path to client dlls\Microsoft.SharePoint.Client.dll”
Add-Type -Path “$path to client dlls\Microsoft.SharePoint.Client.Runtime.dll”

3. Declare the parameters

$global:appId = “your-client-id-guid-string”
$global:appSecret = “your-client-secret”

$global:adminUrl = “”

$global:SPFeatureId = “any-sharepoint-feature-id-fbace37b4a34”;

4. Connect to admin URL to get all site collection

Connect-PnPOnline -AppId $global:appId -AppSecret $global:appSecret -Url $global:adminUrl

$adminConnection = Get-PnPConnection

$allSitecollections = Get-PnPTenantSite -Connection $adminConnection

$sitecollections = New-Object System.Collections.ArrayList

5. For each site collection, connect again and activate the feature

foreach($siteCollection in $allSitecollections)
$targetUrl = $siteCollection.Url
Connect-PnPOnline -AppId $global:appId -AppSecret $global:appSecret -Url $targetUrl
$connection = Get-PnPConnection

#Activate SPFeature
$ctx = Get-PnPContext #This is important to get client content and use in CSOM
$site = $

$Site.Features.Add($global:SPFeatureId, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None) | Out-Null

Disconnect-PnPOnline -ErrorAction SilentlyContinue

That’s all!!!


Add a custom javascript file to SharePoint library using csom

var list = Ctx.Site.GetCatalog((int)ListTemplateType.MasterPageCatalog);

var rootFolder = list.RootFolder;

bool displayTemplateExists = DisplayTemplateExists(Ctx, list, ProjectStatusAll.Title);
string destFileName = rootFolder.ServerRelativeUrl + “/Display Templates/Content Web Parts/” + “Item_ProjectStatusAll.js”;
string content = ProjectStatusAll.Content;
string ctId = “0x0101002039C03B61C64EC4A04F5361F38510660500E478F12A266BD24B842D0B2128BDDAAB”;

var fields = new List<KeyValuePair<string, string>>();

fields.Add(new KeyValuePair<string, string>(“Title”, ProjectStatusAll.Title));
fields.Add(new KeyValuePair<string, string>(“TargetControlType”, ProjectStatusAll.TargetControlType));
fields.Add(new KeyValuePair<string, string>(“DisplayTemplateLevel”, ProjectStatusAll.DisplayTemplateLevel));
fields.Add(new KeyValuePair<string, string>(“TemplateHidden”, ProjectStatusAll.TemplateHidden));
fields.Add(new KeyValuePair<string, string>(“ManagedPropertyMapping”, ProjectStatusAll.ManagedPropertyMapping));

if (!displayTemplateExists)
CreateFile(Ctx, list, content, Encoding.UTF8, destFileName, ctId, fields, false);


public File CreateFile(ClientContext Ctx, List list, string content, Encoding encoding, string destFileName, string ctId, List<KeyValuePair<string, string>> fields, bool overwrite)
// Verify encoding
if (encoding == null)
throw new ArgumentNullException(“encoding”);

if (list == null)
throw new ArgumentNullException(“list”);

FileCreationInformation fileCreateInfo = new FileCreationInformation();
fileCreateInfo.Url = destFileName;
fileCreateInfo.Content = encoding.GetBytes(content);
fileCreateInfo.Overwrite = overwrite;

File createdFile = list.RootFolder.Files.Add(fileCreateInfo);

ListItem item = createdFile.ListItemAllFields;

item[“ContentTypeId”] = ctId;

foreach (var field in fields)
item[field.Key] = field.Value;


return createdFile;