ささみ学習帳 - sasami's study book

ささみ学習帳

Microsoft365 や Power Platform について学んだこと・アイデアのメモ

Microsoft365関連の未使用ライセンス数が指定値を下回ったらTeamsチャネルに通知するPowerAutomateクラウドフロー💎

 

Microsoft365関連の未使用ライセンス数が指定値を下回ったらTeamsチャネルに通知するPowershellスクリプト」のPowerAutomateクラウドフロー版です。Graph API を使うのであればPowerAutomateでもできるよね?ということで作ってみました。

 

 

このスクリプトで実現できること

Microsoft365関連ライセンスの未使用数が指定した条件を下回ったら、Teamsのチャネルで通知する

 

準備するもの

PowerAutomate 有償ライセンス

PremiumコネクタのHTTPを使用しますのでPowerAutomate有償プランが必要になります。

※実運用には使用できませんが、PowerApps 開発者向けプランで無料で試してみることはできます。

AzureADにアプリ登録

こちらの記事で登録したアプリに少し設定を加えて流用します。

新規に作成する場合はこちらの記事の「AzureADにアプリ登録」1〜8まで実施してください。

sasami-axis.hatenablog.com

 

(追加手順)

1.Microsoft Entra 管理センター にアクセス(管理者アカウントでサインイン)

https://entra.microsoft.com/#view/Microsoft_AAD_IAM/

2.Azure Active Directory→アプリケーション→アプリの登録で該当アプリをクリック

3.概要に表示される [アプリケーション (クライアント) ID] と [ディレクトリ (テナント) ID] の値をコピーしておきます

 

4.証明書とシークレット→クライアントシークレット→新しいクライアントシークレット

 

5.説明を入力し有効期限を選択して「追加」

 

6.値をコピーしておく(他の画面に遷移するとコピーできなくなるので忘れずに)

以上で準備は完了です。

フロー全体図

 

フロー解説

トリガー - 手動でフローをトリガーします

今回は検証目的で作成した為こちらのトリガーを使用しています。実際運用する場合はスケジュール実行になるかと思います。

 

変数を初期化する - messages

Teams チャネルに通知するメッセージを組み立てるための変数を初期化しています。

 

HTTP-GraphAPI-ListSubscribedSkus

このフローの本体はここです。HTTPコネクタのHTTPアクションでsubscribedSkus を一覧表示するGraph APIを実行しています。必要なアクセス許可(Organization.Read.All)の関係で、プレミアムコネクタのHTTPアクションが必要になっています。

GET https://graph.microsoft.com/v1.0/subscribedSkus

learn.microsoft.com

出力はこのようなjsonです。

 

JSONの解析

HTTPアクションの出力を解析しています。

スキーマはこちら

{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "value": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "accountName": {
                        "type": "string"
                    },
                    "accountId": {
                        "type": "string"
                    },
                    "appliesTo": {
                        "type": "string"
                    },
                    "capabilityStatus": {
                        "type": "string"
                    },
                    "consumedUnits": {
                        "type": "integer"
                    },
                    "id": {
                        "type": "string"
                    },
                    "skuId": {
                        "type": "string"
                    },
                    "skuPartNumber": {
                        "type": "string"
                    },
                    "subscriptionIds": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "prepaidUnits": {
                        "type": "object",
                        "properties": {
                            "enabled": {
                                "type": "integer"
                            },
                            "suspended": {
                                "type": "integer"
                            },
                            "warning": {
                                "type": "integer"
                            }
                        }
                    },
                    "servicePlans": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "servicePlanId": {
                                    "type": "string"
                                },
                                "servicePlanName": {
                                    "type": "string"
                                },
                                "provisioningStatus": {
                                    "type": "string"
                                },
                                "appliesTo": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "servicePlanId",
                                "servicePlanName",
                                "provisioningStatus",
                                "appliesTo"
                            ]
                        }
                    }
                },
                "required": [
                    "accountName",
                    "accountId",
                    "appliesTo",
                    "capabilityStatus",
                    "consumedUnits",
                    "id",
                    "skuId",
                    "skuPartNumber",
                    "subscriptionIds",
                    "prepaidUnits",
                    "servicePlans"
                ]
            }
        }
    }
}

 

選択アクション

HTTPアクションの出力をJSON解析し、必要な項目のみを抽出します。デバッグ用に多数の項目をマップしていますが、実際使っているのはremainedUnits,produtNameのみです。

remainedUnitsの式

ライセンス総数から割り当て済みの数を減算してます。

ライセンス総数[prepaindUnits/enabled] + (-1 * 割当て済数[consumedUnits])

add(
item()?['prepaidUnits']?['enabled'],
mul(item()?['consumedUnits'],-1)
)

 

productNameの式

skuPartNumberの名称では分かりづらいのでここに置き換えています。replaceでひたすら置換していますので、もっとスマートな手段に改善したいです。

製品名との対応はこちらのページにありますので、必要なライセンスの分を追加変更してください。

learn.microsoft.com

replace(
    replace(
        replace(
            replace(
                replace(
                    replace(
                        replace(item()?['skuPartNumber'], 'DEVELOPERPACK_E5','Microsoft 365 E5 Developer'),
                        'FLOW_FREE','Microsoft Power Automate Free'),
                    'Win10_VDA_E3','Windows10 Enterprise E3'),
                'EXCHANGESTANDARD','Exchange Online (プラン1)'),
            'POWER_BI_STANDARD','Power BI'),
        'SPE_E3','Microsoft 365 E3'),
        'EXCHANGEARCHIVE_ADDON','Exchange Online Archiving for Exchange Online')

 

アレイのフィルター処理-残数が閾値以下→条件

未割当ライセンス残数(remaindUnits)が閾値を下回っているライセンスのみ抽出し、1件以上該当した場合のみ後続の処理を実行します。


Apply to each (メッセージ本文の組み立て)

未割当ライセンス残数(remaindUnits)が閾値を下回っているライセンスの名称と残数を、通知メッセージに組み立てています。

 

チャットまたはチャネルでメッセージを投稿する

前工程で組み立てたメッセージをTeamsのチャネルに投稿します。

 

実行イメージ

※上はPowerShellスクリプト版の出力です。

 

さいごに

Graph API を使うのであればPowerAutomateでもできるよね?と軽い気持ちで試してみました。Powershell版とどちらが良いかは好みです。

ただ、クラウドフロー版はPowerAutomateの有償プランが必要となってしまうことが個人的にはネックです。

 

参考にしたページ

jpdynamicscrm.github.io