【PowerShell】SharePoint クライアント オブジェクト モデル (CSOM) を使用した SharePoint Online の操作

PowerShell で SharePoint クライアント オブジェクト モデル (以下、CSOM) を使用して、SharePoint でデータを取得、更新、および管理します。

# 準備

## Module のインストール

[PowerShell Gallery](https://www.powershellgallery.com/) からModule をインストールします。

### [Microsoft.Online.SharePoint.PowerShell](https://www.powershellgallery.com/packages/Microsoft.Online.SharePoint.PowerShell)

```powershell
# SharePoint Online Management Shell のインストール、更新
if((Get-Module Microsoft.Online.SharePoint.PowerShell -ListAvailable | measure).Count -eq 0) {
    Install-Module Microsoft.Online.SharePoint.PowerShell -Force
} else {
    Update-Module Microsoft.Online.SharePoint.PowerShell
}

# インストールされているモジュールの確認
Get-Module Microsoft.Online.SharePoint.PowerShell -ListAvailable | select Name, Version
```

### [SharePointOnline.CSOM](https://www.powershellgallery.com/packages/SharePointOnline.CSOM)

```powershell
# SharePointOnline.CSOM のインストール、更新
if((Get-Module SharePointOnline.CSOM -ListAvailable | measure).Count -eq 0) {
    Install-Module SharePointOnline.CSOM -Force
} else {
    Update-Module SharePointOnline.CSOM
}

# 使用できるコマンドの一覧
Get-Command -Module SharePointOnline.CSOM | select Name, Version
```

### トラブルシューティング

#### インストールしたのにコマンドが実行できない場合

インポートしてみて、コマンドが表示されるか確認してください。

```powershell
# インポート
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking

# 使用できるコマンドの一覧
Get-Command -Module Microsoft.Online.SharePoint.PowerShell | select Name, Version
```

#### Install-Module コマンドで「NuGet プロバイダーが必要...」となる場合

セキュリティ上の脆弱性の観点(2020/04 時点)から PowerShell Gallery のセキュリティプロトコルの既定値が **TLS1.2** となり、 それ以前のサポートは廃止されました。

SecurityProtocol プロパティに **TLS1.2** を追加してインストールコマンドを再度実行します。

```powershell
# TLS1.2 通信を許可する
if (([Net.ServicePointManager]::SecurityProtocol -and [Net.SecurityProtocolType]::Tls12) -ne [Net.SecurityProtocolType]::Tls12) {
    [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
}

# NuGet インストール
Install-PackageProvider NuGet -MinimumVersion 2.8.5.201 -Force
```

# 操作

## SharePoint Web サイトの操作

### 接続用のコンテキストを生成する

```powershell
# CSOM ライブラリを読み込む
Load-SPOnlineCSOMAssemblies

# テナント名
$Tenant = 'mako0001mockup'
# サイト名
$SiteName = 'testSiteCol0001'

# クライアントコンテキスト生成
$webFullUrl = "https://${Tenant}.sharepoint.com/sites/$SiteName"
$context = New-Object Microsoft.SharePoint.Client.ClientContext($webFullUrl)

[string] $UserName = 'admin@mako0001mockup.onmicrosoft.com'
[string] $Password = 'Mock0001'

# 資格情報設定
$secureString = ConvertTo-SecureString $Password –AsPlainText -Force
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $secureString)
```

以降の処理で `$context` 変数を使用します。

### Web サイトのプロパティを取得する

```powershell
# Web サイトのプロパティを取得する
$web = $context.Web
$context.Load($web)
$context.ExecuteQuery()

$web.Title
```

### Web サイトのプロパティに書き込む

```powershell
# Web サイトのプロパティに書き込む
$web = $context.Web
$web.Title = 'New Title'
$web.Description = 'New Description'
$web.Update()
$context.ExecuteQuery()
```

## SharePoint リストの操作

### すべての SharePoint リストを取得する

```powershell
# すべての SharePoint リストを取得する
$lists = $context.Web.Lists
$context.Load($lists)
$context.ExecuteQuery()

$lists | select Id, Title
```

### SharePoint リストを作成および更新する

```powershell
# SharePoint リストを作成および更新する
$lists = $context.Web.Lists
$creationInfo = New-Object Microsoft.SharePoint.Client.ListCreationInformation
$creationInfo.Title = 'My List'
$creationInfo.TemplateType = [Microsoft.SharePoint.Client.ListTemplateType]::Announcements
$list = $lists.Add($creationInfo)
$list.Description = 'New Description'

$list.Update()
$context.ExecuteQuery()
```

### SharePoint リストを削除する

```powershell
# SharePoint リストを削除する
$list = $context.Web.Lists.GetByTitle('My List')
$list.DeleteObject()
$context.ExecuteQuery()
```

### SharePoint リストからアイテムを取得する

```powershell
# SharePoint リストからアイテムを取得する
$list = $context.Web.Lists.GetByTitle('Announcements')
$query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(100)
$items = $list.GetItems($query)
$context.Load($items)
$context.ExecuteQuery()

$items | % {
    '{0} : {1}' -f $_['Title'], $_['Body']
}
```

### 新しいリスト アイテムを作成する

```powershell
# 新しいリスト アイテムを作成する
$list = $context.Web.Lists.GetByTitle('Announcements')
$itemCreateInfo = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
$listItem = $list.AddItem($itemCreateInfo)
$listItem['Title'] = 'My New Item!'
$listItem['Body'] = 'Hello World!'
$listItem.Update()
$context.Load($listItem)
$context.ExecuteQuery()
```

# 参考サイト

- [SharePoint のクライアント ライブラリ コードを使用して基本的な操作を完了する](https://docs.microsoft.com/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-client-library-code)
- [【SPO】CSOM と SharePoint Online 管理シェルを PowerShell でパッケージ管理](https://www.samurainote.com/entry/2019/02/23/222546)
- [PowerShell + CSOM で SharePoint Online を操作する](https://idea.tostring.jp/?p=914)
- [SharePointOnlineの.NETクライアントAPIリファレンス](https://docs.microsoft.com/previous-versions/office/sharepoint-csom/jj193041(v=office.15)#csom-namespaces-in-this-library)
- [PowerShell接続時「NuGet プロバイダーが必要」エラーが発生する（TLS1.2必須の影響）][tls1_2]
- [SharePointOnlineを管理するためのPowerShellモジュール](https://docs.microsoft.com/archive/blogs/dawiese/powershell-modules-for-managing-sharepoint-online)

[tls1_2]: <https://cloudsteady.jp/post/30310/>