まえがき
ライセンス管理は大事だね
Microsoft 365を導入している企業では、E3やE5といったエンタープライズ契約を使っていることが多いと思います。一般的には年間契約で例えばMicrosoft 365 E3ライセンスを1000本、E5ライセンスを300本 というように契約をして、その中でユーザーに割り当てます。
イメージとしては在庫を購入しておいて、ライセンス割当済みのユーザーが増えてきてライセンスが少なくなったら買い増すというような動きになります。逆にライセンスをユーザーから外すと在庫が増えるので、他のユーザーに回すこともできます。
下の図は私のテストテナントのライセンス状況です。E5ライセンスが25本購入されており、そのうち21本はユーザーに割当済み。在庫残は4ということがわかります。
ライセンス管理はすなわちコスト管理でもある
在庫に余裕を持てばもちろん安心なのですが、当然Microsoftへの支払いは多くなります。
かと言って利用できるライセンス数が極端に少なければ、急に割当が必要になっても対応ができません。ライセンスの追加購入には発注してからリードタイムがかかります。傾向の把握が必要なのです。
現在のライセンス数や在庫はさきほどのスクリーンショットのように Microsoft365管理センター > 課金 >ライセンス の項目を見ればわかるのですが、確認できるのはあくまで現時点の値です。
とくに、従業員が1000人を超えるような企業の場合は利用しているライセンスも多岐にわたり、変化がわからないと急にあるライセンスがたくさん割り当てられていても気がつけません。
この記事ではExcelファイルへその時点のライセンス情報を取得日付きで記録します。
上のような管理用テーブルに、定期的にこの値を記録すれば時間経過を横軸にした変化がわかります。割り当てられているライセンス数の変化がわかれば、発注の精度も上がります。ひいてはコスト削減に繋げられます。
この記事でできること
この記事では、できるだけ簡単に以下を実現するための解説を試みてみます。
- Power Automate クラウドフローによるライセンス情報の取得
- SharePoint上に配置したExcelファイルへの情報記録
- Power BIを用いたライセンスの在庫、利用状況の変化をグラフ化
必要なもの
- Power Automate Premium ライセンス(HTTPアクション利用のため)
- アプリ登録(システム部署への依頼)
法人向けにはBusiness Standard,Premium,Basic というのもありますが、私自身こちらのライセンス管理方法がわからず。おそらく同じようにライセンス状況を確認できるのではないかと思いますので試してみてください。
完成イメージはこちらになります。
実装
Entra ID アプリ登録
ライセンスの情報をPower Automateで取得するためには、まずEntra IDでのアプリ登録が必要です。ライセンス情報のようなものは、誰でも簡単に取得できてしまってはよろしくありません。そもそも権限がありません。
アプリ登録とは、特定の権限を持つアプリ(仕組み)用のIDとパスワード(シークレット)を発行する作業と考えればイメージしやすいでしょう。
このアプリ登録で作成されたアプリ用のIDのことを「サービスプリンシパル」と呼ぶことが多いです。
アプリに与える権限
ライセンス情報を取得するのに必要な権限は以下です。
LicenseAssignment.Read.All
→ テナント全体のディレクトリ情報を読み取る権限(ライセンス在庫・割当の読み取り)。

具体的な操作方法は、以前にこちらの記事で紹介しているので参考にしてください。
上記の記事ではUser.ReadWrite.All、Directory.ReadWrite.All の権限を与えていますが、この記事ではライセンス情報を入手するだけなので、LicenseAssignment.Read.All だけで構いません。Writeが含まれている権限は何かを書き換えることができるものですので、そういう処理を含まないのであれば避け、必要最小限の権限を与えましょう。
アプリ登録(サービスプリンシパルの作成)は、会社によって作成できる人やルールが異なります。今回のライセンス管理に関する記事を利用する方は管理者なのかとは思いますが、くれぐれも独断で進めず社内のルールを確認してから進めてください。また、シークレットの管理は慎重に。
控えておく情報
サービスプリンシパルを作成したら以下の3つの情報が手に入ります。
- テナントID
- アプリID
- シークレット
今回利用するのはこちらのエンドポイントです。
Power Automateでライセンス情報の取得
いよいよクラウドフローを実装します。
HTTP要求でJSONを取得
「作成」アクションに先程入手したテナントID、アプリID、シークレットを収めて、「HTTP要求」アクションの各項目に配置します。方法は「GET」、認証はActie Directory OAuth、資格情報の種類は「シークレット」を選択します。
「作成」アクションは変数とちがって名前がそのまま使われるので扱いやすい名前に変更しておきます。
https://graph.microsoft.com/v1.0/subscribedSkus
https://graph.microsoft.com
「作成」は右角の...から設定を開き、セキュリティで保護された入力のスイッチをオンにすることで鍵付きにしています。

