Power Automate で稟議書を実装してみた2 (CUI で環境準備編)

## 経緯

[前回](https://qiita.com/miyamiya/items/2f8290fa4541cc3eb953) は、GUI を使って SharePoint 作ったサイトとリストの説明を行いましたが、今回はそれを CUI で作成します

## PnP PowerShell のインストール

PowerShell は 5.1 を利用しています

まずは、管理者として PowerShell を開き、次のコマンドを実行します

```powershell
Install-Module SharePointPnPPowerShellOnline
```

[![](https://1bed.allright.life/wp-content/uploads/2020/04/blog2-1-300x146.png)](https://1bed.allright.life/wp-content/uploads/2020/04/blog2-1.png)

## サイト、リストの作成

```powershell
# Credential の生成
$cred = Get-Credential

# SharePoint Online の URL
$spoUrl = 'https://<your-organization-name>.sharepoint.com'

# 作成するサイトの URL
$siteUrl = ('{0}/sites/{1}' -f $spoUrl, 'ExampleWorkflow')

# SharePoint Online に接続
$spoCon = Connect-PnPOnline -Url $spoUrl -Credential $cred

# サイトの生成 (コミュニケーションサイト、デザインがトピック、ロケールを日本語)
New-PnPSite -Title ExampleWorkFlow -Url $siteUrl -type CommunicationSite -SiteDesign Topic -Lcid 1041 -Wait:$false -Connection $spoCon

# SharePoint Online からの切断 (複数の接続を使っている時は -Connection $spoCon を必ずつける)
Disconnect-PnPOnline -Connection $spoCon


### サイトの設定を変更

# 作成したサイトに接続 ※サイトの作成が終わるまで、少し待たないといけない
$siteCon = Connect-PnPOnline -Url $siteUrl -Credential $cred

# Web オブジェクトを取得
$web = Get-PnPWeb -Includes RegionalSettings.TimeZones -Connection $siteCon

# 日本のタイムゾーンを取得
$timezone = $web.RegionalSettings.TimeZones | Where-Object Description -Match "(東京|Tokyo)"

# タイムゾーンを日本に変更
$web.RegionalSettings.TimeZone = $timezone
$web.Update()

# サーバーに設定を反映
$ctx = Get-PnPContext
$ctx.ExecuteQuery()
$ctx.Dispose()

### グループマスタリストの作成

# 作成するリストの内部名
$internalListName = 'Lists/GroupMaster'

# リストの作成 (カスタムリストとして作成)
New-PnPList -Template GenericList -Url $internalListName -Title 'グループマスタ' -Connection $siteCon > $null

# Title の表示列名を変更
Set-PnPField -List $internalListName -Identity 'Title' -Values @{'Title' = 'グループ名';} -Connection $siteCon

# Add-PnPFieldFromXml で使うので ListId を取得 (後でも使います)
$groupListId = (Get-PnPList $internalListName -Connection $siteCon).Id

# ユーザーまたはグループ列のテンプレート (ユーザーのみ、複数選択)
$fieldxmlTemplate = '<Field Type="UserMulti" DisplayName="{0}" List="UserInfo" Required="FALSE" EnforceUniqueValues="FALSE" ShowField="ImnName" UserSelectionMode="PeopleOnly" UserSelectionScope="0" Mult="TRUE" Sortable="FALSE" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}" />'

# 承認者列の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f '承認者', (New-Guid).Guid, $groupListId.Guid, 'ApprovalUsers') -Connection $siteCon > $null

# 確認者列の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f '確認者', (New-Guid).Guid, $groupListId.Guid, 'ConfirmUsers') -Connection $siteCon > $null

# すべてのアイテムビューに追加した列を表示
Set-PnPView -List $internalListName -Identity 'すべてのアイテム' -Fields 'LinkTitle','ApprovalUsers','ConfirmUsers' -Connection $siteCon


### 承認経路マスタリストの作成

# 作成するリストの内部名
$internalListName = 'Lists/ApprovalPathMaster'

# リストの作成 (カスタムリストとして作成)
New-PnPList -Template GenericList -Url $internalListName -Title '承認経路マスタ' -Connection $siteCon > $null

# Title の表示列名を変更
Set-PnPField -List $internalListName -Identity 'Title' -Values @{'Title' = '承認経路名';} -Connection $siteCon

# Add-PnPFieldFromXml で使うので ListId を取得 (後でも使います)
$approvalPathListId = (Get-PnPList -Identity $internalListName -Connection $siteCon).Id

# 参照列のテンプレート
$fieldxmlTemplate = '<Field Type="Lookup" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" List="{1}" ShowField="Title" UnlimitedLengthInDocumentLibrary="FALSE" RelationshipDeleteBehavior="None" ID="{2}" SourceID="{3}" StaticName="{4}" Name="{4}" />'

# 経路列の作成
1..5 | ForEach-Object{ Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f "経路$($_)", $groupListId.Guid, (New-Guid).Guid, $approvalPathListId.Guid, "Path$($_)") -Connection $siteCon } > $null

# 数値列のテンプレート
$fieldxmlTemplate = '<Field Type="Number" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="TRUE" IMEMode="inactive" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}" />'

# 必要承認数列の作成
1..5 | ForEach-Object{ Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f "経路$($_)の必要承認数", (New-Guid).Guid, $approvalPathListId.Guid, "Path$($_)Approvals") -Connection $siteCon } > $null

# すべてのアイテムビューに追加した列を表示
Set-PnPView -List $internalListName -Identity 'すべてのアイテム' -Fields 'LinkTitle','Path1','Path1Approvals','Path2','Path2Approvals','Path3','Path3Approvals','Path4','Path4Approvals','Path5','Path5Approvals' -Connection $siteCon


### 申請ワークフローリストの作成

# 作成するリストの内部名
$internalListName = 'Lists/Apply'

# リストの作成 (カスタムリストとして作成)
New-PnPList -Template GenericList -Url $internalListName -Title '申請ワークフロー' -Connection $siteCon > $null

# Title の表示列名を変更
Set-PnPField -List $internalListName -Identity 'Title' -Values @{'Title' = '申請タイトル';} -Connection $siteCon

# Add-PnPFieldFromXml で使うので ListId を取得 (後でも使います)
$applyListId = (Get-PnPList -Identity $internalListName -Connection $siteCon).Id

# 1行テキストのテンプレート
$fieldxmlTemplate = '<Field Type="Text" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="TRUE" MaxLength="255" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}" CustomFormatter="" IMEMode=""><Default></Default></Field>'

# ステータス列の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f 'ステータス', (New-Guid).Guid, $applyListId.Guid, "Status") -Connection $siteCon > $null

# 参照列のテンプレート
$fieldxmlTemplate = '<Field Type="Lookup" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" List="{1}" ShowField="Title" UnlimitedLengthInDocumentLibrary="FALSE" RelationshipDeleteBehavior="None" ID="{2}" SourceID="{3}" StaticName="{4}" Name="{4}" />'

# 承認経路列の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f '承認経路', $approvalPathListId.Guid, (New-Guid).Guid, $applyListId.Guid, "ApprovalPath") -Connection $siteCon > $null

# 複数行テキスト列(拡張リッチテキスト)のテンプレート
$fieldxmlTemplate = '<Field Type="Note" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" NumLines="6" RichText="TRUE" RichTextMode="FullHtml" IsolateStyles="TRUE" Sortable="FALSE" IMEMode="inactive" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}" RestrictedMode="TRUE" AppendOnly="FALSE" />'

# 申請文の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f '申請文', (New-Guid).Guid, $applyListId.Guid, "Body") -Connection $siteCon > $null

# 数値列のテンプレート (初期値 0 を入れる)
$fieldxmlTemplate = '<Field Type="Number" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="TRUE" IMEMode="inactive" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}"><Default>0</Default></Field>'

# 経路の承認数列の作成
1..5 | ForEach-Object{ Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f "経路$($_)承認数", (New-Guid).Guid, $applyListId.Guid, "Path$($_)Accept") -Connection $siteCon } > $null

# 経路の否認数列の作成
1..5 | ForEach-Object{ Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f "経路$($_)否認数", (New-Guid).Guid, $applyListId.Guid, "Path$($_)Reject") -Connection $siteCon } > $null

# 複数行テキスト列(書式なし)のテンプレート
$fieldxmlTemplate = '<Field Type="Note" DisplayName="{0}" Required="FALSE" EnforceUniqueValues="FALSE" Indexed="FALSE" NumLines="6" RichText="FALSE" Sortable="FALSE" IMEMode="inactive" ID="{1}" SourceID="{2}" StaticName="{3}" Name="{3}" />'

# 経路のコメント列の作成
1..5 | ForEach-Object{ Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f "経路$($_)コメント", (New-Guid).Guid, $applyListId.Guid, "Path$($_)Comment") -Connection $siteCon } > $null

# ログ列の作成
Add-PnPFieldFromXml -List $internalListName -FieldXml ($fieldxmlTemplate -f 'ログ', (New-Guid).Guid, $applyListId.Guid, "Log") -Connection $siteCon > $null

# すべてのアイテムビューに追加した列を表示
Set-PnPView -List $internalListName -Identity 'すべてのアイテム' -Fields 'LinkTitle','ApprovalPath','Status' -Connection $siteCon

# サイトからの切断 (複数の接続を使っている時は -Connection $siteCon を必ずつける)
Disconnect-PnPOnline -Connection $siteCon
```

## 考察

細かくコメントを入れることで、個人的には復習もできました
次は Power Automate で作ったフローの説明をしていきます

## 関連記事

自分のためのメモに近い記事なのですが、長いのでインデックスつけます

* [Power Automate で稟議書を実装してみた1 (GUI で環境準備編)](https://qiita.com/miyamiya/items/2f8290fa4541cc3eb953)
* Power Automate で稟議書を実装してみた2 (CUI で環境準備編)
* [Power Automate で稟議書を実装してみた3 (Power Automate 編1)](https://qiita.com/miyamiya/items/35ca2d1cd05bc77396ce)
* [Power Automate で稟議書を実装してみた4 (Power Automate 編2)](https://qiita.com/miyamiya/items/1ef9cab407499a64477e)
* [Power Automate で稟議書を実装してみた5 (Power Automate 編3)](https://qiita.com/miyamiya/items/3b60c57653e20a7a6ff0)
* [Power Automate で稟議書を実装してみた6 (Power Automate 編4)](https://qiita.com/miyamiya/items/5f5a81b16901ed9e61cc)