So I went to deploy to test and for some reason kept getting access denied errors, but I'm global admin!! and Site collection admin!! What. It died on the code where I am uploading to the master page gallery.
The problem was I had been deploying to /sites/site and not to the root web in other tests. The root web has a setting on it called DenyAddAndCustomizePagesStatus which is set to true but on the /sites/site sites, it's set to false :|. Even more annoying, I had also deployed to a demo tenant under the root web and this works, so I can only assume since it's a demo tenant with content that Microsofts code actually does this for you… https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f?ui=en-US&rs=en-US&ad=US
Here's the code for deactivating on your site collection. Thanks to Ronny Lewandowski and SPMeta2 for helping me to solve this issue :).
static void Main(string[] args) { string siteUrl = ConfigurationManager.AppSettings["SiteUrl"]; string adminUrl = ConfigurationManager.AppSettings["AdminUrl"]; string userName = ConfigurationManager.AppSettings["AdministratorUserName"]; string password = ConfigurationManager.AppSettings["AdministratorPassword"]; var securePassword = new SecureString(); foreach (var c in password) { securePassword.AppendChar(c); } Console.WriteLine("Start: Allow customisations..."); DisableDenyAddAndCustomizePages(adminUrl, siteUrl, userName, securePassword); Console.WriteLine("End: Allow customisations... \n"); } public static void DisableDenyAddAndCustomizePages(string adminUrl, string siteUrl, string userName, SecureString securePassword) { using (var ctx = new ClientContext(adminUrl)) { ctx.Credentials = new SharePointOnlineCredentials(userName, securePassword); Tenant tenant = new Tenant(ctx); var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true); ctx.Load(siteProperties); ctx.ExecuteQuery(); siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled; var result = siteProperties.Update(); ctx.Load(result); ctx.ExecuteQuery(); while (!result.IsComplete) { Thread.Sleep(result.PollingInterval); ctx.Load(result); ctx.ExecuteQuery(); } } }
ALSO, here is the code in PowerShell if you just want to quickly run it once:
Clear-Host $spOnlineUser = '' $spOnlinePassword = '' $spOnlineSiteAdminUrl = '' $spOnlineSiteUrl = '' $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $spOnlineUser, $(convertto-securestring $spOnlinePassword -asplaintext -force) Connect-SPOService -Url $spOnlineSiteAdminUrl -Credential $cred Write-Host "Connecting to " $spOnlineSiteUrl $site = Get-SPOSite -Identity $spOnlineSiteUrl Write-Host "Connection Successful!!" -ForegroundColor "Green" Set-SPOSite -Identity $spOnlineSiteUrl -DenyAddAndCustomizePages 0 Write-Host "Finished!!" -ForegroundColor "Green"
Thanks a lot to share. This saved my time. Incredible…