Skip to content
This repository has been archived by the owner on Jan 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2957 from pnp/dev
Browse files Browse the repository at this point in the history
October 2020 Release
  • Loading branch information
erwinvanhunen authored Oct 12, 2020
2 parents f9c1596 + 1adf0eb commit 7318423
Show file tree
Hide file tree
Showing 37 changed files with 925 additions and 100 deletions.
Binary file modified Binaries/SharePointPnP.Modernization.Framework.dll
Binary file not shown.
Binary file modified Binaries/release/SharePointPnP.Modernization.Framework.dll
Binary file not shown.
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [3.26.2010.0 - unreleased]

### Added
- Added `Set-PnPTenant -EnableAutoNewsDigest` option to disable the automatic news digest mails sent to end users [PR #2901](https://github.com/pnp/PnP-PowerShell/pull/2901)
- Added `Register-PnPManagementShellAccess` cmdlet to register correct access required for the multi-tenant application PnP Management Shell which is used behind the scenes of the Provisioning Engine for certain actions towards SharePoint Online.
- Added the description being shown of a Site Script when running `Get-PnPSiteScript` [PR #2895](https://github.com/pnp/PnP-PowerShell/pull/2895)
- Added -Includes to `Get-PnPUser` [PR #2939](https://github.com/pnp/PnP-PowerShell/pull/2939)
- Added an sample for Azure Automation [PR #2835](https://github.com/pnp/PnP-PowerShell/pull/2835)
- Added -DisableCustomAppAuthentication to `Set-PnPTenant` [PR #2923](https://github.com/pnp/PnP-PowerShell/pull/2923)

### Changed
- Fixed example for `Get-PnPTeamsChannel` [PR #2919](https://github.com/pnp/PnP-PowerShell/pull/2919)
- Fixed possible token acquisition issue when extracting a tenant template. [PR #2874](https://github.com/pnp/PnP-PowerShell/pull/2874)
- Fixed scenario when no configuration file provided with Get-PnPTenantTemplate throws an undefined error [PR #2873](https://github.com/pnp/PnP-PowerShell/pull/2873)
- Fixed examples for `New-PnPTeamsTeam` [PR #2870](https://github.com/pnp/PnP-PowerShell/pull/2870)
- Updated documentation for `Get-PnPField` [PR #2856](https://github.com/pnp/PnP-PowerShell/pull/2856)
- Updated documentation for `Get-PnPListItem` [PR #2806](https://github.com/pnp/PnP-PowerShell/pull/2806)
- Improved certificate file handling and errors shown if the file does not exist, is empty or points to a folder [PR #2888](https://github.com/pnp/PnP-PowerShell/pull/2888)
- Fixed issue with where connecting with Connect-PnPOnline to an URL ending on a slash could cause an exception when using some cmdlets.

### Contributors
- Koen Zomers [koenzomers]
- Gautam Sheth [gautamdsheth]
- Giacomo Pozzoni [jackpoz]
- James May [fowl2]
- Aimery Thomas [a1mery]
- Heinrich Ulbricht [heinrich-ulbricht]
- Veronique Lengelle [veronicageek]
- Todd Klindt [ToddKlindt]
- Paul Bullock [pkbullock]

## [3.25.2009.1]

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Commands/Admin/GetStorageEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace PnP.PowerShell.Commands
{
[Cmdlet(VerbsCommon.Get, "PnPStorageEntity", SupportsShouldProcess = true)]
[Cmdlet(VerbsCommon.Get, "PnPStorageEntity")]
[CmdletHelp(@"Retrieve Storage Entities / Farm Properties from either the Tenant App Catalog or from the current site if it has a site scope app catalog.",
Category = CmdletHelpCategory.TenantAdmin,
SupportedPlatform = CmdletSupportedPlatform.Online)]
Expand Down
2 changes: 1 addition & 1 deletion Commands/Admin/GetTenantAppCatalogUrl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace PnP.PowerShell.Commands
{
[Cmdlet(VerbsCommon.Get, "PnPTenantAppCatalogUrl", SupportsShouldProcess = true)]
[Cmdlet(VerbsCommon.Get, "PnPTenantAppCatalogUrl")]
[CmdletHelp(@"Retrieves the url of the tenant scoped app catalog",
Category = CmdletHelpCategory.TenantAdmin,
SupportedPlatform = CmdletSupportedPlatform.Online)]
Expand Down
2 changes: 1 addition & 1 deletion Commands/Admin/GetTenantSite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace PnP.PowerShell.Commands
{
[Cmdlet(VerbsCommon.Get, "PnPTenantSite", SupportsShouldProcess = true)]
[Cmdlet(VerbsCommon.Get, "PnPTenantSite")]
[CmdletHelp(@"Retrieve site information.", "Use this cmdlet to retrieve site information from your tenant administration.",
Category = CmdletHelpCategory.TenantAdmin,
SupportedPlatform = CmdletSupportedPlatform.SP2016 | CmdletSupportedPlatform.SP2019 | CmdletSupportedPlatform.Online,
Expand Down
16 changes: 16 additions & 0 deletions Commands/Admin/SetTenant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,12 @@ The only two characters that can be managed at this time are the # and % charact

[Parameter(Mandatory = false, HelpMessage = "Boolean indicating if Azure Information Protection (AIP) should be enabled on the tenant. For more information, see https://docs.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files#use-powershell-to-enable-support-for-sensitivity-labels")]
public bool? EnableAIPIntegration;

[Parameter(Mandatory = false)]
public bool? DisableCustomAppAuthentication;

[Parameter(Mandatory = false, HelpMessage = "Boolean indicating if a news digest should automatically be sent to end users to inform them about news that they may have missed. On by default. For more information, see https://aka.ms/autonewsdigest")]
public bool? EnableAutoNewsDigest;

protected override void ExecuteCmdlet()
{
Expand Down Expand Up @@ -972,6 +978,16 @@ protected override void ExecuteCmdlet()
Tenant.EnableAIPIntegration = EnableAIPIntegration.Value;
isDirty = true;
}
if (DisableCustomAppAuthentication.HasValue)
{
Tenant.DisableCustomAppAuthentication = DisableCustomAppAuthentication.Value;
isDirty = true;
}
if (EnableAutoNewsDigest.HasValue)
{
Tenant.EnableAutoNewsDigest = EnableAutoNewsDigest.Value;
isDirty = true;
}
if (isDirty)
{
ClientContext.ExecuteQueryRetry();
Expand Down
4 changes: 2 additions & 2 deletions Commands/Admin/SetTenantSyncClientRestriction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class SetTenantSyncClientRestriction : PnPAdminCmdlet
[Parameter(Mandatory = false, HelpMessage = @"Blocks certain file types from syncing with the new sync client (OneDrive.exe). Provide as one string separating the extensions using a semicolon (;). I.e. ""docx;pptx""")]
public List<string> ExcludedFileExtensions;

[Parameter(Mandatory = false, HelpMessage = "Controls whether or not a tenant's users can sync OneDrive for Business libraries with the old OneDrive for Business sync client. The valid values are OptOut, HardOptin, and SoftOptin.")]
[Parameter(Mandatory = false, HelpMessage = "Controls whether or not a tenant's users can sync OneDrive for Business libraries with the old OneDrive for Business sync client. The valid values are OptOut, HardOptin, and SoftOptin. GrooveBlockOption is planned to be deprecated. Please refrain from using the parameter.")]
public Enums.GrooveBlockOption GrooveBlockOption;

protected override void ExecuteCmdlet()
Expand Down Expand Up @@ -90,4 +90,4 @@ protected override void ExecuteCmdlet()
}
}
}
#endif
#endif
5 changes: 5 additions & 0 deletions Commands/Base/ConnectOnline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,11 @@ protected override void ProcessRecord()
/// </summary>
protected void Connect()
{
if (!string.IsNullOrEmpty(Url) && Url.EndsWith("/"))
{
Url = Url.Substring(0, Url.Length - 1);
}

PnPConnection connection = null;

var latestVersion = PnPConnectionHelper.GetLatestVersion();
Expand Down
14 changes: 3 additions & 11 deletions Commands/Base/InitializePowerShellAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,24 +250,16 @@ protected override void ProcessRecord()
record.Properties.Add(new PSVariableProperty(new PSVariable("AzureAppId", azureApp.AppId)));

var waitTime = 60;
Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Waiting {waitTime} seconds to launch consent flow in a browser window. This wait is required to make sure that Azure AD is able to initialize all required artifacts.");

Console.TreatControlCAsInput = true;
Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Waiting {waitTime} seconds to start the consent flow in a browser window. This wait is required to make sure that Azure AD is able to initialize all required artifacts.");

for (var i = 0; i < waitTime; i++)
{
Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, ".");
System.Threading.Thread.Sleep(1000);

// Check if CTRL+C has been pressed and if so, abort the wait
if (Host.UI.RawUI.KeyAvailable)
if (Stopping)
{
var key = Host.UI.RawUI.ReadKey(ReadKeyOptions.AllowCtrlC | ReadKeyOptions.NoEcho | ReadKeyOptions.IncludeKeyUp);
if ((key.ControlKeyState.HasFlag(ControlKeyStates.LeftCtrlPressed) || key.ControlKeyState.HasFlag(ControlKeyStates.RightCtrlPressed)) && key.VirtualKeyCode == 67)
{

break;
}
break;
}
}
Host.UI.WriteLine();
Expand Down
37 changes: 37 additions & 0 deletions Commands/Base/RegisterPnPManagementShellAccess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Microsoft.Identity.Client;
using OfficeDevPnP.Core;
using PnP.PowerShell.CmdletHelpAttributes;
using PnP.PowerShell.Commands.Model;
using System;
using System.Management.Automation;

namespace PnP.PowerShell.Commands.Base
{
[Cmdlet(VerbsLifecycle.Register, "PnPManagementShellAccess")]
[CmdletHelp("Registers the multi-tenant app PnP Management Shell for delegate access to the required environments",
Category = CmdletHelpCategory.TenantAdmin)]
[CmdletExample(
Code = "PS:> Register-PnPManagementShellAccess -SiteUrl https://yourtenant.sharepoint.com",
Remarks = "Will prompt you to authenticate and if needed will ask you to provide consent to specific required rights.",
SortOrder = 1)]
public class RegisterPnPManagementShellAccess : PSCmdlet
{
[Parameter(Mandatory = false)]
public AzureEnvironment AzureEnvironment = AzureEnvironment.Production;

[Parameter(Mandatory = true)]
public string SiteUrl;
protected override void ProcessRecord()
{
var endPoint = GenericToken.GetAzureADLoginEndPoint(AzureEnvironment);
var uri = new Uri(SiteUrl);
var scopes = new[] { $"{uri.Scheme}://{uri.Authority}//.default" };

var application = PublicClientApplicationBuilder.Create(PnPConnection.PnPManagementShellClientId).WithAuthority($"{endPoint}/organizations/").WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient").Build();

var result = application.AcquireTokenInteractive(scopes).ExecuteAsync().GetAwaiter().GetResult();
result = application.AcquireTokenInteractive(new[] { "https://graph.microsoft.com/.default" }).ExecuteAsync().GetAwaiter().GetResult();

}
}
}
2 changes: 1 addition & 1 deletion Commands/Base/TokenHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static string AcquireToken(string resource, string scope = null)
if (scope == null)
{
// SharePoint or Graph V1 resource
var scopes = new[] { $"https://{resource}//.default" };
var scopes = new[] { $"https://{resource.Replace("https://","").TrimEnd('/')}/.default" };
token = GenericToken.AcquireDelegatedTokenWithCredentials(PnPConnection.PnPManagementShellClientId, scopes, "https://login.microsoftonline.com/organizations/", PnPConnection.CurrentConnection.PSCredential.UserName, PnPConnection.CurrentConnection.PSCredential.Password);
}
else
Expand Down
2 changes: 1 addition & 1 deletion Commands/Fields/AddField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace PnP.PowerShell.Commands.Fields
{
[Cmdlet(VerbsCommon.Add, "PnPField", DefaultParameterSetName = "Add field to list")]
[CmdletHelp("Add a field",
"Adds a field to a list or as a site column",
"Adds a field (a column) to a list or as a site column. To add a column of type Managed Metadata use the Add-PnPTaxonomyField cmdlet",
Category = CmdletHelpCategory.Fields,
OutputType = typeof(Field),
OutputTypeLink = "https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee545882(v=office.15)",
Expand Down
2 changes: 1 addition & 1 deletion Commands/Lists/GetListItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace PnP.PowerShell.Commands.Lists
Remarks = "Retrieves all list items from the Tasks list in pages of 1000 items",
SortOrder = 7)]
[CmdletExample(
Code = "PS:> Get-PnPListItem -List Tasks -PageSize 1000 -ScriptBlock { Param($items) $items.Context.ExecuteQuery() } | % { $_.BreakRoleInheritance($true, $true) }",
Code = "PS:> Get-PnPListItem -List Tasks -PageSize 1000 -ScriptBlock { Param($items) $items.Context.ExecuteQuery() } | ForEach-Object { $_.BreakRoleInheritance($true, $true) }",
Remarks = "Retrieves all list items from the Tasks list in pages of 1000 items and breaks permission inheritance on each item",
SortOrder = 8)]
[CmdletExample(
Expand Down
80 changes: 75 additions & 5 deletions Commands/Model/GenericToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using System.Threading.Tasks;
using System.Security;
using OfficeDevPnP.Core;
using System.Management.Automation;
using PnP.PowerShell.Commands.Base;

namespace PnP.PowerShell.Commands.Model
{
Expand Down Expand Up @@ -181,11 +183,28 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI

try
{
tokenResult = confidentialClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult();
tokenResult = confidentialClientApplication.AcquireTokenSilent(scopes, account.First()).WithForceRefresh(true).ExecuteAsync().GetAwaiter().GetResult();
}
catch
{
tokenResult = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().GetAwaiter().GetResult();
try
{
tokenResult = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().GetAwaiter().GetResult();
}
catch (MsalUiRequiredException msalEx)
{
if (msalEx.Classification == UiRequiredExceptionClassification.ConsentRequired)
{
if (clientId == PnPConnection.PnPManagementShellClientId)
{
throw new PSInvalidOperationException("Please provide consent to the PnP Management Shell application with 'Register-PnPManagementShellAccess' and follow the steps on screen.");
}
else
{
throw msalEx;
}
}
}
}

return new GenericToken(tokenResult.AccessToken);
Expand Down Expand Up @@ -228,7 +247,24 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI
}
catch
{
tokenResult = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().GetAwaiter().GetResult();
try
{
tokenResult = confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync().GetAwaiter().GetResult();
}
catch (MsalUiRequiredException msalEx)
{
if (msalEx.Classification == UiRequiredExceptionClassification.ConsentRequired)
{
if (clientId == PnPConnection.PnPManagementShellClientId)
{
throw new PSInvalidOperationException("Please provide consent to the PnP Management Shell application with 'Register-PnPManagementShellAccess' and follow the steps on screen.");
}
else
{
throw msalEx;
}
}
}
}
return new GenericToken(tokenResult.AccessToken);
}
Expand Down Expand Up @@ -267,7 +303,24 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s
}
catch
{
tokenResult = publicClientApplication.AcquireTokenInteractive(scopes).ExecuteAsync().GetAwaiter().GetResult();
try
{
tokenResult = publicClientApplication.AcquireTokenInteractive(scopes).WithExtraScopesToConsent(new[] { "https://graph.microsoft.com/.default" }).ExecuteAsync().GetAwaiter().GetResult();
}
catch (MsalUiRequiredException msalEx)
{
if (msalEx.Classification == UiRequiredExceptionClassification.ConsentRequired)
{
if (clientId == PnPConnection.PnPManagementShellClientId)
{
throw new PSInvalidOperationException("Please provide consent to the PnP Management Shell application with 'Register-PnPManagementShellAccess' and follow the steps on screen.");
}
else
{
throw msalEx;
}
}
}
}
return new GenericToken(tokenResult.AccessToken);
}
Expand Down Expand Up @@ -351,7 +404,24 @@ public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId,
}
catch
{
tokenResult = publicClientApplication.AcquireTokenByUsernamePassword(scopes, username, securePassword).ExecuteAsync().GetAwaiter().GetResult();
try
{
tokenResult = publicClientApplication.AcquireTokenByUsernamePassword(scopes, username, securePassword).ExecuteAsync().GetAwaiter().GetResult();
}
catch (MsalUiRequiredException msalEx)
{
if (msalEx.Classification == UiRequiredExceptionClassification.ConsentRequired)
{
if (clientId == PnPConnection.PnPManagementShellClientId)
{
throw new PSInvalidOperationException("Please provide consent to the PnP Management Shell application with 'Register-PnPManagementShellAccess' and follow the steps on screen.");
}
else
{
throw msalEx;
}
}
}
}

return new GenericToken(tokenResult.AccessToken);
Expand Down
3 changes: 2 additions & 1 deletion Commands/Model/GraphToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using PnP.PowerShell.Commands.Utilities;
using System;
using System.Linq;
using System.Management.Automation;
using System.Security;
using System.Security.Cryptography.X509Certificates;

Expand Down Expand Up @@ -39,7 +40,7 @@ public GraphToken(string accesstoken) : base(accesstoken)
public static GraphToken AcquireApplicationToken(string tenant, string clientId, X509Certificate2 certificate, AzureEnvironment azureEnvironment)
{
var endPoint = GenericToken.GetAzureADLoginEndPoint(azureEnvironment);
return new GraphToken(GenericToken.AcquireApplicationToken(tenant, clientId, $"{endPoint}/{tenant}", new[] { $"{ResourceIdentifier}/{DefaultScope}" }, certificate).AccessToken);
return new GraphToken(GenericToken.AcquireApplicationToken(tenant, clientId, $"{endPoint}/{tenant}", new[] { $"{ResourceIdentifier}/{DefaultScope}" }, certificate).AccessToken);
}

/// <summary>
Expand Down
5 changes: 5 additions & 0 deletions Commands/Model/SPOTenant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public SPOTenant(Tenant tenant)
this.provisionSharedWithEveryoneFolder = tenant.ProvisionSharedWithEveryoneFolder;
this.signInAccelerationDomain = tenant.SignInAccelerationDomain;
this.disabledWebPartIds = tenant.DisabledWebPartIds;

try
{
this.enableGuestSignInAcceleration = tenant.EnableGuestSignInAcceleration;
Expand Down Expand Up @@ -471,6 +472,8 @@ public SPOTenant(Tenant tenant)

public Guid[] DisabledWebPartIds => disabledWebPartIds;

public bool DisableCustomAppAuthentication => disableCustomAppAuthentication;

private bool hideDefaultThemes;

private long storageQuota;
Expand Down Expand Up @@ -600,6 +603,8 @@ public SPOTenant(Tenant tenant)
private int emailAttestationReAuthDays;

private Guid[] disabledWebPartIds;

private bool disableCustomAppAuthentication;
}
}
#endif
Loading

0 comments on commit 7318423

Please sign in to comment.