Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #3861: adding capability to return a folder as list item #4151

Merged
merged 2 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 23 additions & 2 deletions documentation/Get-PnPFolder.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ Get-PnPFolder -CurrentWebRootFolder [-Includes <String[]>] [-Connection <PnPConn

### Folder by url
```powershell
Get-PnPFolder -Url <String> [-Includes <String[]>] [-Connection <PnPConnection>] [-Verbose]
Get-PnPFolder -Url <String> [-Includes <String[]>] [-AsListItem <SwitchParameter>] [-Connection <PnPConnection>] [-Verbose]
```

### Root folder of a list
```powershell
Get-PnPFolder -ListRootFolder <ListPipeBind> [-Includes <String[]>] [-Connection <PnPConnection>] [-Verbose]
Get-PnPFolder -ListRootFolder <ListPipeBind> [-Includes <String[]>] [-AsListItem <SwitchParameter>] [-Connection <PnPConnection>] [-Verbose]
```

### Folders In List
Expand Down Expand Up @@ -91,6 +91,13 @@ Get-PnPFolder -List "Shared Documents"

Returns the folders inside the root folder of the list called 'Shared Documents'. Please use Get-PnPFolder -ListRootFolder <folder> | Get-PnPFolderInFolder instead.

### EXAMPLE 7
```powershell
Get-PnPFolder -Url "/sites/demo/Shared Documents/Test" -AsListItem
```

Returns the folder called 'Test' which is located in the root of the site collection located at '/sites/demo' inside 'Shared Documents' document library as a SharePoint list item.

## PARAMETERS

### -CurrentWebRootFolder
Expand Down Expand Up @@ -164,6 +171,20 @@ Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```

### -AsListItem
Returns the folder as a listitem showing all its properties

```yaml
Type: SwitchParameter
Parameter Sets: Folder by url, Root folder of a list

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -Verbose
When provided, additional debug statements will be shown while executing the cmdlet.

Expand Down
144 changes: 81 additions & 63 deletions src/Commands/Files/GetFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public class GetFolder : PnPWebRetrievalsCmdlet<Folder>
private const string ParameterSet_FOLDERSINCURRENTWEB = "Folders in current Web";
private const string ParameterSet_CURRENTWEBROOTFOLDER = "Root folder of the current Web";
private const string ParameterSet_LISTROOTFOLDER = "Root folder of a list";
private const string ParameterSet_FOLDERSINLIST = "Folders In List";
private const string ParameterSet_FOLDERBYURL = "Folder by url";
private const string ParameterSet_FOLDERSINLIST = "Folders In List";
private const string ParameterSet_FOLDERBYURL = "Folder by url";

[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_FOLDERBYURL)]
[Alias("RelativeUrl")]
Expand All @@ -32,94 +32,112 @@ public class GetFolder : PnPWebRetrievalsCmdlet<Folder>
[Parameter(Mandatory = true, Position = 1, ParameterSetName = ParameterSet_CURRENTWEBROOTFOLDER)]
public SwitchParameter CurrentWebRootFolder;

[Parameter(Mandatory = false, ParameterSetName = ParameterSet_FOLDERBYURL)]
[Parameter(Mandatory = false, ParameterSetName = ParameterSet_LISTROOTFOLDER)]
public SwitchParameter AsListItem;