まずは、これだけでテスト実行してみます。エラーがでなければ下記のようなJSON情報が「HTTP要求」アクションの出力にかえってきているはずです。
JSONの情報量に圧倒されそうですが、ポイントは以下のとおりです。
- 3行目:value項目が配列になっていて、1要素が1つのライセンス(3行目の角括弧は配列を表します)
- 96行目:skuPartNumverの値がライセンス名(Microsoftの内部名称()
- 93行目:consumedUnitsの数字が現在割り当てられているライセンス数(ユーザ数)
- 100行目、111行目:prepaidUnitsの値のうちenabledが契約中のライセンス数
- つまり enabled数 - consumedUnits数 = ライセンス残数 (この計算はあとでPower BIで行います)
その他の項目については、この記事の末尾へ、Copilotによる解説を載せておきます。
記録用Excelファイル・テーブルを用意
取得した情報を記録するためのExcelファイルをSharePointサイトのドキュメントライブラリ上に用意します。
JSONを参考に記録したい項目をヘッダーにしてテーブル化します。テーブルにはこの段階で適当な名前を付けておきましょう。
Excelへの値書き出し
取得したJSONのValueの値は配列担っていたことを思い出しましょう。配列の1つずつの要素が1ライセンスですから、ループを回して1要素1行としてExcelに書き込んでいきます。
そのためには、「それぞれに適用する」アクションを使います。(以下 Aplly to eachと表現します)
作成したExcelのテーブルに情報を書き込むために、Apply to eachの中に「表に行を追加」アクションを加えて、先程作成したファイルとテーブルを選択しておきます。
Apply to eachの「以前の手順から出力を選択」の項目には、とりあえず動的なコンテンツから「本文」を選択しますが、実はこれではいけません。マウスを当てると「body('テナントのライセンス一覧')」と表示されますが、利用したいのはJSON全体ではなくそのなかのvalue項目の配列部分です。
私がよくやるのは、「以前の手順から出力を選択」の欄にカーソルを持っていって、ctrl + A、Ctrl + Xで切り取り。
「式」を選択して、貼り付け。前後の @{ } 部分を削除したあと、value部分を指定するために以下のように書き換えます。
body('テナントのライセンス一覧')?['value']
これでちゃんとお目当ての値が取れそうなのかを確認するために、ループの中に「作成」を作り、item()を式でいれてからテスト実行してみます。デバッグのテクニックとして「作成」を使うのはおすすめです。個人的には名前を「作成」のままにしてあるのはデバッグ用みたいに使っています。
テストしてみる
テスト実行すると、私のテナントでは5種類のライセンスがあるので配列は5つあったのでループが5周回りました。各要素が取得できていることがわかります。
ここまで確認できたら、Excelに書き出せるように必要な項目をセットしていくだけです。
Excel行に要素を割り当てる
「表に行を追加」アクションの「詳細オプションを表示」すると、Excelのテーブルに設定したヘッダーが並んでいることがわかります。こちらに以下の式を設定していきます。「式」を選択してから記述のを忘れないようにしましょう。
convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time','yyyy/MM/dd')
item()?['skuPartNumber']
item()?['skuId']
item()?['appliesTo']
item()?['prepaidUnits']?['enabled']
item()?['consumedUnits']
enabledだけ少し書き方がちがいますね。JSONを見比べてもらうと、この項目はprepaidUnitsと分類のなかのenabledという小項目の値なのです。階層構造担っている場合はこのように?でつないで記述します。?をつけておくと仮に値がなかった場合にもエラーにならないという性質があります。
書き出しをテスト実行
実行すると、このように各ライセンスの保有数と割当済みの数が記録できました。このフローを例えば週末にでも定期実行させておけば割り当てられているライセンスの推移が追えるというわけです。
Power BIで見える化
データが自動取得できるようになったので、今度はPower BIを使ってライセンスの推移がグラフで見えるようにしてみます。
もちろんExcel上でグラフ化しても良いですが、E3,E5ライセンスがあり、自身で確認するだけならば追加費用は必要ないのでチャレンジしてみましょう。
今回は気軽にチャレンジするため、あえてPower BIデスクトップは使わず、Power BIサービスだけで実装します。Power BIデスクトップを普段から使っている方には説明不要だと思いますので。
テスト用にExcelデータを加工
Power BIでのグラフの効果がわかりやすいように、今回は黄色の部分に手でテストデータを追加しました。
1月1日には保有ライセンスは25、使用済は12からスタートして、2月入り枯渇してきたので2月19日に保有ライセンスを30まで増やしたというシチュエーションです。
https://m365.cloud.microsoft/ にアクセスして、アプリ>すべてのアプリ>Power BI をクリックします。
「マイワークスペース」を開いたら、「新しい項目」>「すべての項目」の中から「セマンティックモデル」を探してクリックします。
データの形式は「Excel」を選びます。
ファイルのURLを取得します。このとき、Excelを開いた状態のブラウザ上のURLをコピーしてきてはいけません。
対象のファイルの三点リーダーから「詳細」をクリックし、画面右下の「その他の詳細」の中の「パス」を取得します。
Excelファイルを置いたSharePointのサイトURLを入力します。参照先はSharePointなので、「認証の種類」は「組織アカウント」を選びユーザーによるサインインを行います。プライバシーレベルは「組織」か「プライベート」を選択しておくとよいでしょう。「次へ」進みます。
Power BI未経験の場合、この辺りがわかりにくいかもしれません。Power BIで作ったセマンティックモデルというアイテム(一定の処理を加えたデータの塊)が、ここでサインインしたユーザーの権限によってSharePointからデータを取得する権限を得るという意味を持ちます。
Excelファイルの中身が見えるようになりました。画面左側で今回作成したテーブルを選択します。シートの選択も可能ですが、Excel内のシートが増えたときにずれてしまうこともあるので、テーブル名で指定したほうが無難です。
確認ができたら「データの変換」をクリックします。

各列には型が設定されています。グラフには数値を使いますので、enabledとConsumedUnitsの型がテキストなど担っていると困ります。
自動的に適切な型がつくはずですが、もし異なる場合には型アイコン部分をクリックして変換します。「取得日」の型が日付になっている点もポイントです。
問題がなければ「レポートの作成」をクリックし、適当な名前を付けて「作成」をクリックします。
レポートが消えてしまった場合は、マイワークスペースを開いてセマンティックモデルの三点リーダーから「レポートを作成」をクリックしましょう。
しばらく待つとレポート作成画面が表示されます。
「視覚化」から「折れ線グラフ」のアイコンをクリックしたあと、画面右端の「データ」の中にある「ライセンス」のテーブルを開き、下図のようにチェックを入れていきます。視覚化のX軸、Y軸に選択した項目がセットされたはずです。グラフは適当な大きさに引き伸ばしてください。
スライサーの設定
今度はグラフ以外の何もない場所をクリックしたあと、「視覚化」の中から「スライサー」のアイコンをクリックします。
配置されたスライサーを選択された状態で「skuPartNumber」を選択します。そうするとライセンスが選択できる状態になります。
スライサーでさきほどテストデータを用意したE5ライセンスを選択すると、E5ライセンスのデータだけに絞り込まれることでグラフがはっきりしました。
スライサーを単一選択に変更
ひとつのグラフに複数のライセンス数の合計が表示されても仕方ないので、スライサーを選択した状態で「視覚化」の真ん中のアイコンをクリックし、「選択項目」>「単一選択」のトグルをONにすると、スライサーがラジオボタンに変わります。
今度はグラフを選択した状態で「視覚化」の真ん中のアイコンをクリックし、「網掛け領域」のトグルをONにします。
さらに、「系列」を「すべて」から「enabledの合計」に切り替えて、その下の「カラー」のトグルをOFFにします。
すると、enabled(割当済みのライセンス数)の網掛けだけが残って、保有ライセンス数のグラフは線だけが残ります。

ここまでできれば、ライセンス数の残りがどのくらいかが見えやすくなりました。
レポートを保存
ある程度できてきたので、消えてしまわないようにレポートを保存しておきましょう。画面右上過度の「保存」をクリックするとレポート名を聞かれます。セマンティックモデルと同じ名前にしておくと、あとでPower BIデスクトップでも編集できるようになります。
保存すると閲覧画面になります。さらに加工を加えたい場合は上部中央の「編集」をクリックします。
データラベル
グラフを選択した状態で「視覚化」の中央アイコンから「データラベル」のトグルをONにします。グラフの中に数字が表示されるようになりました。
タイトル
グラフを選択した状態で「視覚化」の中央アイコンからさらに「全般」タブを選択すると「タイトル」という項目が見つかります。グラフの左肩のタイトル名を変更することができます。
X軸を取得日に変える
ここでうっかりしていましたが、グラフのX軸は日付の下にYearという表示が出ています。
Power BIでは例えば売上をグラフにするような場合、月の合計、年の合計などを簡単にグラフを変化させて表示できます。
しかし、今回はある時点のライセンス数であって、月や年でその合計のグラフが出てきても仕方がないですね。
視覚化のX軸のところで、「Date Hierarchy」を「取得日」に切り替えましょう。
いろいろと加工を加えたら忘れずに「保存」しておきましょう。
画面左上の「閲覧表示」をクリックします。
在庫数を計算する
グラフの紫色の線と青色の線の差である白い部分の高さが在庫を表しています。
在庫 = 契約数 - 割当済み数
になります。こういうのをPower BIで計算する場合にはDAX式というのを使います。
Power BI デスクトップの場合はビジュアルの画面で作成できるのですが、Power BI サービスのレポート画面ではまだこの操作ができないので、セマンティックモデルを開きます。
まずワークスペースを開き、セマンティックモデルの三点リーダーから「セマンティックモデルを開く」をクリックします。
画面右上角の「表示中」という緑色のボタンをクリックして「編集」に切り替えます。

「新しいメジャー」をクリックすると式を入力できるので、以下を貼り付けて「コミット」を押します。すると右側のテーブルの中にライセンス残数という項目ができました。
レポート画面の編集にもどると、先程メジャーで作成した「ライセンス残数」の項目がデータの中に現れているのがわかります。グラフとスライサーを適当に避けた場所に、視覚化「テーブル」で「取得日」と「ライセンス残数」のチェックを入れると残数を表として表示できます。
表の下に合計があるのは変なので、視覚化の真ん中のアイコンをクリックして「合計」のトグルをOFFにしました。
Power BIの自動更新を設定する
無事に見える化ができましたが、このままだとExcelファイルにデータが追加されてもPower BIのグラフは変化しません。セマンティックモデルは更新をかけることでデータを吸い取り、グラフに反映させます。
マイワークスペースに戻り、セマンティックモデルの「更新のスケジュール設定」アイコンをクリックします。
「最新の情報に更新」を開いて、定期更新の曜日と時間を選択しましょう。
Power AutomateでExcelファイルに情報が追加されるタイミングよりもあとに設定すると良いと思います。
ちなみに、Power Automateからセマンティックモデルの更新トリガーを発動させることもできるので、その場合はこの設定が不要です。
Power Automateの定期実行を設定する
フローの一番上にある「手動でフローをトリガーします」を削除します。
代わりに「繰り返し」トリガーを毎週日曜日実行に設定しました。
さきほどPower BIの定期実行設定のところで触れていましたが、Power BIのセマンティックモデルはPower Automateからキックすることができます。こうしておけば、Excelへの追加処理ができたあとでPower BIに値を吸い上げさせることができます。
アクションの名前は「データセットの更新」となっていますが、これは現在のセマンティックモデルの昔の名前です。「データセット」と呼ばれていましたその名残です。
先程つくったセマンティックモデルを選択すれば出来上がり!
まとめ
Power AutomateとPower BIをつかってGraph APIからM365ライセンスの取得とライセンス在庫の計算までやってみました。
HTTP要求なのでPower AutomateをつかわなくてもPythonやPowerShellでも同じようなことはできると思いますが、SharePointへの保存からPower BIの見える化までをサーバ不要で組み立てられるのはPower Platformの利点だと思います。
Power BIではマイワークスペースに置くことで、自分自身はレポートのURLを開くだけで最新の状態を確認することができます。もし他のユーザーにも作成したグラフを共有したいという場合には、共有する側と共有される側の両方にPower BI Proライセンスが必要です。
Proライセンスの取得は難しいという場合には、セマンティックモデルをダウンロードして、相手のマイワークスペースにもアップロードし、Excelファイルへの認証さえ行えるようにすれば良いかと思います。
こんな人が書いてます。
こちらの記事はランゲルハンス島のDDさんが紹介しました。ブログでクラウドフローのTIPSのようなものを書いたり、Qiita記事を書いたりしていますのでご贔屓に。
フォローやいいねいただけると嬉しいです。
関西のPowerPlatform系の勉強会にときどき出没しますので、気軽に声をかけていただけると喜びます!
付録:Microsoft Graph API ライセンス情報(SKU)項目解説
このドキュメントは、Microsoft Graph API で取得した Microsoft 365 テナントのライセンス(SKU)情報について、
各プロパティが何を意味するのかを解説したものです。
1. 全体概要
この JSON オブジェクトは、テナントで利用可能な 1 種類のライセンス(SKU) を表します。
例では DEVELOPERPACK_E5(Microsoft 365 Developer Program E5) の情報です。
2. ルートレベルの項目
accountName
- ライセンスを保持しているテナント(アカウント)の表示名
- 開発者テナントやパートナー経由の場合、短縮名になることがあります
accountId
- テナント(Microsoft Entra ID / Azure AD)の一意な ID(Tenant ID)
appliesTo
- ライセンスが割り当てられる対象
-
User:ユーザー単位 -
Company:テナント全体
-
capabilityStatus
- ライセンス全体の状態
-
Enabled:使用可能 -
Suspended:一時停止中 -
Deleted:削除済み
-
consumedUnits
- 現在使用中(割り当て済み)のライセンス数
id
- Graph API 内部で使用される一意な識別子
- 通常は
accountId_skuIdの形式
skuId
- SKU(ライセンス種別)を識別する GUID
- スクリプトや API 操作で使用
skuPartNumber
- 人が読める SKU 名称
- 例:
DEVELOPERPACK_E5,ENTERPRISEPACK,ENTERPRISEPREMIUM
subscriptionIds
- この SKU が紐づく Microsoft 365 / Azure サブスクリプション ID
- 課金・契約単位の識別子
3. prepaidUnits(購入・割当可能数)
| 項目 | 説明 |
|---|---|
| enabled | 有効で割り当て可能なライセンス数 |
| suspended | 一時停止中のライセンス数 |
| warning | 有効期限警告状態のライセンス数 |
| lockedOut | 支払い未完了等でロックされたライセンス数 |
4. servicePlans(ライセンス内の個別サービス)
1 つのライセンス(SKU)は、複数の サービスプラン で構成されています。
servicePlanId
- サービスプランを識別する GUID
servicePlanName
- サービスプランの内部名称
- 例:Exchange, Teams, SharePoint, MyAnalytics など
servicePlanType
- サービスの内部的な分類
- 管理者が意識する必要はほとんどありません
provisioningStatus
- サービスプランの有効状態
-
Success:有効 -
Disabled:無効 -
PendingActivation:有効化処理中
-
appliesTo(servicePlans 内)
- サービスの適用対象
-
User:ユーザー単位 -
Company:テナント全体
-
5. 実務でよく使う重要項目
skuPartNumberconsumedUnitsprepaidUnits.enabledservicePlans[].provisioningStatus
6. 補足
- ユーザーごとのライセンス詳細や、
サービスプランの ON / OFF 状態を確認する場合は
licenseDetailsエンドポイントを使用します。









































