pnp / PnP-PowerShell

SharePoint PnP PowerShell CmdLets
https://pnp.github.io/powershell
Other
985 stars 665 forks source link

Get-PnPListItem: PageSize parameter does nothing #2143

Open mann-david opened 5 years ago

mann-david commented 5 years ago

Reporting an Issue or Missing Feature

Bug

Expected behavior

Running Get-PnPListItem -List $lst -Connection $myConnection -PageSize 4 should retrieve only 4 items from the list

Actual behavior

Running the command returns all items from the list

Steps to reproduce behavior

$myConnection = connect-pnponline -url "url" -ReturnConnection $lst = Get-PnPList -Identity "Test" -Connection $myConnection Get-PnPListItem -List $lst -Connection $myConnection -PageSize 4

2019-06-27_9-28-41

List has 10 items in it

Which version of the PnP-PowerShell Cmdlets are you using?

What is the version of the Cmdlet module you are running?

3.10.1906.0

How did you install the PnP-PowerShell Cmdlets?

ghost commented 5 years ago

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

reusto commented 4 years ago

According to the documentation the -PageSize parameter is responsible for setting "The number of items to retrieve per page request." Therefor getting all your items is the expected behavior, it just uses multiple request of 4 items per request to get them all.

What is missing in this case is a parameter to set the value how many items should be returned, which unfortunately isn't doable anymore even with the query parameter since the introduction of the -PageSize parameter. (see #879 )

The indented workaround/way to do it seems to be to set the -PageSize to 4 and then use the Select command with -first set to 4. (according to #888 )

Get-PnPListItem -List 'yourlist' -PageSize 4 | select -first 4 | Foreach {$items += $_}

mann-david commented 4 years ago

In case it helps someone else, here's a POSH function that does what I needed, using CSOM:

# if you're building a module, these two lines could also go into the RequiredAssemblies property of the PSD1 file
[reflection.assembly]::loadwithpartialname("Microsoft.SharePoint.Client") | Out-Null
[reflection.assembly]::loadwithpartialname("Microsoft.SharePoint.Client.Runtime") | Out-Null

function GetListItemsByQueryWithLimit([string]$qry, [string]$listName, [string]$siteURL, [PSCredential]$creds){
    $query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $query.ViewXml = $qry

    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
    $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($creds.Username, $creds.Password)
    $list = $Ctx.Web.lists.GetByTitle($listName)
    $listItems = $list.GetItems($query)
    $ctx.Load($listItems)
    $ctx.ExecuteQuery()

    return $listItems

}
mann-david commented 4 years ago

And a slightly more efficient option if you already have a Listand Contextin your POSH. You can just pass them in and cast the PnPContextto a standard CSOM ClientRuntimeContext to avoid having to recreate them in the function and have different contexts:

function GetListItemsByQueryWithLimit([string]$qry, [Microsoft.SharePoint.Client.List]$list, [OfficeDevPnP.Core.PnPClientContext]$PnPCtx) {
    $query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $query.ViewXml = $qry
    $ctx = [Microsoft.SharePoint.Client.ClientRuntimeContext]$PnPCtx
    $listItems = $list.GetItems($query)
    $ctx.Load($listItems)
    $ctx.ExecuteQuery()
    return $listItems
}
sympmarc commented 4 years ago

I suppose what the real question is here is what value the -Page-Size brings.

In the example from the docs:

Get-PnPListItem -List Tasks -PageSize 1000 Retrieves all list items from the Tasks list in pages of 1000 items

However, if there are more than 5000 items, we get the standard list view threshold error.

I had assumed the PageSize would page through and return the full set of items, regardless the number of items in the list. What is the intent?

simon-stealthbits commented 3 years ago

Regarding the lists with 5000 items issue.

I ran into the issue with threshold errors when querying SPO lists which contain more than 5000 items with regular CSOM code and resolved it by tweaking the content of the view XML of the CAML query and setting additional properties on the CamlQuery object.

The following are the tweaks which were required to get a query which worked against SharePoint On-Prem to work for SharePoint Online:

  1. The view should include an OrderBy clause which sorts by the ID column with Ascending set to TRUE
  2. The RowLimit element should have a Paged property set to TRUE,
  3. Note: The booleans in the view XML should be in all caps, SPO seemed pickier than on-prem,
  4. The AllowIncrementalResults property of the CamlQuery object should be set to true.

e.g. (assuming a variable PreviousListItemCollection is the ListItemCollection object from the previous page, or null)

Microsoft.SharePoint.Client.CamlQuery query = new Microsoft.SharePoint.Client.CamlQuery()
{
    ViewXml = @"<View>
            <Query><OrderBy><FieldRef Name="ID" Ascending="TRUE"/></OrderBy></Query>
            <RowLimit Paged='TRUE'>1000</RowLimit>
        </View>",
    ListItemCollectionPosition = PreviousListItemCollection?.ListItemCollectionPosition,
    AllowIncrementalResults = true
};