ルドルフもわたるふもいろいろあってな

Microsoft 365、Power Platform、PowerShellについて調べたことや検証したことなどを投稿します。技術の話は面白い。

【解説編】Power Automate を使ってテナント内のチーム一覧をCSVに保存する

掲題のフローの解説編です。

フローをGitHubで公開しました。下記リンク先からダウンロードしてください。
github.com

解説するフロー図

アクションの設定を閉じた状態のフロー図


開いた状態のフロー図


ステップごとの説明

1.「手動でフローをトリガーします」トリガー

このフローは任意のタイミングで実行するために手動実行のトリガーを使用しています。

2.「変数を初期化する-Microsoft365グループ」アクション

このアクションは「変数」>「変数を初期化する」アクションです。

このフローではテナント内のMicrosoft365グループを取得する方法としてHTTP要求のアクションを使用しています。このアクションは1回の要求で取得できるデータ数に制限があります。そのため、テナント内のチームの数が多い場合は、複数回に分けてデータの取得を行います。

HTTP要求を実行するたびにデータの取得結果をMicrosoft365グループの配列にマージするため、この配列を格納するための変数を宣言します。

3.「変数を初期化する-リクエスト先URI」アクション

このアクションは「変数」>「変数を初期化する」アクションです。

前述の通り、複数回に分けてデータの取得を行う場合はHTTP要求を実行するたびにリクエスト先が変わります。そのため、このURIを変数にします。

4.「Do until-テナント内のグループをすべて取得」アクション

このアクションは「コントロール」>「Do Until」アクションです。条件式の判定がtrue である限り処理が繰り返し実行されます。

「Do until」アクションを使って、HTTP要求を使って複数回にわたって実行し目的のデータを取得します。
この方法については、下記記事で解説しています。そちらの記事を参照してください。
wataruf.hatenablog.com

今回はポイントを2点だけ解説します。

ポイント1:HTTP要求のから返された配列をunion関数でマージする

このフローではHTTP要求を実行するたびに、APIから返されたデータを変数「Microsoft365グループ」に追記で格納しています。

この追記を行う方法は、「apply to each」と「配列変数への追加」アクションの組み合わせでも行うことができます。ですが、「apply to each」を使う方法よりunion関数を使うほうがマージのスピードが圧倒的に速いです。そのため、union関数を使う方法を採用しています。

また、一見ひとつのアクションにまとめられそうな「作成」アクションと「変数を設定」アクションを別々のアクションに分けているのも理由があります。

  • 「データ操作」>「作成」アクション
    • union関数を使ってAPIから返されたデータを変数「Microsoft365グループ」の配列にマージ
  • 「変数」>「変数を設定」アクション
    • マージしたデータを変数「Microsoft365グループ」に格納

それはこの2つのデータ操作をひとつのアクションにまとめると、アクションの入力と出力の両方に変数「Microsoft365グループ」が含まれてしますためです。Power Automate ではこのような自己参照が含まれるアクションを設定することができません。

この2つのアクションを以下のようにひとつにまとめてフローを保存しようとすると、、

このように自己参照のエラーメッセージが表示されてしまいます。この状態でフローを保存することはできません。

フローの保存がコード 'WorkflowRunActionInputsInvalidProperty' およびメッセージ '種類 'SetVariable' のワークフロー実行アクション '変数の設定-Microsoft365グループ' の入力が無効です。変数 'Microsoft365グループ' の値を更新するときに自己参照はサポートされていません。' で失敗しました。

「変数の設定」アクションで変数の値を更新する前に、「データ操作」>「作成」アクションを挟むことによって自己参照を避けることができます。
 ※ 繰り返し処理を行う場面でこの手法が活きることは多いと思います。

ポイント2:Graph API でグループの一覧を取得する際にURIを修正する

このフローではフローの実行ユーザーが所属しているチーム以外のチームも含めて取得するために、取得対象をチームではなくMicrosoft365グループにしています。つまり、HTTP要求アクションのリクエスト対象はグループのAPIです。

このAPIが返す NextLink のURIに対してそのままHTTP要求を送るとエラーになります。調べたところ、URIに「/(スラッシュ)」が1文字足りないようです。そのため、replace関数を使ってURIを修正しています。

5.「アレイのフィルター処理-チームに紐づくグループのみを取得」アクション

このアクションは「データ操作」>「アレイのフィルター処理」です。APIから取得したグループの一覧から、チームに紐づくグループのみをフィルタして取得します。

Microsoft365グループには「resourceProvisioningOptions」というプロパティがあります。チームに紐づくグループにはこのプロパティに"Team"という値が含まれています。そのため、このプロパティの値を使ってフィルタを行います。

"inputs": {
"from": "@variables('Microsoft365グループ')",
"where": "@equals(empty(item()?['resourceProvisioningOptions']), false)"
},

6.「選択」アクション

このアクションは「データ操作」>「選択」アクションです。このアクションを使って、チームの情報を表す配列から目的のプロパティのみを取得します。

"inputs": {
"from": "@body('アレイのフィルター処理-チームに紐づくグループのみを取得')",
"select": {
"displayName": "@item()?['displayName']",
"mail": "@item()?['mail']",
"visibility": "@item()?['visibility']",
"createdDateTime": "@convertTimeZone(item()?['createdDateTime'], 'UTC', 'Tokyo Standard Time', 'yyyy/MM/dd HH:mm:ss')",
"Id": "@item()?['Id']"
}
},

7.「CSVテーブルの作成」から「OneDriveへのCSV保存」スコープまで

欲しいデータを"6.「アレイのフィルター処理-チームに紐づくグループのみを取得」アクション" までのステップで取得しました。最後はそのデータをCSVにしてOneDriveに保存します。

このアクションは下記の記事で詳しい詳しい解説を記載しています。今回実施していることは同じです。そのため解説は割愛します。
wataruf.hatenablog.com

最後に

早速このフローの実行をためしてくださった、おいしみさんから下記の情報を頂きました。取得対象のグループが多いとこのフローではタイムアウトになってしまい取得に失敗してしまします。フローを分割するなどしてなんとか回避する方法はありますが、スマートな対応方法が分かっていないです。

こちらについて何かご存じのノウハウや情報がありましたら、ツイッターの上記返信ツリーもしくはましゅまろで情報いただけると助かります。

ましゅまろ
https://marshmallow-qa.com/wataruf01?utm_medium=url_text&utm_source=promotion

もし自分で何かよい方法を見つけたらまたブログで展開します。

今回は以上です。