protected override void ExecuteCmdlet()
{
DefaultRetrievalExpressions = new Expression<Func<Folder, object>>[] { f => f.ServerRelativeUrl, f => f.Name, f => f.TimeLastModified, f => f.ItemCount };

Folder folder = null;
switch(ParameterSetName)
switch (ParameterSetName)
{
case ParameterSet_FOLDERSINCURRENTWEB:
{
WriteVerbose("Getting all folders in the root of the current web");
ClientContext.Load(CurrentWeb, w => w.Folders.IncludeWithDefaultProperties(RetrievalExpressions));
ClientContext.ExecuteQueryRetry();
WriteObject(CurrentWeb.Folders, true);
break;
}
{
WriteVerbose("Getting all folders in the root of the current web");
ClientContext.Load(CurrentWeb, w => w.Folders.IncludeWithDefaultProperties(RetrievalExpressions));
ClientContext.ExecuteQueryRetry();
WriteObject(CurrentWeb.Folders, true);
break;
}

case ParameterSet_CURRENTWEBROOTFOLDER:
{
WriteVerbose("Getting root folder of the current web");
folder = CurrentWeb.RootFolder;
ReturnFolderProperties(folder);
break;
}
{
WriteVerbose("Getting root folder of the current web");
folder = CurrentWeb.RootFolder;

ReturnFolderProperties(folder);
break;
}

case ParameterSet_LISTROOTFOLDER:
{
WriteVerbose("Getting root folder of the provided list");
var list = ListRootFolder.GetList(CurrentWeb);
folder = list.RootFolder;
ReturnFolderProperties(folder);
break;
}
{
WriteVerbose("Getting root folder of the provided list");
var list = ListRootFolder.GetList(CurrentWeb);
folder = list.RootFolder;

ReturnFolderProperties(folder);
break;
}

case ParameterSet_FOLDERSINLIST:
{
// Gets the provided list
{
// Gets the provided list
#pragma warning disable CS0618 // Type or member is obsolete
var list = List.GetList(CurrentWeb);
var list = List.GetList(CurrentWeb);
#pragma warning restore CS0618 // Type or member is obsolete

// Query for all folders in the list
CamlQuery query = CamlQuery.CreateAllFoldersQuery();
do
{
// Execute the query. It will retrieve all properties of the folders. Refraining to using the RetrievalExpressions would cause a tremendous increased load on SharePoint as it would have to execute a query per list item which would be less efficient, especially on lists with many folders, than just getting all properties directly
ListItemCollection listItems = list.GetItems(query);
ClientContext.Load(listItems, item => item.Include(t => t.Folder), item => item.ListItemCollectionPosition);
ClientContext.ExecuteQueryRetry();

// Take all the folders from the resulting list items and put them in a list to return
var folders = new List<Folder>(listItems.Count);
foreach (ListItem listItem in listItems)
// Query for all folders in the list
CamlQuery query = CamlQuery.CreateAllFoldersQuery();
do
{
var listFolder = listItem.Folder;
listFolder.EnsureProperties(RetrievalExpressions);
folders.Add(listFolder);
}

WriteObject(folders, true);

query.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);
break;
}
// Execute the query. It will retrieve all properties of the folders. Refraining to using the RetrievalExpressions would cause a tremendous increased load on SharePoint as it would have to execute a query per list item which would be less efficient, especially on lists with many folders, than just getting all properties directly
ListItemCollection listItems = list.GetItems(query);
ClientContext.Load(listItems, item => item.Include(t => t.Folder), item => item.ListItemCollectionPosition);
ClientContext.ExecuteQueryRetry();

// Take all the folders from the resulting list items and put them in a list to return
var folders = new List<Folder>(listItems.Count);
foreach (ListItem listItem in listItems)
{
var listFolder = listItem.Folder;
listFolder.EnsureProperties(RetrievalExpressions);
folders.Add(listFolder);
}

WriteObject(folders, true);

query.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);
break;
}

case ParameterSet_FOLDERBYURL:
{
WriteVerbose("Getting folder at the provided url");
var webServerRelativeUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl);
if (!Url.StartsWith(webServerRelativeUrl, StringComparison.OrdinalIgnoreCase))
{
Url = UrlUtility.Combine(webServerRelativeUrl, Url);
WriteVerbose("Getting folder at the provided url");
var webServerRelativeUrl = CurrentWeb.EnsureProperty(w => w.ServerRelativeUrl);
if (!Url.StartsWith(webServerRelativeUrl, StringComparison.OrdinalIgnoreCase))
{
Url = UrlUtility.Combine(webServerRelativeUrl, Url);
}
folder = CurrentWeb.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(Url));

ReturnFolderProperties(folder);
break;
}
folder = CurrentWeb.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(Url));

ReturnFolderProperties(folder);
break;
}
}
}

private void ReturnFolderProperties(Folder folder)
{
WriteVerbose("Retrieving folder properties");
folder?.EnsureProperties(RetrievalExpressions);
WriteObject(folder, false);

if (AsListItem.IsPresent)
{
folder?.EnsureProperties(RetrievalExpressions);
folder?.EnsureProperties(f => f.Exists, f => f.ListItemAllFields);
if (folder.Exists)
{
WriteObject(folder.ListItemAllFields);
}
}
else
{
folder?.EnsureProperties(RetrievalExpressions);
WriteObject(folder, false);
}

}
}
}
Loading