Skip to content

Commit

Permalink
Merge pull request #2866 from gautamdsheth/bug/restore-recycle-issue
Browse files Browse the repository at this point in the history
Feature/Fix #2485 - improved recycle bin item handling in Restore/Clear cmdlets
  • Loading branch information
KoenZomers authored Mar 10, 2023
2 parents 93df57a + 3f0bdf9 commit 105207d
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Properties of `Get-PnPAzureADServicePrincipal` are now all typed instead of some of them returning unparsed JSON fragments. [#2717](https://github.com/pnp/powershell/pull/2717)
- Changed `Add-PnPTeamsChannel` to no longer require an `-OwnerUPN` to be provided when specifying `-ChannelType Standard` [#2786](https://github.com/pnp/powershell/pull/2786)
- Changed `Add-PnPFile` by default to upload a file as a draft with a minor version now instead of publishing it as a major version. `-CheckinType MajorCheckIn` can be used to still upload the file as a major published version [#2806](https://github.com/pnp/powershell/pull/2806)
- Improved `Restore-PnPRecycleBinItem` and `Clear-PnPRecycleBinItem` cmdlets to better work with large items in recycle bin. [#2866] (https://github.com/pnp/powershell/pull/2866)
- Changed `Get-PnPUserProfileProperty` to no longer return additional user profile properties under UserProfileProperties but instead directly on the returned instance. [#2840](https://github.com/pnp/powershell/pull/2840)

### Removed
Expand Down
2 changes: 1 addition & 1 deletion documentation/Add-PnPFile.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ Managed Metadata (multiple values with paths to terms): -Values @{"MetadataField
Managed Metadata (multiple values with ids of terms): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818","52d88107-c2a8-4bf0-adfa-04bc2305b593"}
Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnp"}
Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnP"}
```yaml
Type: Hashtable
Expand Down
2 changes: 1 addition & 1 deletion documentation/Add-PnPListItem.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ Managed Metadata (multiple values with paths to terms): -Values @{"MetadataField
Managed Metadata (multiple values with ids of terms): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818","52d88107-c2a8-4bf0-adfa-04bc2305b593"}
Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnp"}
Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnP"}
```yaml
Type: Hashtable
Expand Down
2 changes: 1 addition & 1 deletion documentation/Add-PnPSiteTemplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Allows to add PnP Site Template object to a tenant template.

### EXAMPLE 1
```powershell
Add-PnpSiteTemplate -TenantTemplate $tenanttemplate -SiteTemplate $sitetemplate
Add-PnPSiteTemplate -TenantTemplate $tenanttemplate -SiteTemplate $sitetemplate
```

Adds an existing site template to an existing tenant template object
Expand Down
2 changes: 1 addition & 1 deletion documentation/Clear-PnpRecycleBinItem.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Allows to permanently delete items from recycle bin. By default the command will

### EXAMPLE 1
```powershell
Get-PnPRecycleBinItem | Where-Object LeafName -like "*.docx" | Clear-PnpRecycleBinItem
Get-PnPRecycleBinItem | Where-Object LeafName -like "*.docx" | Clear-PnPRecycleBinItem
```

Permanently deletes all the items in the first and second stage recycle bins of which the file names have the .docx extension
Expand Down
16 changes: 9 additions & 7 deletions src/Commands/RecycleBin/ClearRecycleBinItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.SharePoint.Client;

using PnP.PowerShell.Commands.Base.PipeBinds;
using PnP.PowerShell.Commands.Utilities;
using Resources = PnP.PowerShell.Commands.Properties.Resources;

namespace PnP.PowerShell.Commands.RecycleBin
Expand Down Expand Up @@ -45,15 +46,16 @@ protected override void ExecuteCmdlet()
if (ParameterSpecified(nameof(RowLimit)))
{
if (Force || ShouldContinue(SecondStageOnly ? Resources.ClearSecondStageRecycleBin : Resources.ClearBothRecycleBins, Resources.Confirm))
{
{
RecycleBinItemState recycleBinStage = SecondStageOnly ? RecycleBinItemState.SecondStageRecycleBin : RecycleBinItemState.None;

RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, recycleBinStage);
ClientContext.Load(items);
ClientContext.ExecuteQueryRetry();

items.DeleteAll();
ClientContext.ExecuteQueryRetry();
var recycleBinItemCollection = RecycleBinUtility.GetRecycleBinItemCollection(ClientContext, RowLimit, recycleBinStage);
for (var i = 0; i < recycleBinItemCollection.Count; i++)
{
var recycleBinItems = recycleBinItemCollection[i];
recycleBinItems.DeleteAll();
ClientContext.ExecuteQueryRetry();
}
}
}
else
Expand Down
15 changes: 8 additions & 7 deletions src/Commands/RecycleBin/RestoreRecycleBinItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.SharePoint.Client;

using PnP.PowerShell.Commands.Base.PipeBinds;
using PnP.PowerShell.Commands.Utilities;
using Resources = PnP.PowerShell.Commands.Properties.Resources;

namespace PnP.PowerShell.Commands.RecycleBin
Expand All @@ -24,7 +25,6 @@ protected override void ExecuteCmdlet()
{
if (ParameterSpecified(nameof(Identity)))
{

var recycleBinItem = Identity.GetRecycleBinItem(ClientContext.Site);

if (Force || ShouldContinue(string.Format(Resources.RestoreRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm))
Expand All @@ -39,12 +39,13 @@ protected override void ExecuteCmdlet()
{
if (Force || ShouldContinue(string.Format(Resources.Restore0RecycleBinItems, RowLimit), Resources.Confirm))
{
RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, RecycleBinItemState.None);
ClientContext.Load(items);
ClientContext.ExecuteQueryRetry();

items.RestoreAll();
ClientContext.ExecuteQueryRetry();
var recycleBinItemCollection = RecycleBinUtility.GetRecycleBinItemCollection(ClientContext, RowLimit, RecycleBinItemState.None);
for (var i = 0; i < recycleBinItemCollection.Count; i++)
{
var recycleBinItems = recycleBinItemCollection[i];
recycleBinItems.RestoreAll();
ClientContext.ExecuteQueryRetry();
}
}
}
else
Expand Down
49 changes: 45 additions & 4 deletions src/Commands/Utilities/RecycleBinUtility.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using Microsoft.SharePoint.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;

namespace PnP.PowerShell.Commands.Utilities
{
Expand Down Expand Up @@ -39,11 +37,11 @@ internal static List<RecycleBinItem> GetRecycleBinItems(ClientContext ctx, int?
{
iterationRowLimit = 5000;
}

items = ctx.Site.GetRecycleBinItems(pagingInfo, iterationRowLimit, false, RecycleBinOrderBy.DefaultOrderBy, recycleBinStage);
ctx.Load(items);
ctx.ExecuteQueryRetry();
recycleBinItems.AddRange(items.ToList());
recycleBinItems.AddRange(items.ToList());

// Paging magic (if needed)
// Based on this work our good friends at Portiva did ❤
Expand All @@ -61,5 +59,48 @@ internal static List<RecycleBinItem> GetRecycleBinItems(ClientContext ctx, int?

return recycleBinItems;
}

internal static List<RecycleBinItemCollection> GetRecycleBinItemCollection(ClientContext ctx, int? rowLimit = null, RecycleBinItemState recycleBinItemState = RecycleBinItemState.None)
{
string pagingInfo = null;
RecycleBinItemCollection items;
var recycleBinItems = new List<RecycleBinItemCollection>();

do
{
// We don't actually know what the List View Threshold for the Recycle Bin is, so we'll use the safe number (5000) and implement paging.
int iterationRowLimit;
if (rowLimit.HasValue && rowLimit.Value >= 5000)
{
// Subtract this page's count from the rowLimit (we don't want duplicates or go out of bounds)
if (rowLimit.HasValue) rowLimit -= 5000;

iterationRowLimit = 5000;
}
else if (rowLimit.HasValue && rowLimit.Value > 0 && rowLimit.Value < 5000)
{
iterationRowLimit = rowLimit.Value;
}
else
{
iterationRowLimit = 5000;
}

items = ctx.Site.GetRecycleBinItems(pagingInfo, iterationRowLimit, false, RecycleBinOrderBy.DefaultOrderBy, recycleBinItemState);
ctx.Load(items);
ctx.ExecuteQueryRetry();
recycleBinItems.Add(items);

if (items.Count > 0)
{
var nextId = items.Last().Id;
var nextTitle = WebUtility.UrlEncode(items.Last().Title);
pagingInfo = $"id={nextId}&title={nextTitle}";
}
}
while (items?.Count == 5000);

return recycleBinItems;
}
}
}

0 comments on commit 105207d

Please sign in to comment.