SharePoint just denied your custom script from running. What do?

5 ways to enable Custom Scripts for a SharePoint site collection

This post was most recently updated on August 31st, 2022.

8 min read.

This article explains how to enable custom scripting for any SharePoint site collection. This is functionally equivalent to setting setting “-DenyAddAndCustomizePages 0” or disabling the NoScript feature. Different instructions and solutions apply to SharePoint Online, and on-premises scenarios (SharePoint Server 2013, 2016, and probably 2019) – so see below for all of them.

Different solutions are required to resolve the issue for different target sites:

  • Modern SharePoint Team Sites (attached to Office Groups if on SharePoint Online, and without one if On-Premises)
  • Modern SharePoint Communication sites (after 08/2017 – at least on SharePoint Online)
  • SharePoint MySites (On-Premises)
  • Personal OneDrive sites (SharePoint Online)
  • Any SharePoint Site Collection created through self-service site creation (both SharePoint Online and On-Premises)
  • Tenant root Site Collection (SharePoint Online)
  • Any Classic SharePoint site collection (all environments!)

Update 22.4.2019: Added the option of using Google Chrome SP Editor to achieve this.

Why enable Custom Scripts?

Most typically I run into this when trying to insert a script web part with custom JavaScript into a site, that has NoScript enabled. This means that even if you had permissions (like the owner – or full control) to insert script/content webparts otherwise – you’ll be stopped from doing that because of this switch. That’s annoying – since script webparts are incredibly useful!

However, that is the default setting on quite a few different sites – note that Microsoft explains it this way.

By default, script is allowed on sites that admins create. It is not allowed on OneDrive, on sites users create themselves, and on the root site for your organization.

That kind of makes sense. Custom scripting makes it possible to customize the sites quite extensively, and Microsoft doesn’t want that on OneDrive sites, or the good old MySites for SharePoint User Profiles.

Well, nowadays they don’t really want that anywhere, and for pretty good reasons. But let’s not get into that – that’s a whole paradigm debate! :)

Anyway, Microsoft continues:

If SharePoint Online was set up for your organization before 2015, your custom script settings might still be set to “Not Configured” even though in the SharePoint admin center they appear to be set to prevent users from running custom script. In this case, users won’t be able to copy items between SharePoint sites and between OneDrive and SharePoint. On the settings page of the SharePoint admin center, click OK to accept the custom script settings as they appear and enable cross-site copying.

Useful information. This means we’ll need to tweak the setting not only for sites with customization but also for some older sites.

Other situations when this might come up, is when uploading sandboxed solutions or any of the following file types.

“Script file types” that SharePoint blocks by default:
  • .asmx
  • .ascx
  • .aspx
  • .htc
  • .jar
  • .master
  • .swf
  • .xap
  • .xsf

These are all files that could potentially include code or scripts – JavaScript, Java, ActionScript, C# – so Microsoft prefers to block or restrict them on a lot of sites. For more info about this functionality, check out this KB page by Microsoft.

Is it really called “DenyAddAndCustomizePages”? Why?

Yes, that’s the name of the property blocking custom scripts on a Site Collection (or an SPSite, or just “Site” like they’re also called – confusing, I know!) It’s not a feature as in “SPFeature”, but it is often called the “NoScript feature”.

The naming is weird otherwise, too – instead of allowing or enabling custom scripts, you’re disabling the denial of the permission to add and customize pages. Yeah, pretty convoluted, right?

However, this just sounds like the whole option to have contributor users without permission to use the coolest webparts was just hindsight, something that was implemented 6 years after the whole permission model was implemented. And since SharePoint is a product with a long history, that wouldn’t be too surprising!

As said earlier, while Microsoft wants to let people work freely on their sites, they don’t want any customizations anymore – and using a Script Editor to inject custom JavaScript and cooler stylesheets is definitely a customization! So while Microsoft wants to empower users, they don’t want to empower them to break the sites.

And there was no permission level that would enable you to administer a site (like an owner), produce content (like a contributor/member), but not add your coolest JavaScript libraries on the site. If you could add a paragraph to a page, you could also inject your JavaScript into the page.

Perhaps I’ll go deeper into the security implications of this model in another post, but Microsoft realized it’s flawed and found a way around it. A new option that’s backward compatible (doesn’t usually break existing sites) and makes it possible for you to stop people from breaking the site.

What happens when you don’t enable Custom Scripting on a site?

The typical situation where this functionality comes up is this unfortunate dialog, which you could run into on your webpart pages:

“Web Part Error: A Web Part or Web Form Control on this Page cannot be displayed or imported. You don’t have Add and Customize Pages permissions required to perform this action.”
“Web Part Error: A Web Part or Web Form Control on this Page cannot be displayed or imported. You don’t have Add and Customize Pages permissions required to perform this action.”

It’s all different On-Premises…

Heh, because of course it is!

