SharePoint Online を利用していると、リストに格納されたアイテムが 5,000 件を超えることも珍しくありません。こうしたリストのアイテムを PowerShell の CSOM で扱おうと思うと、5,000 件の壁にぶつかります。
これは、SharePoint Online からは一度に 5,000 件より多いアイテムを取得できないためです。ではどうするかというと、5,000 件の制限の範囲内で小分けにしてアイテムを取得していきます。ページングというやつですね。
ではさっそくスクリプトを見ていきましょう。
さっそくスクリプト
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
#リストが存在するサイトの URL
$siteUrl = "https://hogehoge.sharepoint.com/sites/hogehoge"
#リストの表示名
$listTitle = "ほげほげ"
#接続情報の登録とコンテキストの作成
$user = Read-Host -Prompt "Enter Username."
$password = Read-Host -Prompt "Enter Password." -AsSecureString
$credential = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $password)
$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$context.Credentials = $credential
#リストの取得
$list = $Context.get_web().get_lists().getByTitle($listTitle)
#5000 件を超える場合のためのページング準備
$caml = @"
<View Scope="Recursive">
<RowLimit Paged="TRUE">5000</RowLimit>
</View>
"@
$pagePosition = $null
$allItems = @()
#全リストアイテムの取得処理開始
Do{
$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$query.ListItemCollectionPosition = $pagePosition
$query.ViewXml = $caml
$listItems = $list.GetItems($query)
$context.Load($listItems)
$context.ExecuteQuery()
#つぎのページのポジションを保持
$pagePosition = $listItems.ListItemCollectionPosition
#取得したアイテムを保持
$allItems += $listItems
}
#つぎのページがなくなるまで実行
Until($pagePosition -eq $null)
#全リストアイテムの取得処理終了
Write-Host "ALL ITEMS COUNT: " $allItems.Count
20 行目付近で作成している CAML で RowLimit
に Paged="TRUE"
を指定してページングを有効にしています。また、32 行目で CamlQuery
の ListItemCollectionPosition
にページを指定してアイテムを取得するためのページ情報を指定しています。このページ情報は、つぎのページの情報がクエリの結果に返ってくるので、40 行目で変数に保存しておき次回のクエリで利用します。
あとは、つぎのページがなくなるまでループを回しながらアイテムを取得していきます。
さいごに
じつは SharePoint Online では、モダン UI のリストを中心に、これまでよく話題になっていた「5,000 件問題」を緩和すべく手が入ってきています。そのため、CSOM を利用した PowerShell からも 5,000 件を超えるアイテムが格納されたリストを扱う機会が増えると思いますので、今回の方法を覚えておくと利用できるシーンがあるかと思います。