はじめに
棚卸作業などで、Share Point Online のドキュメントライブラリのディレクトリ構成の棚卸を行いたい!と考えてことはありませんか?
今回はそのようなときに利用できるフローをPower Automate で作成してみました。
なお、標準機能でディレクトリ構成の出力を行いたい場合や、普段利用しているツールと同様の方法でディレクトリ構成の出力を行いたい場合は、もくだいさんのドキュメントライブラリのフォルダ、ファイル一覧を取得したいをご参照ください。
さっそく作成してみる
今回利用する変数
今回利用する変数は以下です。
最初に変数の初期化を行いましょう。


| 名前 | 種類 | 値 |
|---|---|---|
| InitParent | 文字列 | [ディレクトリ構成を作成したい親ディレクトリ] ex ) /Shared Documents/General |
| Parent | 文字列 | @{variables('InitParent')} |
| Index | 整数 | 1 |
| resultDirectory | アレイ | |
| Directory | アレイ | @{body('選択')} ※後述 |
InitParent で設定したディレクトリのフォルダ一覧を取得する
InitParent で設定したディレクトリ以下のフォルダ/ファイルの一覧を取得します。
「フォルダーの一覧」を選択し、対象のサイトを選択後、先ほど作成した「initParent」をファイル識別子に設定します。
その際、【Power Automate】Share Point コネクタのファイル識別子に動的コンテンツを利用するでも説明したように、replace 関数を利用して値を設定しましょう!
ファイル識別子
replace(variables('Parent'), '/', '%2F')
続いて「選択」アクションを選択し、「フォルダーの一覧」で取得した結果で必要なものだけを抜き出しましょう。
今回は以下のように設定しました。
Parent には、変数のParent を用いています。
マップ
{
"Parent": @{variables('Parent')},
"isFolder": @{item()?['IsFolder']},
"DisplayName": @{item()?['DisplayName']},
"Path": @{item()?['Path']},
"isDone": @{false}
}

変数「Directory」の設定
「変数」>「変数の初期化」を選択し、「Directory」というアレイ型の変数を作成します。
値には、先ほど「選択」で出力された結果を選択します。

サブフォルダを含めてフォルダーの一覧を取得する
上記の方法だけでは、サブフォルダーも含めてフォルダーの一覧を取得することはできませんでした。
ここでは上記で取得したフォルダー一覧をもとにサブフォルダーも含めてフォルダーの一覧を取得していこうと思います。
サブフォルダーまで探索するためのループ条件ですが、今回は
「Directory 変数に格納された値の長さ(数) と ループ処理を行った回数」
で比較を行いたいと思います。

Do until のループ条件
@greaterOrEquals(length(variables('Directory')), variables('Index'))
今回ループ処理回数のカウントに「Index」という変数を用いていますが、iterationIndexes という関数を利用してもいいかもですね。
JSON 解析を用いて値を参照しやすくする
続いて、「JSON の解析」を用いて「Directory」に格納されている値を順に参照していきます。
以下のように設定します。
コンテンツ
last(take(variables('Directory'), variables('Index')))
{
"type": "object",
"properties": {
"Parent": {
"type": "string"
},
"isFolder": {
"type": "boolean"
},
"DisplayName": {
"type": "string"
},
"Path": {
"type": "string"
},
"isDone": {
"type": "boolean"
}
}
}
これにより、Index 番目の配列が参照されますね。
フォルダー一覧を取得する
続いて、「条件」コントロールを追加します。
この条件には、現在の対象となっているディレクトリが、ファイルか?フォルダーか?を判断するようにします。
もしフォルダーであれば、対象フォルダー以下のフォルダー一覧を取得し、「Directory」変数に値を追加します。
ファイルであれば、特になにも処理を行いません。
これにより、フォルダーが存在している場合「Directory」の値が増えるためループ回数が増えますね。
条件には以下のように設定します。
@body('JSON_の解析')?['isFolder'] 次の値に等しい @true
フォルダーであった場合には、フォルダー一覧を取得し、「Directory」に追加したいので以下のように設定します。
- フォルダー一覧
サイトのアドレス
任意のアドレス
ファイル識別子
@replace(body('JSON_の解析')?['Path'], '/', '%2F')
- 変数の設定
変数
Parent
値
@{body('JSON_の解析')?['Parent']}
- 選択
開始
@{body('フォルダーの一覧_2')}
マップ
{
"Parent": @{variables('Parent')},
"DisplayName": @{item()?['DisplayName']},
"isFolder": @{item()?['IsFolder']},
"Path": @{item()?['Path']},
"isDone": @{body('JSON_の解析')?['isDone']}
}
- Apply to each
@{body('選択_2')}
- 配列変数に追加
変数
Directory
値
@{items('Apply_to_each_2')}

ここで、「Directory」に値を追加する際、Apply to each の処理が必要になってきます。
Apply to each なしで「選択」で出力された値を配列変数に追加しようとすると、エラーになるかと思います。
追加を行う際は、「選択」で取得した結果を1つずつ配列変数に追加する必要があるのでこのようになっています。
インデックの増加
ループ処理の最後に、「Index」の値を1増やす処理を追加しましょう!
これにより、対象ディレクトリのサブフォルダを含めたディレクトリー構成を取得することができます。

取得したディレクトリ構成に属性を追加する
これまでの処理で取得された結果は、
- フォルダー名
- パス
- 親フォルダー
- フォルダーかファイルか
のみでした。
これらに加え更に
- サイズ
- 最終更新日
まで取得できるようにしたいと思います。
以下のような構成のフローを作成します。

メタデータを取得する
Apply to each処理には以下を設定します。
@{variables('Directory')}
メタデータの取得ですが、これはファイルとフォルダーでそれぞれアクションが異なってきます。
なので「条件」を追加し、以前同様フォルダーか?ファイルか?を判定する条件を追加します。
設定するパラメータはほぼ同じなので、今回はフォルダーのメタデータの取得について解説します。
- フォルダー メタデータの取得
サイトのアドレス
任意のアドレス
ファイル識別子
@replace(items('Apply_to_each')?['Path'], '/', '%2F')
- 作成
{
"isDone": @{items('Apply_to_each')?['isDone']},
"Parent": @{items('Apply_to_each')?['Parent']},
"isFolder": @{items('Apply_to_each')?['isFolder']},
"DisplayName": @{items('Apply_to_each')?['DisplayName']},
"Path": @{items('Apply_to_each')?['Path']},
"Size": @{body('フォルダー_メタデータの取得')?['Size']},
"LastModified": @{body('フォルダー_メタデータの取得')?['LastModified']}
}
- 配列変数に追加
名前
resultDirectory
値
@{outputs('作成_2')}
これで、メタデータの取得で得られた結果を踏まえた配列を取得することができるようになりました!
他の情報も取得したい場合は同様の方法で取得を行ってみてください。
ディレクトリ構成を見やすいかたちで出力する(作成まだ)
こちらは作成完了できたら追記します。
どなたかよい案があればください!!
おわりに
今回紹介したやり方を応用すれば、対象ディレクトリ配下のサブフォルダー含むすべてのファイルに対して、特定の処理を行う。
ということもできるようになります。
興味のある方はそちらも試してみるとよいですね。