On-Premises (SharePoint Server 2010, 2013, 2016, 2019, and so on) the security model is slightly different. Custom Scripting is not disabled per se, but using Script Editor or Content Editor web parts might still be disabled for editors on the new web applications.

This means, that you’ll be severely limited with your webpart options by default!

The Classic webpart options missing all the fun ones - like Script Editor webpart and Content Editor webpart!
The Classic webpart options missing all the fun ones – like Script Editor webpart and Content Editor webpart!

How to get around the issue then? See below for the solutions I’ve found so far!

Solution(s)

This article explains a few different options on how to fix the issue! See below how to enable custom scripts on SharePoint Online / 2013 / 2016 / 2019 (check the “applies to” under each solution):

Enable custom scripts tenant-wide

Applies to: SharePoint Online

  • SharePoint MySites
  • Personal OneDrive sites
  • Any SharePoint site collection created based on self-service site creation

This is, of course, fairly straightforward. You can enable Custom Scripts (basically, this is equivalent of setting the “DenyAddAndCustomizePages” switch to false for the site) for the whole tenant at once.

You can do that using SharePoint Admin GUI. Here’s how to do that:

Time needed: 2 minutes

  1. Navigate to your O365 SharePoint Admin Portal

  2. Click “Settings“.

  3. Click the “classic settings page” (see below):



    The link is going to be something like https://[yourtenant]-admin.sharepoint.com/_layouts/15/online/TenantSettings.aspx

  4. Scroll down, down, down… A bit further down you’ll see these options – make sure they’re set to “Allow“:

    Enable custom scripts in SharePoint Online Admin Portal settings
    Enable custom scripts in SharePoint Online Admin Portal settings Enable custom scripts in SharePoint Online Admin Portal settings.

This change will come into action in the next 24 hours. No – it’s not instant.

However, if you don’t have 24 hours to wait, see the next solution.

Enable custom scripts using (vanilla) PowerShell

Applies to: SharePoint Online

  • Modern SharePoint Team Sites (attached to Office Groups)
  • Modern SharePoint Communication sites (after 08/2017)
  • Personal OneDrive sites
  • Any SharePoint site collection created based on self-service site creation
  • SharePoint Online tenant root site collection
  • Any Classic SharePoint site collection

This makes it possible to enable the custom scripts for any SharePoint Online site collection – even Modern ones! The snippet below shows how to enable it for one site – you can modify it to loop through all sites if you need to!

Below, you can see an example of the PowerShell script required for this change.

Connect-SPOService -Url https://[yourtenant]-admin.sharepoint.com -credential admin@[tenant].onmicrosoft.com 
Set-SPOSite -Identity https://[yourtenant].sharepoint.com/[siteurl] -DenyAddAndCustomizePages 0

Setting “-DenyAddAndCustomizePages 0” is equivalent to running “DenyAddAndCustomizePages $false” – since PowerShell treats 0 the same as a false boolean value.

You’ll only need SharePoint Online Management Shell, no other dependencies. Nice and simple!

The best part? Unlike the switch on the tenant admin site, this change should be practically instant!

Enable custom scripts using SharePoint Patterns and Practices (PnP) PowerShell

Applies to: SharePoint Online

And in one or more of the listed environments, it applies to these different site collection types:

  • Modern SharePoint Team Sites (attached to Office Groups if on SharePoint Online)
  • Modern SharePoint Communication sites (after 08/2017)
  • Personal OneDrive sites
  • Any SharePoint site collection created based on self-service site creation
  • SharePoint Online tenant root Site Collection
  • Any Classic SharePoint Site Collection

The script below should work for all of these 4 different environments, as long as you use the right version of the PnP PowerShell module.

# If you don't already have the modules, run Install-module first!
Import-Module -Name SharePointPnPPowerShellOnline -DisableNameChecking

Connect-PnPOnline -Url 'https://[yourtenant]-admin.sharepoint.com/' -Credentials (Get-Credential)

$DenyAddAndCustomizePagesStatusEnum = [Microsoft.Online.SharePoint.TenantAdministration.DenyAddAndCustomizePagesStatus]

$context = Get-PnPContext
$site = Get-PnPTenantSite -Detailed -Url 'https://[yourtenant].sharepoint.com/'

$site.DenyAddAndCustomizePages = $DenyAddAndCustomizePagesStatusEnum::Disabled

$site.Update()
$context.ExecuteQuery()

# This row should output list of your sites' URLs and the status of their custom scripting (disabled or not)
Get-PnPTenantSite -Detailed -Url 'https://[yourtenant].sharepoint.com/' | select url,DenyAddAndCustomizePages

Disconnect-PnPOnline

