Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Commands/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"profiles": {
"profiles": {
"PnP.PowerShell-Module": {
"commandName": "Executable",
"executablePath": "pwsh",
Expand Down
79 changes: 49 additions & 30 deletions src/Commands/RecycleBin/RestoreRecycleBinItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,53 +10,72 @@ namespace PnP.PowerShell.Commands.RecycleBin
[OutputType(typeof(void))]
public class RestoreRecycleBinItem : PnPSharePointCmdlet
{
[Parameter(Mandatory = false, ValueFromPipeline = true)]
private const string ParameterSetName_RESTORE_MULTIPLE_ITEMS_BY_ID = "Restore Multiple Items By Id";
private const string ParameterSetName_RESTORE_SINGLE_ITEM_BY_ID = "Restore Single Items By Id";

[Parameter(Mandatory = false, ParameterSetName = ParameterSetName_RESTORE_SINGLE_ITEM_BY_ID, Position = 0, ValueFromPipeline = true)]
public RecycleBinItemPipeBind Identity;

[Parameter(Mandatory = false)]

[Parameter(Mandatory = false, ParameterSetName = ParameterSetName_RESTORE_SINGLE_ITEM_BY_ID)]
public SwitchParameter Force;

[Parameter(Mandatory = false)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSetName_RESTORE_SINGLE_ITEM_BY_ID)]
public int RowLimit;

[Parameter(Mandatory = true, ParameterSetName = ParameterSetName_RESTORE_MULTIPLE_ITEMS_BY_ID)]
public string[] IdList;

protected override void ExecuteCmdlet()
{
if (ParameterSpecified(nameof(Identity)))
switch (ParameterSetName)
{
var recycleBinItem = Identity.GetRecycleBinItem(Connection.PnPContext);
case ParameterSetName_RESTORE_SINGLE_ITEM_BY_ID:

if (recycleBinItem == null)
{
throw new PSArgumentException("Recycle bin item not found with the ID specified", nameof(Identity));
}

if (Force || ShouldContinue(string.Format(Resources.RestoreRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm))
{
recycleBinItem.Restore();
}
}
else
{
if (ParameterSpecified(nameof(RowLimit)))
{
if (Force || ShouldContinue(string.Format(Resources.Restore0RecycleBinItems, RowLimit), Resources.Confirm))
if (ParameterSpecified(nameof(Identity)))
{
var recycleBinItemCollection = RecycleBinUtility.GetRecycleBinItemCollection(ClientContext, RowLimit, RecycleBinItemState.None);
for (var i = 0; i < recycleBinItemCollection.Count; i++)
var recycleBinItem = Identity.GetRecycleBinItem(Connection.PnPContext);

if (recycleBinItem == null)
{
throw new PSArgumentException("Recycle bin item not found with the ID specified", nameof(Identity));
}

if (Force || ShouldContinue(string.Format(Resources.RestoreRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm))
{
var recycleBinItems = recycleBinItemCollection[i];
recycleBinItems.RestoreAll();
ClientContext.ExecuteQueryRetry();
recycleBinItem.Restore();
}
}
}
else
{
if (Force || ShouldContinue(Resources.RestoreRecycleBinItems, Resources.Confirm))
else
{
Connection.PnPContext.Site.RecycleBin.RestoreAll();
if (ParameterSpecified(nameof(RowLimit)))
{
if (Force || ShouldContinue(string.Format(Resources.Restore0RecycleBinItems, RowLimit), Resources.Confirm))
{
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
{
if (Force || ShouldContinue(Resources.RestoreRecycleBinItems, Resources.Confirm))
{
Connection.PnPContext.Site.RecycleBin.RestoreAll();
}
}
}
}
break;

case ParameterSetName_RESTORE_MULTIPLE_ITEMS_BY_ID:
RecycleBinUtility.RestoreRecycleBinItemInBulk(HttpClient, ClientContext, IdList);
break;

}
}
}
Expand Down
46 changes: 44 additions & 2 deletions src/Commands/Utilities/RecycleBinUtility.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
using Microsoft.SharePoint.Client;
using Newtonsoft.Json;
using PnP.PowerShell.Commands.Model.Mail;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Net;
using System.Net.Http;
using System.Xml.Linq;

namespace PnP.PowerShell.Commands.Utilities
{
Expand Down Expand Up @@ -99,8 +105,44 @@ internal static List<RecycleBinItemCollection> GetRecycleBinItemCollection(Clien
}
}
while (items?.Count == 5000);

return recycleBinItems;
}

internal static void RestoreRecycleBinItemInBulk(HttpClient httpClient, ClientContext ctx, string[] idsList)
{

Uri currentContextUri = new Uri(ctx.Url);
string apiCall = $"{currentContextUri}/_api/site/RecycleBin/RestoreByIds";

string idsString = string.Join("','", idsList); // Convert array to a comma-separated string

try
{
string requestBody = $"{{'ids':['{idsString}']}}";
REST.RestHelper.Post(httpClient, apiCall,ctx, requestBody,"application/json", "application/json");
}
catch
{
//fall back logic
//Unable to process as batch because of an error in restoring one of the ids in batch, processing individually
foreach (string id in idsList)
{
try
{
string requestBody = $"{{'ids':['{id}']}}";
REST.RestHelper.Post(httpClient, apiCall, ctx, requestBody, "application/json", "application/json");

}
catch
{
//Digest errors because they can be due to to the following two reasons and we cannot do anything
//1. Item with the same name already exists
//2. Item is no longer in recycle bin / Previously restored";

}
}
}
}
}
}
}
Loading