Skip to content

Commit 60ce6f7

Browse files
Merge pull request #4554 from gautamdsheth/fix/4203-allow-scripts
Fix #4203: Add -Force parameter to Add-PnPApp, Publish-PnPApp, Remove-PnPApp, and Unpublish-PnPApp to allow temporary script enabling on no-script sites
2 parents 0d9f2e7 + d523bd9 commit 60ce6f7

File tree

9 files changed

+280
-37
lines changed

9 files changed

+280
-37
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
3434
- Added `-AllowWebPropertyBagUpdateWhenDenyAddAndCustomizePagesIsEnabled` to `Set-PnPTenant` which allows for updating of web property bag when DenyAddAndCustomizePages is enabled [#4508](https://github.com/pnp/powershell/pull/4508)
3535
- Added `SiteId` to the output of `Get-PnPTenantSite` [#4527](https://github.com/pnp/powershell/pull/4527)
3636
- Added `Add-PnPFileSensitivityLabel` which allows for assigning sensitivity labels to SharePoint files [#4538](https://github.com/pnp/powershell/pull/4538)
37-
- Added `-CanSyncHubSitePermissions` parameter to `Set-PnPSite` cmdlet to set value of allowing syncing hub site permissions to this associated site.
37+
- `Add-PnPApp` , `Publish-PnPApp` , `Remove-PnPApp` and `Unpublish-PnPApp` now have `-Force` parameter to change the site to allow scripts to be temporarily enabled. [#4554](https://github.com/pnp/powershell/pull/4554)
38+
- Added `-CanSyncHubSitePermissions` parameter to `Set-PnPSite` cmdlet to set value of allowing syncing hub site permissions to this associated site. [#4555](https://github.com/pnp/powershell/pull/4555)
3839
- Added `Get-PnPProfileCardProperty`, `New-PnPProfileCardProperty` and `Remove-PnPProfileCardProperty` cmdlets to manage showing additional properties on the Microsoft 365 user profile [#4548](https://github.com/pnp/powershell/pull/4548)
3940
- Added `Get-PnPCopilotAdminLimitedMode` and `Set-PnPCopilotAdminLimitedMode` which allows for managing the setting that controls whether Microsoft 365 Copilot in Teams Meetings users can receive responses to sentiment-related prompts [#4562](https://github.com/pnp/powershell/pull/4562)
4041
- Added `-Contributors` and `-Managers` parameters to `New-PnPTermGroup` and `Set-PnPTermGroup` cmdlets.
@@ -64,9 +65,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
6465
- When passing in an existing connection using `-Connection` on `Connect-PnPOnline`, the clientid from the passed in connection will be used for the new connection [#4425](https://github.com/pnp/powershell/pull/4425)
6566
- Removed `-Confirm` parameter from `Remove-PnPUser` and `Remove-PnPAvailableSiteClassification` cmdlets. Use `-Force` instead. [#4455](https://github.com/pnp/powershell/pull/4455)
6667
- `Get-PnPFile` now also supports passing in a full SharePoint Online URL [#4480](https://github.com/pnp/powershell/pull/4480)
68+
- `Add-PnPApp` , `Publish-PnPApp` , `Remove-PnPApp` and `Unpublish-PnPApp` now support disabling script settings if tenant app catalog is a no-script site.
6769
- `Send-PnPMail` now throws a warning about the retirement of the SharePoint SendEmail API.
6870
- `Get-PnPCustomAction` now supports a completer for `-Identity` and uses the PnP Core SDK to return custom actions.
6971

72+
7073
### Fixed
7174

7275
- Fixed issue with `Set-PnPSearchExternalSchema` cmdlet when used with the `-Wait` parameter throwing a warning [#4253](https://github.com/pnp/powershell/pull/4253)

documentation/Add-PnPApp.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ Add/uploads an available app to the app catalog
1515
## SYNTAX
1616

1717
```powershell
18-
Add-PnPApp [-Path] <String> [-Scope <AppCatalogScope>] [-Overwrite] [-Timeout <Int32>] [-Publish [-SkipFeatureDeployment]]
19-
[-Connection <PnPConnection>]
18+
Add-PnPApp [-Path] <String> [-Scope <AppCatalogScope>] [-Overwrite] [-Timeout <Int32>] [-Publish [-SkipFeatureDeployment]] [-Connection <PnPConnection>] [-Force <SwitchParameter>]
2019
```
2120

2221
## DESCRIPTION
@@ -147,6 +146,20 @@ Accept pipeline input: False
147146
Accept wildcard characters: False
148147
```
149148
149+
### -Force
150+
If provided, no confirmation will be asked to change no-script setting.
151+
152+
```yaml
153+
Type: SwitchParameter
154+
Parameter Sets: (All)
155+
156+
Required: False
157+
Position: Named
158+
Default value: None
159+
Accept pipeline input: False
160+
Accept wildcard characters: False
161+
```
162+
150163
## RELATED LINKS
151164
152165
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

documentation/Publish-PnPApp.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ Publishes/Deploys/Trusts an available app in the app catalog
1515
## SYNTAX
1616

1717
```powershell
18-
Publish-PnPApp [-Identity] <AppMetadataPipeBind> [-SkipFeatureDeployment] [-Scope <AppCatalogScope>]
19-
[-Connection <PnPConnection>]
18+
Publish-PnPApp [-Identity] <AppMetadataPipeBind> [-SkipFeatureDeployment] [-Scope <AppCatalogScope>] [-Connection <PnPConnection>] [-Force <SwitchParameter>]
2019
```
2120

2221
## DESCRIPTION
@@ -97,6 +96,20 @@ Accept pipeline input: False
9796
Accept wildcard characters: False
9897
```
9998
99+
### -Force
100+
If provided, no confirmation will be asked to change no-script setting.
101+
102+
```yaml
103+
Type: SwitchParameter
104+
Parameter Sets: (All)
105+
106+
Required: False
107+
Position: Named
108+
Default value: None
109+
Accept pipeline input: False
110+
Accept wildcard characters: False
111+
```
112+
100113
## RELATED LINKS
101114
102115
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

documentation/Remove-PnPApp.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Removes an app from the app catalog.
1515
## SYNTAX
1616

1717
```powershell
18-
Remove-PnPApp [-Identity] <AppMetadataPipeBind> [-Scope <AppCatalogScope>] [-Connection <PnPConnection>]
18+
Remove-PnPApp [-Identity] <AppMetadataPipeBind> [-Scope <AppCatalogScope>] [-Connection <PnPConnection>] [-Force <SwitchParameter>]
1919
```
2020

2121
## DESCRIPTION
@@ -83,6 +83,20 @@ Accept pipeline input: False
8383
Accept wildcard characters: False
8484
```
8585
86+
### -Force
87+
If provided, no confirmation will be asked to change no-script setting.
88+
89+
```yaml
90+
Type: SwitchParameter
91+
Parameter Sets: (All)
92+
93+
Required: False
94+
Position: Named
95+
Default value: None
96+
Accept pipeline input: False
97+
Accept wildcard characters: False
98+
```
99+
86100
## RELATED LINKS
87101
88102
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

documentation/Unpublish-PnPApp.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Unpublishes/retracts an available add-in from the app catalog.
1515
## SYNTAX
1616

1717
```powershell
18-
Unpublish-PnPApp [-Identity] <AppMetadataPipeBind> [-Scope <AppCatalogScope>] [-Connection <PnPConnection>]
18+
Unpublish-PnPApp [-Identity] <AppMetadataPipeBind> [-Scope <AppCatalogScope>] [-Connection <PnPConnection>] [-Force <SwitchParameter>]
1919
2020
```
2121

@@ -84,6 +84,20 @@ Accept pipeline input: False
8484
Accept wildcard characters: False
8585
```
8686
87+
### -Force
88+
If provided, no confirmation will be asked to change no-script setting.
89+
90+
```yaml
91+
Type: SwitchParameter
92+
Parameter Sets: (All)
93+
94+
Required: False
95+
Position: Named
96+
Default value: None
97+
Accept pipeline input: False
98+
Accept wildcard characters: False
99+
```
100+
87101
## RELATED LINKS
88102
89103
[Microsoft 365 Patterns and Practices](https://aka.ms/m365pnp)

src/Commands/Apps/AddApp.cs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
using PnP.Framework.ALM;
1+
using Microsoft.Online.SharePoint.TenantAdministration;
2+
using Microsoft.SharePoint.Client;
3+
using PnP.Framework.ALM;
24
using PnP.Framework.Enums;
5+
using PnP.PowerShell.Commands.Base;
36
using System.Management.Automation;
47

58
namespace PnP.PowerShell.Commands.Apps
69
{
710
[Cmdlet(VerbsCommon.Add, "PnPApp")]
8-
public class AddApp : PnPSharePointCmdlet
11+
public class AddApp : PnPAdminCmdlet
912
{
1013
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
1114
public string Path;
@@ -25,8 +28,35 @@ public class AddApp : PnPSharePointCmdlet
2528
[Parameter(Mandatory = false)]
2629
public int Timeout = 200;
2730

31+
[Parameter(Mandatory = false)]
32+
public SwitchParameter Force;
33+
2834
protected override void ExecuteCmdlet()
2935
{
36+
bool isScriptSettingUpdated = false;
37+
38+
if (Scope == AppCatalogScope.Tenant)
39+
{
40+
var appcatalogUri = ClientContext.Web.GetAppCatalog();
41+
var ctx = ClientContext.Clone(appcatalogUri);
42+
WriteVerbose("Checking if the tenant app catalog is a no-script site");
43+
if (ctx.Site.IsNoScriptSite())
44+
{
45+
if (Force || ShouldContinue("The tenant appcatalog is a no-script site. Do you want to temporarily enable scripting on it?", Properties.Resources.Confirm))
46+
{
47+
WriteVerbose("Temporarily enabling scripting on the tenant app catalog site");
48+
var tenant = new Tenant(AdminContext);
49+
tenant.SetSiteProperties(appcatalogUri.AbsoluteUri, noScriptSite: false);
50+
isScriptSettingUpdated = true;
51+
}
52+
else
53+
{
54+
WriteWarning("Scripting is disabled on the tenant app catalog site. This command cannot proceed without allowing scripts.");
55+
return;
56+
}
57+
}
58+
}
59+
3060
if (!System.IO.Path.IsPathRooted(Path))
3161
{
3262
Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path);
@@ -42,7 +72,6 @@ protected override void ExecuteCmdlet()
4272

4373
try
4474
{
45-
4675
if (Publish)
4776
{
4877
if (manager.Deploy(result, SkipFeatureDeployment, Scope))
@@ -58,6 +87,18 @@ protected override void ExecuteCmdlet()
5887
manager.Remove(result, Scope);
5988
throw;
6089
}
90+
finally
91+
{
92+
if (isScriptSettingUpdated)
93+
{
94+
WriteVerbose("Disabling scripting on the tenant app catalog site");
95+
var appcatalogUri = ClientContext.Web.GetAppCatalog();
96+
var ctx = ClientContext.Clone(appcatalogUri);
97+
98+
var tenant = new Tenant(AdminContext);
99+
tenant.SetSiteProperties(appcatalogUri.AbsoluteUri, noScriptSite: true);
100+
}
101+
}
61102
}
62103
}
63104
}

src/Commands/Apps/PublishApp.cs

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
using PnP.Framework.Enums;
2-
1+
using Microsoft.Online.SharePoint.TenantAdministration;
2+
using Microsoft.SharePoint.Client;
3+
using PnP.Framework.Enums;
4+
using PnP.PowerShell.Commands.Base;
35
using PnP.PowerShell.Commands.Base.PipeBinds;
46
using System;
57
using System.Management.Automation;
68

79
namespace PnP.PowerShell.Commands.Apps
810
{
911
[Cmdlet(VerbsData.Publish, "PnPApp")]
10-
public class PublishApp : PnPSharePointCmdlet
12+
public class PublishApp : PnPAdminCmdlet
1113
{
1214
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
1315
public AppMetadataPipeBind Identity;
@@ -18,17 +20,64 @@ public class PublishApp : PnPSharePointCmdlet
1820
[Parameter(Mandatory = false, ValueFromPipeline = true)]
1921
public AppCatalogScope Scope = AppCatalogScope.Tenant;
2022

23+
[Parameter(Mandatory = false)]
24+
public SwitchParameter Force;
25+
2126
protected override void ExecuteCmdlet()
2227
{
23-
var manager = new PnP.Framework.ALM.AppManager(ClientContext);
28+
bool isScriptSettingUpdated = false;
2429

25-
var app = Identity.GetAppMetadata(ClientContext, Scope);
26-
if (app != null)
30+
if (Scope == AppCatalogScope.Tenant)
2731
{
28-
manager.Deploy(app, SkipFeatureDeployment, Scope);
29-
} else
32+
var appcatalogUri = ClientContext.Web.GetAppCatalog();
33+
var ctx = ClientContext.Clone(appcatalogUri);
34+
WriteVerbose("Checking if the tenant app catalog is a no-script site");
35+
if (ctx.Site.IsNoScriptSite())
36+
{
37+
if (Force || ShouldContinue("The tenant appcatalog is a no-script site. Do you want to temporarily enable scripting on it?", Properties.Resources.Confirm))
38+
{
39+
WriteVerbose("Temporarily enabling scripting on the tenant app catalog site");
40+
var tenant = new Tenant(AdminContext);
41+
tenant.SetSiteProperties(appcatalogUri.AbsoluteUri, noScriptSite: false);
42+
isScriptSettingUpdated = true;
43+
}
44+
else
45+
{
46+
WriteWarning("Scripting is disabled on the tenant app catalog site. This command cannot proceed without allowing scripts.");
47+
return;
48+
}
49+
}
50+
}
51+
52+
try
3053
{
31-
throw new Exception("Cannot find app");
54+
var manager = new PnP.Framework.ALM.AppManager(ClientContext);
55+
56+
var app = Identity.GetAppMetadata(ClientContext, Scope);
57+
if (app != null)
58+
{
59+
manager.Deploy(app, SkipFeatureDeployment, Scope);
60+
}
61+
else
62+
{
63+
throw new Exception("Cannot find app");
64+
}
65+
}
66+
catch
67+
{
68+
throw;
69+
}
70+
finally
71+
{
72+
if (isScriptSettingUpdated)
73+
{
74+
WriteVerbose("Disabling scripting on the tenant app catalog site");
75+
var appcatalogUri = ClientContext.Web.GetAppCatalog();
76+
var ctx = ClientContext.Clone(appcatalogUri);
77+
78+
var tenant = new Tenant(AdminContext);
79+
tenant.SetSiteProperties(appcatalogUri.AbsoluteUri, noScriptSite: true);
80+
}
3281
}
3382
}
3483
}

0 commit comments

Comments
 (0)