(See more: https://techcommunity.microsoft.com/t5/SharePoint-Developer/How-do-I-set-DenyAddAndCustomizePages-using-PnP/td-p/32372)

This script should be almost instant as well – we’re talking about a delay of 30 seconds or so, so quite an improvement over the switch on the tenant admin site!

However, if you want to apply this change to On-Premises environments, you might want to check out the following solution…

Enable custom scripts using PowerShell on SharePoint Server 2013/2016/2019

Applies to: SharePoint 2013 | SharePoint 2016 | SharePoint 2019

And in one or more of the listed environments, it applies to these different site collection types:

  • SharePoint MySites (On SharePoint Server)
  • Any Classic SharePoint Site Collection

With SharePoint Server, the story is a bit different.

First, you hit “Web Part Security” Central Administration’s web application management:

Each SharePoint Web Application has this GUI option in the Ribbon - "Web Part Security"
Each SharePoint Web Application has this GUI option in the Ribbon – “Web Part Security”

And you get this particular pop-up. Let’s take a closer look…

SharePoint Server has this "Security For Web Part Pages" dialog for Web Applications - it's used to set the similar "Custom Scripting" options, as on SharePoint Online.
SharePoint Server has this “Security For Web Part Pages” dialog for Web Applications – it’s used to set the similar “Custom Scripting” options, as on SharePoint Online.

So you now have these options for web applications.

Selection to allow or prevent scriptable web parts - e.g. that is "Script Editor" and "Content Editor" web parts.
Selection to allow or prevent scriptable web parts – e.g. that is “Script Editor” and “Content Editor” web parts.

By selecting “Allows contributors to add or edit scriptable Web Parts.” you enable the contributor/editor/member users to add those web parts on the page.

If you don’t want to (or can’t) use the GUI to enable this, you can also use this PowerShell:

$wa = get-spwebapplication "https://contoso.intranet.ch"

# Web application now has these 3 properties, that match the ones in the GUI:
$wa.AllowPartToPartCommunication
$wa.AllowAccessToWebPartCatalog
$wa.AllowContributorsToEditScriptableParts

# The last one affects the Custom Script Editor webparts:
$wa.AllowContributorsToEditScriptableParts = $true
$wa.Update()

After applying either one of the options above (GUI or PowerShell script), you’ll have the Script Editor and Content Editor webparts available. Check it out:

Yay, we've got the Script Editor available! Now we can do all the nasty stuff ourselves without the need of a Site Collection admin.
Yay, we’ve got the Script Editor available! Now we can do all the nasty stuff ourselves without the need of a Site Collection admin.

This change is practically instant. Yay for the pros of on-premises! ;)

Enable Custom Scripting using Chrome SP Editor

Applies to: SharePoint Online

  • Modern SharePoint Team Sites (attached to Office Groups)
  • Modern SharePoint Communication sites (after 08/2017)

Okay, this one was brought up by my friend and colleague Tomi Tavela. Can’t believe I didn’t think of it myself because it’s super obvious and I have used it myself – but you can of course do this with Chrome SP Editor as well!

I’ve written a fair bit about Chrome SP Editor already before, so I’m not going to go into the basics – let’s just jump straight to the solution!

How to activate Custom Scripts on a Modern SharePoint site using Chrome SP Editor:
  1. Navigate to your Tenant Administration
  2. Fire up your Chrome SP Editor (see screenshot below)
  3. Select “Modern properties” from the left-hand navigation (there are now so many features in the tool that you might need to scroll down a bit first!)
  4. Scroll down to the “Enable or disable running scripts…” part, find your site from the list (or use search or filtering), and click “Allow Scripts”.
  5. You should see the updated value refreshed on the list after a short while. Simple as that!

See the screenshots for the steps below!

How to access the Chrome SP Editor in your browser.
How to access the Chrome SP Editor in your browser.

And then:

To enable or disable Custom Scripting on a Modern Site Collection, you need to navigate to "Modern properties".
To enable or disable Custom Scripting on a Modern Site Collection, you need to navigate to “Modern properties”.

After which you get this:

You'll see a list of Modern Sites on your tenant - I love how the Chrome SP Editor even color codes them based on whether they're independent (white), hubs (green) or attached to a hub (yellow)!
You’ll see a list of Modern Sites on your tenant – I love how the Chrome SP Editor even color codes them based on whether they’re independent (white), hubs (green), or attached to a hub (yellow)!

It’s super useful, as you can search/filter even an incredibly large number of sites:

Chrome SP Editor can even filter the results based on template, url, title or Hub site association.
Chrome SP Editor can even filter the results based on template, URL, title, or Hub site association.

And the “Allow Scripts” -switch is quite a bit easier than using PowerShell :)

Flipping the "Allow Scripts" -switch in Chrome SP Editor only takes a few seconds and should be in action right away!
Flipping the “Allow Scripts” -switch in Chrome SP Editor only takes a few seconds and should be in action right away!

Further reading

For pretty good documentation about the whole NoScript stuff (on SharePoint Online), check out this page: https://support.office.com/en-us/article/allow-or-prevent-custom-script-1f2c515f-5d7e-448a-9fd7-835da935584f

mm
5 4 votes
Article Rating
Subscribe
Notify of
guest

24 Comments
most voted
newest oldest
Inline Feedbacks
View all comments