Share Point Online上のファイル一覧取得Power Shell


#0.Intro
Share Point上のドキュメント ライブラリ内のファイルを整理する目的で作成しました。どうもドキュメント ライブラリにPnPが使えないらしく苦労しました。
あっちこっちのサイトを参考に作成しましたが、このようにまとまった形で公開することで、僕のような人の為になったら幸いです。公開していますがコード、正確にわかっていません。でも共有することを優先しました。

#1.本論
SharePoint クライアント オブジェクト モデル (CSOM)はSharePoint上のデータを扱うに辺り必須です。まず読み込みましょう。以下のように関数にまとめと扱いやすいと思います。

```
function Load-SPOnlineCSOMAssemblies
{
Load-SPOnlineCSOMAssembly "Microsoft.SharePoint.Client.dll"
Load-SPOnlineCSOMAssembly "Microsoft.SharePoint.Client.Publishing.dll"
Load-SPOnlineCSOMAssembly "Microsoft.SharePoint.Client.Runtime.dll"
Load-SPOnlineCSOMAssembly "Microsoft.SharePoint.Client.Search.dll"
}
```

先のライブラリを関数を呼び出し読み込み。
対象のサイトを指定し接続します。読み込み対象のサイトのアドレスの確認はGet-SPOSiteを使うとテナント内のサイト一覧が取得できるので良いかと思います。
蛇足かとは思いますが、Get-SPOSiteを叩く際は
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
Connect-SPOService https://XXXXX-admin.sharepoint.com/
という風にテナント名に-adminが付いた管理サイトにアクセスしてから叩く必要があります。
認証部分も僕は苦労しましたが、ポイントはパスワードのところかと思います。

```
Load-SPOnlineCSOMAssemblies

$siteUrl = "https://XXXXX.sharepoint.com/sites/XXXXXXXXXXXX"

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials("XXXXX@XXXXX", (ConvertTo-SecureString -String "XXXX" -asplaintext -force))
$ctx.Credentials = $Credentials
```
会社で使うのでProxy越えが必要になります。以下のコードで可能になります。

```
　[System.Net.WebRequest]::GetSystemWebProxy()
　[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
```

ファイル一覧はリストへアクセスし取得します。｢ドキュメント｣は今回の目的のドキュメントライブラリ(/Shared Documents/ 配下)のファイル一覧です。
リストをロードし抽出(この辺あんまりわかってません、すいません)

```
$objList = $ctx.Web.Lists.GetByTitle("ドキュメント")
$ctx.Load($objList)
$ctx.ExecuteQuery()
```
アイテムを絞り込む時はCamlQueryなるものを指定するそうです。｢RecursiveAll｣は如何にも今回の目的に適っているようで、実際に目的果たしてくれました。

```
$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$query.ViewXml="<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='FSObjType'/><Value Type='Integer'>0</Value></Eq></Where></Query></View>"

$objListItems = $objList.getItems($query)
$ctx.Load($objListItems)
$ctx.ExecuteQuery()
```
絞り込み結果に対してforeachを実行し情報を取り出します。ファイルサイズも欲しかったのですが、下記のような書き方で取れました(単位はbyte)。

終わったらDisposeを忘れずに。

```
foreach($item in $objListItems)
{
	$id = $item.Id.ToString()
	$Filename = $item["FileLeafRef"]
	$FilePath = $item["FileRef"]
	$Editor = $item["Editor"].LookupValue
	$Modified = $item["Modified"]
	$Size = $item["File_x0020_Size"]
	Write-Output ($id + "," + $Filename + "," + $Size + "," + $FilePath)
}

$ctx.Dispose()
```

#2.付記として。
Share Pointはファイルのバージョン履歴を持っています。このバージョン履歴を取得する場合は、先のforeach内で以下のようなコードを追加すると取得できます。

```
($itemはforeachのアイテム)
$f = $item.File
$versions = $f.Versions
$ctx.Load($versions) 
$ctx.ExecuteQuery()      
foreach($version in $item.File.Versions)
{
$VersionData = "$($item.id), $($version.VersionLabel), $($version.CreatedBy.User.DisplayName), $($version.Created),$($version['Title'])"
}
```

更に個々のファイルのハッシュ値を取得したい場合は以下を追加。ここではSHA-256で計算していますが、なんでもいけるはず。

```
($itemはforeachのアイテム)
$f = $item.File
$fileStream = $f.OpenBinaryStream()
$ctx.Load($f) 
$ctx.ExecuteQuery()	
[System.IO.Stream]$stream = $fileStream.Value
$sha256 = [System.Security.Cryptography.SHA256Managed]::Create()
$hash = $sha256.ComputeHash($stream)
$stream.Close()
$sha256.Dispose()
$HashString = ""
foreach( $HashByte in $hash ){
    $HashString += $HashByte.ToString("x2")
}
Write-Output $HashString
```

以上。