PnP PowerShell で SharePoint Online のドキュメントライブラリ配下にある個別権限を全て解除する。

最初の記事がやらかし案件の後片付けの備忘録です。


#経緯
　
ファイルサーバーから、Share Point Online への移行を行っている際に、ツールの設定を間違って、ドキュメントライブラリの一部の階層から下のフォルダ、ファイルに対して全て固有権限がついてしまうということがありまして、キーボードマクロを小一時間で簡易実行し、5000件くらいは解除できたのですが、読み込みが結構かかる場合で操作ミスが多く発生してしまいました。

改めて、Powershellで実装できないかとCSOMでの操作も確認したものの、操作習得や作法を覚えるのに時間がかかりそう＆習得しても活用するのが大変と感じました。
PnP PowerShellであれば、Powershellのお作法の範囲でいろいろなことが実施できそうだったので試みることにしました。
　

#参考

概要はMicrosftを見ます。

https://docs.microsoft.com/ja-jp/powershell/sharepoint/sharepoint-pnp/sharepoint-pnp-cmdlets?view=sharepoint-ps

PnPは初めて触るので、下のリンクに記載されていることを素直に実施します。

https://www.sharepointdiary.com/2016/02/powershell-to-delete-unique-permissions-for-all-list-items-sharepoint-online.html

見てわかる通り、CSOMでは50行程度＆結構な文字数書き込む必要があったものが、PnPでは23行（コメント無しで10行）で終わっています。


#実行コマンド

まずはPnPのインストールから。管理者権限で実行します。


```Powershell:Install-PnP.ps1
#おまじない
Set-ExecutionPolicy RemoteSigned

#インストール
Install-Module SharePointPnPPowerShellOnline

#おまじない
Update-Module SharePointPnPPowerShellOnline

```
　

続いてサインイン、OrgIDには、 Share Point Online 管理センターの”[OrgID]-admin”と同じものを挿入。

Share Point OnlineのPowershellでは、管理センターに入ることが多いですが、今回のURLは操作したいサイトとなります。
汎用化しにくくなるかもしれませんが、その分操作に必要な行数が減ります。

```Powershell:Logon-PnP.ps1
$Global:AdminUser = "host@domain.com"
$cred = Get-Credential -UserName $AdminUser

$Site_URL = "https://[OrgID].sharepoint.com/demo/"

#ログオン
Import-Module SharePointPnPPowerShellOnline -DisableNameChecking
Connect-PnPOnline -Url $Site_URL -Credentials $cred
```
　

他要素認証の場合はCredential 不要

```Powershell:LogonMFS-PnP.ps1
$Site_URL = "https://[OrgID].sharepoint.com/demo/"
Import-Module SharePointPnPPowerShellOnline -DisableNameChecking
Connect-PnPOnline -Url $Site_URL  -UseWebLogin
```
　

そして、接続時点でトラブル発生（素人丸出し）

Connect-PnPOnlineを打ち込んでもMethod not foundとなってしまいます。
明示的にImportして、Get-Module打っても出てくるし、Get-Help指定してもちゃんと表示される。なのにNot Found。


以下URLの通り、Share Point Online関連のアプリケーション（特にCSOM）が邪魔することがあるらしいので、モジュールを全て削除。
ここ以外にも、ユーザーのドキュメント＞Powershellフォルダ内あるPnP以外のSharePointOnlineモジュールも念の為削除しましたが、それでも実行できず。


https://github.com/SharePoint/PnP-PowerShell/issues/1741
　

3時間ほどもやもやして諦めようとしたときに、以下の文書で.Netのバージョンによるアセンブリの混乱が関係しそうと思い、Powershell Core6から5に戻して実行したところ無事接続できました。
Visual Studioのように使用する.Netバージョンが明示的ではないので、現状の混在する状況はとても面倒ですね。

https://tech.tanaka733.net/entry/misterious-missingmethodexception-due-to-aws-tools-for-powershell-and-sdk-for-dotnet
　

よいよ解除処理を実行します。

```Powershell:Remove-UniquePermisson.ps1

$ListName = "Documents"

#Get all list items in batches
$ListItems = Get-PnPListItem -List $ListName -PageSize 500
 
#Iterate through each list item
ForEach($ListItem in $ListItems)
{
    #Check if the Item has unique permissions
    $HasUniquePermissions = Get-PnPProperty -ClientObject $ListItem -Property "HasUniqueRoleAssignments"
    If($HasUniquePermissions)
    {       
        $Msg = "Deleting Unique Permissions on {0} '{1}' at {2} " -f $ListItem.FileSystemObjectType,$ListItem.FieldValues["FileLeafRef"],$ListItem.FieldValues["FileRef"]
        Write-host $Msg
        #Delete unique permissions on the list item
        Set-PnPListItemPermission -List $ListName -Identity $ListItem.ID -InheritPermissions
    }
}

```

私の環境では、数時間後に問題なく解除できていることを確認しました。
後は切断します。

```Powershell:Disconnect-PnPOnline.ps1

#Disconnect
Disconnect-PnPOnline

```

#総括

PnPは、今までShare Point Onlineのコマンドで実装できなかった処理が、オンプレで触れていた内容まで実施でき、加えてCSOMと比較してかなり分かりやすく実装できることを実感しました。
ベンダーに問い合わせたときに、PnPの利用関連の回答は出てこなかったので、PnPを理解することで Share Point Online の活用のアドバンテージになると思いました。