SharePoint で選択肢列と参照列を PowerShell で付け替える(2/3)

[ブログからの転載](http://1bed.allright.life/?p=2607)

前回の続きです
下記手順の 2 番目、参照列の作成を行います。

1. 選択肢列の値を使い、参照列元のリストを作成する
2. 手順 1 で作成したリストを使い、参照列を作成する
3. 選択肢列の値を参照列に移行
4. 選択肢列の削除


## 環境

このリストは最初に作っていた

* リスト名: 選択肢列と参照列を付け替える

| 列名 | 内部列名 | 種類 | 値 |
| --- | --- | --- | --- |
| 目的地 | Title | 1 行テキスト | |
| 乗り物 | vehicle | 選択肢 | 車 , バイク , 自転車 , 船 , 飛行機 |
| おやつ | snack | 選択肢(複数選択可能) | ポテトチップス , アポロ , じゃがりこ , チップスター , ハイレモン , かっぱえびせん | 

このリストを前回作った

* 選択肢列から作成される参照元リスト(マスタリスト)

| 列名 | 生成されるリスト名 | リストのタイトル |
| --- | --- | --- |
| 乗り物 | 乗り物マスタ | vehicleMst |
| おやつ | おやつマスタ | snackMst |

今回はこの列を作成する

* リスト「選択肢列と参照列を付け替える」に追加される参照列名

| 列名 | 内部列名 | 参照リスト名 |
| --- | --- | --- |
| 乗り物 | relVehicle | 乗り物マスタ |
| おやつ | relSnack | おやつマスタ |

## 1. 選択肢列の値を使い、参照列元のリストを作成する

* [https://qiita.com/miyamiya/items/4370e0c4f5e2f98bf51d](SharePoint で選択肢列と参照列を PowerShell で付け替える(1/3)) 

## 2. 「選択肢列と参照列を付け替える」に参照列を作成

```ps1
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")

# SharePoint Online の URL
$url = 'https://<tenant>.sharepoint.com/sites/example'
# ユーザー名
$user = 'miyamiya@example.com';
# パスワード
$secure = Read-Host -Prompt "Enter the password for ${user}(Office365)" -AsSecureString;
# SharePoint Online 認証情報
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $secure);
# SharePoint Client Context インスタンスを生成
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$ctx.Credentials = $credentials


## ここまではいつものおまじない的なコード。
## ログインして SharePoint Client Context のインスタンスを作成しています。


## 必要な変数定義

# 選択肢列を参照列に置き換えるリストのリスト名
$baseListName = "選択肢列と参照列を付け替える"

# 参照列化する列名
$baseFieldName = "乗り物"
#$baseFieldName = "おやつ"

# 作成する参照列の内部列名
$makeFieldInternalName = "relVehicle"
#$makeFieldInternalName = "relSnack"

# 作成する参照列の列名
$makeFieldDisplayName = "乗り物"
#$makeFieldDisplayName = "おやつ"

# マスタリストの名前
$mstListName = "乗り物マスタ"
#$mstListName = "おやつマスタ"


## サーバーから値の取得

# 列を追加するリスト
$baseList = $ctx.Web.Lists.GetByTitle($baseListName)
# 参照列化する列
$baseField = $baseList.Fields.GetByInternalNameOrTitle($baseFieldName)
# マスタリスト
$mstList = $ctx.Web.Lists.GetByTitle($mstListName)

# 値のロード予約
$ctx.Load($baseList)
$ctx.Load($baseField)
$ctx.Load($mstList)
$ctx.ExecuteQuery()


## 参照列の定義生成

# 参照列の XML フォーマット
$fieldXmlFormat = @"
    <Field Type='{0}' DisplayName='{1}' StaticName='{2}' Name='{2}'
        List='{3}'
        Mult='{4}'
        Required='FALSE' EnforceUniqueValues='FALSE'
        ShowField='Title' UnlimitedLengthInDocumentLibrary='FALSE' 
        RelationshipDeleteBehavior='None'
    />
"@

switch ($baseField.TypeAsString.ToUpper()) {
    'CHOICE' {
        $fieldXml = ($fieldXmlFormat -f 'Lookup', $makeFieldDisplayName, $makeFieldInternalName, $mstList.Id, 'FALSE')
    }
    'MULTICHOICE' {
        $fieldXml = ($fieldXmlFormat -f 'LookupMulti', $makeFieldDisplayName, $makeFieldInternalName, $mstList.Id, 'TRUE')
    }
    default {
        # 参照列化する予定のフィールドが選択肢列でない時は処理を停止
        Write-Host ("{0} is not 'Choice' or 'MultiChoice'" -f $baseFieldName)
        exit
    }
}

# 参照列の追加
$result = $baseList.Fields.AddFieldAsXml($fieldXml, $true, ([Microsoft.SharePoint.Client.AddFieldOptions]::AddFieldToDefaultView -bor [Microsoft.SharePoint.Client.AddFieldOptions]::AddFieldInternalNameHint))
$result.Title = $makeFieldDisplayName
$result.Update()
$ctx.ExecuteQuery()

# コンテキスト の破棄
$ctx.Dispose()
```

手順的には、この辺りを注意して参照列を作った

1. 列定義 XML を作成
   既存の選択肢列を取得し、複数選択が許可されていたら Type を LookupMulti にして、 Mult を TRUE にする


2. 参照列の追加
   内部列名を強制するように、オプションとして AddFieldInternalNameHint を付ける


これを、「乗り物」と「おやつ」に実行したので、つぎはデーターの移行だなー