OneDrive for Business /Sharepoint Online Document LibraryをPnPPowershellで管理する
以前にも書きましたが、OneDrive for BusinessはSharePoint Onlineのドキュメントライブラリとして実装されてます。なので、ドキュメントライブラリを操作する技術でOneDrive for Businessを操作できます。
ドキュメントライブラリをPowershellで操作する(CSOM版)
最近はスマホなどを使った多要素認証(Multi-Factor-Authentication)を要求されることが多くなったのでそれに対応したPnPPowerShellを導入しました。
なので、PnPPowerShellをつかってOneDrive for Businessを操作する方法をメモしておきます。(前述のCSOMとライブラリが置き換わるようです)
目次
操作の準備
モジュールの導入
SharePointPnPPowerShellOnlineもしくはPnP.Powershellモジュールを使います。2022/8月現在、最新版はPnP.Powershellです。動作検証済です。
Install-Module PnP.Powershellを実行すればいいはずです。詳細は下記をご覧下さい。
Import-Module PnP.Powershell で使えるようになります。-verboseオプションをつかうとImportされるコマンドレットが出てくるので自分は指定してImportしてやります。
対象サイトにコネクトする
対象サイトを指定してConnectionを作ります。
1 2 3 4 |
$SiteCollectionUrl = "https://tenant-name.sharepoint.com/sites/SubSite-Name" #Or $SiteCollectionUrl = "https://tenant-name-my.sharepoint.com/personal/User-Name" $Connection = Connect-PnPOnline -Url $SiteCollectionUrl -Interactive |
-Interactiveオプションをつけると、Webでの認証が立ち上がってMFA認証を突破できます。ちょっと古い情報だと-UseWebLoginオプションの情報がヒットしますが、Interactiveオプションを使ってください、と警告が出ます。
ドキュメントライブラリの一覧を取得する
サイト内のリストを取得する
1 |
Get-PnPList -Connection $Connection |
このコマンドで接続先のサイトのリスト一覧が取得できます。
取得したいリスト(というかドキュメントライブラリ)の情報を確認しましょう。
1 2 |
$ListName = "Documents" $items = Get-PnPListItem -List $ListName |
これで、リストに含まれているアイテムは取得できます。が、問題があるのでちょっと改良します。
- ListNameが2バイトコードだとうまく動かないことがある。
- ListItemの情報だけとれて、必要な中身が取れないことがある。
ということで改善していきます。
Listを指定する
Get-PnPListItem のサンプルソースみると、-Listオプションの引数がListNameしか見つからないんですが、動きませんでした。まあ、サンプルソースが英語しかないからみたいなんですけど。2バイトコードだと動かないようで。引数の型指定が<ListPipeBind>しか書いてないし。
色々試したところ、Listに対するUnique IDなら動くようなのでIDを引っ張ります。
1 2 3 4 5 6 7 8 |
$Web = $Context.Web $Context.Load($Web) $Context.ExecuteQuery() $ListName = "Documents" $List = $Web.Lists.GetByTitle($ListName) $Context.Load($List) $Context.ExecuteQuery() $items = Get-PnPListItem -List $List.Id |
これでListNameが日本語になっても動きます。(将来的に修正されるかもしれませんが)
ListItemの中身の情報を取得する
Get-PnPListItemは特に指定しないとListItemのプロパティだけとって、中身のデータは取らないようです。汎用リスト向けのなのでそうなってるのかなぁ、という感じですが。DocumentLibraryのFieldを調べて -Fieldオプションを指定してやると取得時にFieldのデータを取得できます。
もしくはContextを$itemsに移して、Load,ExecuteQueryすれば取れるはずなんですが自分の環境ではうまくいきませんでした。(CSOMライブラリと共存してるからかも…)
1 2 |
Import-Module ImportExcel Get-PnPField -List $List.Id |Export-Excel .\DocLibField.xlsx -Show |
ここでは、ImportExcelモジュールを使ってxlsxファイルに出力、表示させています。
ImportExcelについてはこちらを御覧ください。PowerShellからxlsxファイルを直接操作できる大変便利なモジュールでおすすめです。
で、必要そうなfieldを指定して、hashtableに格納されるのでPSCustomObjectに格納し直して出力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$items = Get-PnPListItem -List $List.Id -Fields "FileRef", "File_x0020_Type", "FileLeafRef","FileDirRef","FileSizeDisplay","BaseName","File_x0020_Size","Last_x0020_Modified","Created_x0020_Date","Created","Author","Modified","Editor" $CSV = @() foreach($Item in $Items){ $value =$null $value =$item.FieldValuesAsText $Context.Load($value) $Context.ExecuteQuery() $value =$null $value =$item.FieldValuesAsText $Context.Load($value) $Context.ExecuteQuery() $data = New-Object PSObject -Property @{ Id =$Item.Id URLPath = $value.FieldValues.FileRef Path = $value.FieldValues.FileDirRef FileName = $value.FieldValues.FileLeafRef BaseName = $value.FieldValues.BaseName FileExtension = $value.FieldValues.File_x0020_Type FileSystemObjectType =$value.FieldValues.FileSystemObjectType FSObjType = $value.FieldValues.FSObjType FileSize = $value.FieldValues.File_x0020_Size 更新日時 = $value.FieldValues.Last_x0020_Modified 登録日時 = $value.FieldValues.Created_x0020_Date Created = $value.FieldValues.Created Author = $value.Author Modified = $value.FieldValues.Modified Editor = $value.FieldValues.Editor } $CSV += $data } $CSV|Export-Csv .\DocumentsListsData.csv -Encoding UTF8 -NoTypeInformation |
これでDocumentLibraryの全データを出力できます。
特定のフォルダの一階層を出力する
Get-PnPFolderItemを使うと特定のフォルダ階層のItemを取得できます。デフォルト動作は一階層だけですが、-Recursiveオプションがあるので指定したフォルダから下のItemすべてが取得できると思います。
[-FolderSiteRelativeUrl <String>] …取得したいフォルダまでの相対URLを指定
[-ItemType <String>] …Folder,Fileの指定。指定しないと両方
[-ItemName <String>] …指定したいItemの名前を指定
[-Recursive [<SwitchParameter>]] …再帰取得を指定
1 2 |
$items = Get-PnPFolderItem -Web $Web.Id -FolderSiteRelativeUrl $ListName $items|Export-Csv .\FolderItemLists.csv -Encoding UTF8 -NoTypeInformation |
フィルタを使用して特定のファイルを検索する
Find-PnPFileを利用すると、フィルタを使用してファイル一覧を取得できます。
1 |
$items = Find-PnPFile -Match "*.xlsx" -List $List.Id |
取得したファイルを保存する
Get-PnPFileを-AsFileオプションをつかって実行するとファイルとしてローカルに保存できます。
1 |
foreach($Item in $items){Get-PnPFile $item.ServerRelativeUrl -Path C:\tmp -Filename $Item.Name -AsFile} |
-Pathオプションは.(ドット、つまりカレントディレクトリ)は効かないようでした。同じファイル名があると警告がでるので、Find-PnPFIleやGet-PnPListItemで一括取得した場合はPowerShell側でManageしてください。