次の方法で共有


Expense Agent を設定する (プレビュー)

Von Bedeutung

  • これは運用に対応したプレビュー機能です。
  • 運用に対応したプレビューには 追加使用条件 が適用されます。

ERP と統合された Dynamics 365 Project Operations と製造向けの Dynamics 365 Project Operations に適用されます

経費エージェントは、Microsoft Dynamics 365 Project Operations、財務と運用アプリ、Microsoft Copilot Studio、Power Automate、Dataverse の機能を組み合わせて、AI を使用して経費処理ワークフローを自動化します。 この機能は、システムが領収書を処理し、ユーザーの経費明細行と経費レポートを生成できるようにすることで、時間を節約し、手動作業を削減するのに役立ちます。 Microsoft Power Platform コネクタを使用して、Dataverse 仮想エンティティを介して Outlook、Microsoft Teams、ユーザー カレンダー、財務と運用アプリ環境と統合します。

経費エージェントには複数のフローが含まれており、そのうちの 3 つがコア オーケストレーターとして機能します。

  • メールの処理 – このフローは、構成されたメールボックス フォルダーを 1 時間ごとにスキャンし、添付ファイルを未添付の領収書として Dynamics 365 Finance に格納します。
  • 領収書 ID の抽出 – このフローは、未添付領収書を取り出し、エージェントをトリガーして領収書の詳細を抽出し、未添付の経費明細行を作成します。
  • 経費レポートの処理 – このフローは、各法人のアプリケーションで設定した構成 別のグループ レポート に基づいて、未接続の経費明細行を変換し、経費レポートを生成します。

さらに、エージェントは Microsoft Teams と統合され、経費報告書のレビューと提出にアダプティブ カードを使用できます。

エージェントは、いくつかの Microsoft Power Platform コネクタに依存しています。 これらのコネクタは、提供されている Power Automate フローで自動的に参照されます。

  • Outlook (Office 365) – このコネクタは、共有メールボックスにアクセスして領収書を抽出します。
  • Dataverse (仮想エンティティ) – このコネクタは、仮想エンティティを介して財務と運用アプリと統合されます。
  • Microsoft Copilot Studio – このコネクタは、AI モデルを呼び出して領収書の情報を抽出します。
  • Microsoft Teams – このコネクタは、ユーザーとの対話用のアダプティブ カードを送信します (Teams 統合が有効になっている場合)。
  • Microsoft 365 ユーザー – このコネクタは、ユーザーのカレンダーの詳細を取得します (領収書の解析がコンテキスト対応の場合は省略可能)。

[前提条件]

  1. 財務および運用環境: エージェントをインストールするには、少なくとも財務および運用環境のバージョン 10.0.44 (10.0.2263.175 以降) または 10.0.45 (10.0.2345.115 以降)、または 10.0.46 (10.0.2428.69 以降) が必要です。
  2. Expense Agent ユーザーを設定するために必要なロール: この記事の手順を完了するには、組織のシステム管理者であり、Expense Agent をインストールするための経費エージェント ユーザーを設定するには、次のロールが必要です。
System Role Comments
Power Platform 管理センター システム管理者
  1. Power Platform 管理センター に移動します
  2. 左のペインで 管理 に移動します。 環境 を選択し、続いてお使いの環境を選択します。
  3. アクセス>ユーザー セクションで すべて表示 を選択します。
  4. ユーザーを選択してから ロールを管理する を選択し、ロールを追加します。
Finance and Operations システム管理者
  1. 環境の財務と運用の URL を開きます。
  2. モジュール>システム管理>ユーザー に移動して、ユーザーを選択します。
  3. ロールの追加 – [システム管理者] を選択します。
Microsoft 365 Exchange 管理者とユーザー管理者
  1. Microsoft 365 管理センター に移動します。
  2. ユーザー>アクティブなユーザー> に移動し、ユーザーを選択します。
  3. ロールの管理 を選択し、ロール から Exchange 管理者 を選択します。
  4. 変更を保存 します。
  5. 同じ手順に従って、ユーザー管理者 ロールを追加します。
Teams 管理センター Teams 管理者 Microsoft Teams 統合を有効にする予定の場合は必須

経費エージェントを設定する手順

Expense Agent をインストールして設定するには、次の手順に従います。

  1. 財務と運用アプリ用の Copilot をインストールします。
  2. 環境でエージェント機能を有効にします。
  3. エージェントを実行するための経費ユーザーを作成します。
  4. 共有メールボックスを設定します。
  5. 経費エージェントを設定します。
  6. Microsoft Teams で経費エージェントを有効にする (Microsoft Teams 統合が必要な場合は省略可能)

以降のセクションでは、各手順について詳しく説明します。

ステップ 1: 財務と運用アプリ用の Copilot をインストールする

経費エージェントは、金財務と運用アプリ用の Copilot パッケージの一部として利用できます。 このパッケージを環境にインストールすると、エージェント、環境変数、Power Automate フローなど、必要なすべての資産が自動的に取得されます。

必要なアプリをインストールするには、次の手順に従います。

  1. ブラウザーで Power Platform 管理センター に移動します。
  2. 環境の一覧から、アプリをインストールする環境名を選択します。
  3. 環境の詳細ページ (左側のナビゲーションからではなく ) で、[ リソース ] セクションに移動し、[ Dynamics 365 アプリ] を選択します。
  4. Dynamics 365 アプリの一覧で、財務と運用アプリ用の Copilot を検索します。 既にインストールされていて、更新プログラムが利用可能な場合は、更新 ボタンを選択します。
  5. アプリが Dynamics 365 アプリの下に表示されない場合は、アプリのインストール を選択し、財務と運用アプリ用の Copilot を選択して、指示に従ってインストールを完了します。
  6. Finance および Operations アプリの Copilot は 1.0.3231.4 以降である必要があります

お使いの環境で Copilot を有効にする方法の詳細については、「財務と運用アプリで Copilot 機能を有効にする」を参照してください。

ヒント

パッケージが正常にインストールされたかどうかを確認するには、次の手順に従います。

  1. Power Apps Maker Portal に移動して > 環境を選択 > ソリューションを選択 > 履歴を表示 > msdyn_ExpenseAI を検索して選択 > [詳細] を選択します。
  2. [結果] フィールドを確認します。
    1. 結果に [成功] と表示された場合、パッケージは正しくインストールされています。
    2. 結果に [成功] と表示されない場合、インストールは失敗しています。
  3. インストールが失敗した場合は、msdyn_FnOCopilotAnchorを削除し (アンインストールセクションを参照)、金融および運用アプリ用の Copilot をもう一度インストールします。

ステップ 2: 環境でエージェント機能を有効にする

金融および運用用の Copilot アプリ パッケージをインストールした後、Dataverse および財務および運用環境内から Expense Agent をアクティブ化します。

Dataverse で機能を有効にする

Power Platform 管理センターで Copilot 機能フラグをオンにします。 Copilot 機能フラグを有効にするには、次の手順に従います。

  1. Power Platform 管理センターに移動します。
  2. 環境> 環境を選択 >設定>製品>機能 の順に選択します。
  3. Copilot 機能のフラグがオンになっていることを確認します。

財務と運用環境で機能を有効にする

財務アプリと運用アプリでエージェントをアクティブ化するには、次の手順に従います。

  1. 財務と運用アプリ環境 にサインインします。
  2. 機能管理 に移動し、イマーシブ ホーム機能エージェント管理 機能を有効にします。
  3. 経費エージェントを構成するには (設定は法人ごとに行います)、経費管理>設定>全般>経費管理パラメーター に移動します。
  4. 経費入力エージェント タブで、次の表に示すようにパラメーターを構成します。
パラメーター 価値 Comments
現在の法人で経費エージェントを有効にする イエス 現在の法人でエージェントを有効にするには、はい に切り替えます。
頻度 日単位または週単位 組織で経費報告書を自動的に作成する頻度を構成します。
報告書のグループ化の基準 移動またはプロジェクト プロジェクトまたは移動に基づいて経費をグループ化するように構成します。

手順 3: エージェント処理用の経費エージェントユーザーを作成する

専用の経費エージェント ユーザーを作成して、エージェントが従業員の ID とは無関係に実行されるようにします。 このアプローチは、セキュリティ、管理容易性、および長期的な保守容易性に役立ちます。 必要な特権を持つ既存のユーザー アカウントを使用できますが、システム所有の ID を使用します。

Microsoft Entra ID で Expense Agent ユーザーを作成する

  1. Azure portal にサインインします。
  2. 使用可能な Azure サービスから、Microsoft Entra ID を選択します。
  3. Microsoft Entra ID で、新しいユーザーを作成します。
  4. 追加>ユーザー>新規ユーザーを作成する を選択し、次の詳細を入力します。
    • ユーザー プリンシパル名
    • 適切なドメインを選択する
    • 表示名称
    • パスワード
    • アカウントを有効にする
  5. 詳細を表示し、ユーザー作成プロセスを完了するには、レビュー + 作成 を選択し、作成 を選択します。
  6. [ユーザー] ページ (管理 > ユーザー) から、ユーザーを選択し、詳細ページを表示します。
  7. プロパティの編集 を選択し、設定 タブに移動し、適切な使用場所を入力します。

組織のポリシーによっては、パスワードの変更と多要素認証 (MFA) の設定が必要な場合があります。 パスワードを変更して MFA を設定する場合は、通常と同様の手順に従います。

経費エージェント ユーザーに必要なライセンスを割り当てる

Expense Agent を正常にインストールするには、次のライセンスを経費エージェント ユーザーに割り当てます。

  • Dynamics 365 Teams Members ライセンス
  • Microsoft 365 Business Basic、または Microsoft Teams と Outlook を対象とするライセンス (たとえば、Teams を含む Office 365 E5)
  • Power Apps Premium

ライセンスを割り当てるには、次の手順に従います。

  1. ライセンス管理者以上のユーザーであるライセンスを割り当てるアクセス権を持つユーザーを使用して、Microsoft 365 管理センター にサインインします。
  2. 請求>ライセンス>Dynamics 365 Teams Members ライセンス を選択します。
  3. +ライセンスの割り当て を選択します。
  4. 前の手順で作成した経費エージェント ユーザーを検索します。
  5. [割り当て] を選択してライセンスの割り当てを完了します。
  6. 他のライセンス (Microsoft 365 Business Basic および Power Apps Premium) についても、手順 2 から 5 に従います。

ライセンスの確認および割り当て方法の詳細については、「[アクティブ ユーザー] ページでライセンスの割り当てまたは割り当ての解除を行う」を参照してください。

Power Platform 環境にユーザーを追加する

Power Platform 環境にユーザーを追加するには、次の手順に従います。

  1. Power Platform 管理センター にサインインし、適切な環境を選択します。

    ヒント

    このページでは、Dataverse の環境 ID、Dataverse の環境 URL、財務と運用の URL に関連する情報を提供します。 これらの値を格納して、後のセクションで使用します。

  2. アクセス > ユーザー > すべて表示 に移動します。

  3. ユーザーの追加 を選択し、新しく作成したエージェント ユーザーを入力して、追加 を選択します。

  4. [ セキュリティ ロールの管理 ] ページで、次のロールを追加します。

    • 経費 AI エージェントの役割
    • ファイナンスおよびオペレーション エージェント設定マネージャー
    • システム カスタマイザー
  5. ロールの割り当てを確認するには、保存 を選択します。

これらのロールは、エージェントが機能する必要がある Dataverse および Power Automate コンポーネントへのアクセスを提供します。

ヒント

ユーザーが既に存在し、ロールを割り当てるだけで済む場合は、Power Platform 管理センターに移動し、適切な環境を選択します。

  1. アクセス > ユーザー > すべて表示 に移動します。
  2. 作成したエージェント ユーザーを選択します。
  3. ロールの管理 を選択し、ロールを割り当てます。

財務と運用環境で必要なロールを割り当てる

財務および運用環境で ExpenseAgentRole ロールを割り当てるには、次の手順に従います。

  1. 財務と運用環境で、 システム管理>ユーザー に移動します。
  2. エージェント ユーザーのユーザー レコードを作成します。
  3. ユーザーを作成したら、ユーザーの [ロール] セクションに移動し、[ ロールの割り当て] を選択して ExpenseAgentRole を検索します。
  4. 保存 を選択します。

ExpenseAgentRole は、財務と運用アプリのバージョン 10.0.44 (10.0.2263.81)10.0.45 (10.0.2345.6)、および 財務と運用アプリ用の Copilot のバージョン 1.0.3121.1 から入手できます

共有メールボックス アクセスへのアクセスを割り当てる

エージェント ユーザーには、Mail.Read.Shared Microsoft Graph アクセス許可が必要です。 このアクセス許可により、エージェントはフローの実行中に構成済みの共有メールボックスから領収書を読み取ることができます。

共有メールボックス へのアクセスを割り当てるには、次の手順に従います。

  1. Microsoft Graph エクスプローラーに移動し、作成したエージェント ユーザーを使用してサインインします。
  2. 右上隅にある ユーザー アイコンを選択 >アクセス許可への同意 を選択します。
  3. メール> のドロップ メニューを選択して次を検索 Mail.Read.Shared>同意同意 の順に選択します。

作成されたエージェント ユーザーに必要なロールの概要

環境 役割 Comments
Dataverse
  • 経費 AI エージェントのロール
  • 財務および運用エージェント構成マネージャー
  • システム カスタマイザー
  • 前述のロールにより、エージェントは Dynamics 365 Finance に接続されている Power Automate フロー、環境変数、および仮想エンティティと対話できます
    Finance and Operations
  • ExpenseAgentRole
  • システム ユーザー
  • このロールは、エージェントが財務と運用アプリ環境で経費入力を作成および管理するために必要です。

    注意: ExpenseAgentRole は、財務と運用アプリのバージョン 10.0.44 (10.0.2263.81)10.0.45 (10.0.2345.6)、および 財務と運用アプリ用の Copilot のバージョン 1.0.3121.1 から入手できます
    Graph エクスプローラーを使用した共有メールボックス アクセス Mail.Read.Shared Microsoft Graph のアクセス許可。エージェントはフローの実行中に構成済みの共有メールボックスから領収書を読み取ることができます

    ステップ 4: 共有メールボックスを設定する

    経費エージェントは、共有メールボックスを使用して受信メールの受信と処理を行います。 Exchange 管理者ロールを持つユーザーは、Microsoft 365 管理センターでこのメールボックスを作成して構成する必要があります。

    共有メールボックスを作成して構成するには、次の手順に従います。

    1. 経費管理者アカウントを使用して Microsoft 365 管理センター にサインインします。

    2. 左ペインで Teams & グループ>共有メールボックス を選択します。

      ヒント

      [ すべて表示 ] を選択して完全な一覧を展開する必要がある場合があります。

    3. [ 共有メールボックスの追加] を選択します。

    4. 共有メールボックスの名前とメール アドレスを入力します。

    5. [変更の保存] を選択します。

    6. 次のステップ で、この共有メールボックスにメンバーを追加する を選択します。 (メンバー管理が利用可能になるまでに数分かかる場合があります)。

    7. メンバーの追加 を選択します

    8. 作成したエージェント ユーザーと、メールボックスを監視する他のユーザーを選択し、追加 を選択します。

    9. を選択してを閉じます。

    次の手順では、共有メールボックスのメール アドレスを使用します。 共有メールボックスを設定したら、Time and Expense Agent を構成するときに、そのメール アドレスとフォルダー パス (既定では受信トレイに設定) を環境変数として指定する必要があります。 詳細については、「 手順 5: Expense Agent を設定する」を参照してください。

    ステップ 5: 経費エージェントを設定する

    経費エージェントを設定するには、次の 2 つのオプションがあります。

    • オプション A: PowerShell スクリプトを使用する (推奨)
    • オプション B: Power Apps で手動セットアップを行う (PowerShell なし)

    Von Bedeutung

    Expense Agent のインストールを続行する前に、エージェントが Microsoft Copilot Studio で正常にプロビジョニングされていることを確認します。

    エージェントが正常にプロビジョニングされたことを確認するには、次の手順に従います。

    1. Microsoft Copilot Studio にサインインし、環境を選択します。
    2. エージェント に移動し、ExpenseAgent-Line (プレビュー) を検索します。
    3. [発行] ボタンが有効になっていることを確認します。
    4. 有効になっている場合は、インストールに進みます。 無効の場合は、エージェントがプロビジョニングされるまで待ちます。
    5. 次の手順を繰り返して、経費入力エージェント (プレビュー) が有効になっていることを確認します。

    ヒント

    Copilot の財務および運用アプリのプロビジョニングに 5 ~ 6 時間以上かかる場合は、アプリをアンインストールして再インストールして、セットアップの遅延の可能性を解決します。 詳細については、この記事の最後にある「 Expense Agent のアンインストール 」セクションを参照してください。

    エージェントの手動セットアップには、接続の作成とリンク、Power Automate フローの有効化、ソリューションの発行が含まれます。 このプロセスは時間がかかり、エラーの影響を受けやすくなります。 セットアップを自動化するには、必要なパラメーターを更新した後に PowerShell スクリプトを使用します。

    PowerShell スクリプトで次のタスクを自動化します。

    • 必要な環境変数を更新します。
    • Microsoft Power Platform 接続をソリューション接続参照とリンクします。
    • Time および Expense Agent に必要なすべての Power Automate フローを有効にします。
    • Copilot エージェントを発行します。
    • Dataverse ソリューションを発行します。

    スクリプトを実行する前に、install.ps1 ファイル内の各コネクタの接続 ID を指定する必要があるため、接続を作成する 必要があります。 これらの接続を作成するには、作成したエージェント ユーザーを使用して次の手順に従います。

    1. 新しく作成したエージェント ユーザーを使用して Power Apps Maker ポータル にサインインし、環境を選択します。
    2. 左ウィンドウで、その他 を選択し、接続 を選択します。
    3. [ 新しい接続 ] を選択し、次の表の [接続名] を使用して検索します ( Office 365 Outlook など)。
    4. 一覧から適切なコネクタを選択して作成します。
    5. 接続が作成されたら、接続が作成されたユーザーをメモします。 作成されたエージェント ユーザー ID が理想的です。 次の手順で作成したインストール ファイルで、このユーザー ID を更新します。
    6. 次の表に示す残りの必要な接続ごとに、ステップ 3 と 4 を繰り返します。
    接続名 接続 URL の形式
    Office 365 Outlook https://make.powerapps.com/environments/environmentID/connections
    / shared_office365/connectionID/details
    Office 365 をお使いの方 https://make.powerapps.com/environments/environmentID/connections
    / shared_office365users/connectionID/詳細
    Microsoft Teams https://make.powerapps.com/environments/environmentID/connections
    / shared_teams/connectionID/details
    マイクロソフト Dataverse https://make.powerapps.com/environments/environmentID/connections
    / shared_commondataserviceforapps/connectionID/詳細
    Microsoft Copilot Studio (プレビュー) https://make.powerapps.com/environments/environmentID/connections
    / shared_microsoftcopilotstudio/connectionID/詳細

    インストール ファイルを作成するために必要な情報

    インストール ファイル ( install.ps1) を作成するには、次の情報を使用できます。 (参照については、次の表を参照してください)。

    パラメーター その他の詳細
    Dataverse 環境 ID Power Platform 管理センターから取得する環境 ID を入力します。
    サンプル値: xxxx-xxxx-xxxx-xxx-xxxxxxxxxx
    Dataverse 環境 URL Power Platform 管理センターから環境 URL を入力します。
    注意: 先頭に https:// があり、末尾にスラッシュ '/' がないことを確認してください。
    サンプル値: https://org123.crm.contoso.com
    財務と運用インスタンス URL 財務と運用環境の詳細を次の形式で入力します。
    サンプル値: https://org123.contoso.com
    注意: 先頭に https:// があり、末尾に スラッシュ ‘/’ がないことを確認してください。
    OutlookFolderPath 共有メールボックスに作成されたフォルダー パスを入力します。 他のフォルダーが作成されていない場合は、既定で受信トレイとして設定されます。
    サンプル値: 受信トレイ
    ベスト プラクティスとして、経費管理用に別のフォルダーを作成します
    メールボックス アドレス ID 新しく作成した共有メールボックスのメール アドレスを入力します
    サンプル値: expenseagent@contoso.com
    Microsoft Dataverse の接続名
    Microsoft Copilot Studio の接続名
    Microsoft Office Outlook の接続名
    Microsoft Office 365 ユーザーの接続名
    Microsoft Teams の接続名
    すべての接続名への入力は同じで、作成されたエージェント ユーザーのユーザー電子メール ID です。

    サンプル値: createdexpenseagentuser@contoso.com

    インストール スクリプト ファイルを作成する

    次のコードをコピーして、インストール スクリプト ファイルを作成します。 スクリプトに必要な環境変数を挿入し、PowerShell を使用してスクリプトを実行します。

    インストール スクリプト ファイルをローカル デスクトップに配置します。 One Drive に保存しないでください。

    次のコードを使用して PowerShell スクリプト ファイルを作成します。 スクリプトを実行する前に、前述のパラメーターを更新します。

    ヒント

    Mandatory = $trueの場合、PowerShell ではパラメーターを対話形式で入力するように求められます。そのため、スクリプト ファイルでパラメーターを直接更新する必要はありません。

    手動入力を回避し、インストール スクリプト内のパラメーターを事前に定義する場合は、次のサンプル コードの Param セクションで Mandatory = $falseを設定します。

    次のコードをインストール スクリプト ファイルにコピーし、 'Install.ps1' として保存します。 param セクションの各パラメーター フィールドの変数を更新します。 10 個の変数を更新する必要があります。

    ヒント

    前の表をリファレンスとして使用し、すべてのサンプル値をそれぞれの詳細に置き換えます。

    #requires -Version 7
    Param(
    
       [Parameter(Mandatory=$true, HelpMessage="Dataverse environment id")]
       [string]$DataverseEnvironmentId = "xxxx-xxxx-xxxx-xxx-xxxxxxxxxx", 
    
       [Parameter(Mandatory=$true, HelpMessage="Dataverse environment URL")]
       [string]$DataverseUrl = "https://org123.crm.dynamics.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Finance and Operations instance URL")]
       [string]$D365FinanceAndOperationsUrl = "https://org123.operations.dynamics.com",
    
       [Parameter(Mandatory=$true, HelpMessage="OutlookFolderPath")]
       [string]$OutlookFolderPath = "Inbox",
    
       [Parameter(Mandatory=$true, HelpMessage="Mailbox Address Id")]
       [string]$MailboxAddressId = "expenseagent@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Dataverse connection name")]
       [string]$MicrosoftDataverseConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Copilot Studio connection name")]
       [string]$MicrosoftCopilotStudioConnectionName = "createdexpenseagentuser@contoso.com",
       
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Office Outlook connection name")]
       [string]$Office365OutlookConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Office 365 Users connection name")]
       [string]$Office365UsersConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$true, HelpMessage="Microsoft Teams connection name")]
       [string]$MicrosoftTeamsConnectionName = "createdexpenseagentuser@contoso.com",
    
       [Parameter(Mandatory=$false, HelpMessage="Checks for bot Sync Errors and if there is provisioning required before Agent publish step")]
       [boolean]$CheckBotSyncStatusAndProvisionBots = $false
    
    )
    
    $flows = @(
        "expense entry retry check",
        "expense configuration",
        "get expense outlook folder",
        "generate expense report",
        "send expense report adaptive card",
        "auto match expenses",
        "process emails",
        "extract unattached receipt ids for copilot invocation",
        "extract unattached receipt output using dataverse plugin",
        "generate expense line",
        "generate expense line without project id and status id",
        "identify project ids",
        "user calendar events",
        "process expense report using copilot",
        "invoke expense agent for receipt processing"
    )
    
    
    $agents = @(
        "msdyn_ExpenseEntryAgent",
        "msdyn_ExpenseReportAgent"
    )
    
    
    # Check PS version
    if ($PSVersionTable.PSVersion.Major -lt 7) {
        Write-Error 'This script requires at least PowerShell version 7' -ErrorAction Stop
    }
    
    # Install the required modules if not already installed or if the version is not 1.0.40
    if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell | Where-Object { $_.Version -ge [Version]"1.0.40" })) {
        Write-Host "Microsoft.PowerApps.PowerShell version 1.0.40 not found. Installing..." -ForegroundColor Yellow
        Install-Module -Name Microsoft.PowerApps.PowerShell -RequiredVersion 1.0.40 -Force -AllowClobber -Scope CurrentUser
    } else {
        Write-Host "Microsoft.PowerApps.PowerShell version 1.0.40 is already installed." -ForegroundColor Green
    }
    
    if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.Administration.PowerShell | Where-Object { $_.Version -ge [Version]"2.0.147" })) {
        Install-Module -Name Microsoft.PowerApps.Administration.PowerShell -RequiredVersion 2.0.147 -Force -AllowClobber -Scope CurrentUser
    }
    
    # Install the required modules if not already installed
    if (-not (Get-Module -ListAvailable -Name Az.Accounts | Where-Object { $_.Version -ge [Version]"5.0.1"})) {
        Install-Module -Name Az.Accounts -RequiredVersion 5.0.1 -Force -AllowClobber -Scope CurrentUser
    }
    
    # Import required modulesds
    Import-Module Az.Accounts
    Import-Module Microsoft.PowerApps.PowerShell
    Import-Module Microsoft.PowerApps.Administration.PowerShell
    
    # global variable declaration
    $filter = '$filter'
    
    
    function Get-AccessToken {
        # Retrieve the access token for the Dataverse environment
        $accessToken = (Get-AzAccessToken -ResourceUrl "$DataverseUrl" -AsSecureString).Token
        Write-Host "Access token for $userId retrieved successfully." -ForegroundColor Green
        return $accessToken
    }
    
    function Get-AccessTokenPlainText {
        param(
            [Parameter(Mandatory=$true, HelpMessage="Access token for authentication")]
            [securestring]$accessToken
        )
        # Retrieve the access token for the PVA environment
        $token = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
        [Runtime.InteropServices.Marshal]::SecureStringToBSTR($accessToken))
        return $token
    }
    
    function update-EnvironmentVaribleValue {
            param (
            [string]$accessToken,
            [string]$env_key,
            [string]$env_value   # Access token for authentication
        )
    
        try 
        {
            # Get the environment variable definition
            $envVarDefinition = Invoke-RestMethod -Method Get -Uri "$DataverseUrl/api/data/v9.2/environmentvariabledefinitions?$filter=schemaname eq '$env_key'" -Headers @{
                Authorization = "Bearer $accessToken"
            }
    
            if ($envVarDefinition.value -ne $null) {
                $envVarDefId = $envVarDefinition.value[0].environmentvariabledefinitionid
    
                # Get the environment variable value record
                $filterValue = [System.Web.HttpUtility]::UrlEncode("_environmentvariabledefinitionid_value eq $envVarDefId")
                $envVarValue = Invoke-RestMethod -Method Get -Uri "$DataverseUrl/api/data/v9.2/environmentvariablevalues?$filter=$filterValue" -Headers @{
                    Authorization = "Bearer $accessToken"
                }
    
                if ($envVarValue.value -ne $null) {
                    $envVarValueId = $envVarValue.value[0].environmentvariablevalueid
                    # Update the environment variable value
                    Invoke-RestMethod -Method Patch -Uri "$DataverseUrl/api/data/v9.2/environmentvariablevalues($envVarValueId)" -Headers @{
                        Authorization = "Bearer $accessToken"
                        "Content-Type" = "application/json"
                    } -Body (@{ value = $env_value } | ConvertTo-Json -Depth 1)
                    Write-Host "Environment variable updated with name $env_key and value $env_value" -ForegroundColor Green
                } else {
                    Write-Host "Environment variable value not found for $env_key. Skipping..." -ForegroundColor Red
                }
            } 
            else {
                Write-Host "Environment variable definition not found for $env_key. Skipping..." -ForegroundColor Yellow
            }
      }
      catch {
            Write-Host "Failed to update environment variable $env_key. Error: $($_)" -ForegroundColor Red
            throw $_  # Re-throw the error to stop the script if this step is critical
        }
    
    }
    
    function update_EnvironmentVariablesForExpense {
            param (
            [string]$accessToken   # Access token for authentication
        )
    
        write-host "Updating environment variables..." -ForegroundColor Yellow
    
        try 
        {
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseFnoInstanceUrl" -env_value $D365FinanceAndOperationsUrl
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseAgentOutlookFolderPath" -env_value $OutlookFolderPath
            update-EnvironmentVaribleValue -accessToken $accessToken -env_key "msdyn_ExpenseAgentMailboxAddressId" -env_value $MailboxAddressId
            
        }
        Catch {
            Write-Host "Failed to update environment variables. Error: $($_)" -ForegroundColor Red -ErrorAction Stop
        }
    }
    
    # Function to publish the solution
    function Publish-Solution {
        param (
            [string]$accessToken
        )
    
        Write-Host "Publishing All" -ForegroundColor Yellow
    
        # Construct the API endpoint for publishing the solution
        $uri = "$DataverseUrl/api/data/v9.2/PublishAllXml"
    
    
        # Make the API call
        try {
            Invoke-RestMethod -Method Post `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                }
    
            Write-Host "Publish All - Success!" -ForegroundColor Green
        } catch {
            Write-Host "Failed to publish. Error: $($_.Exception)" -ForegroundColor Red
            
        }
    }
    
    function Get-FlowGuidByName {
        param (
            [string]$accessToken,   # Access token for authentication
            [string]$flowName       # Name of the flow to search for
        )
    
        #Write-Host "Retrieving GUID for flow: $flowName" -ForegroundColor Yellow
    
        # Construct the API endpoint with a filter for the flow name
        $encodedFlowName = [System.Web.HttpUtility]::UrlEncode($flowName)
        $uri = "$DataverseUrl/api/data/v9.2/workflows?$filter=name eq '$encodedFlowName'"
    
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                }
    
            # Check if the flow was found
            if ($response.value.Count -gt 0) {
                $flow = $response.value[0]
                Write-Host "Flow found: $($flow.name) with GUID: $($flow.workflowid)" -ForegroundColor Green
                return $flow.workflowid
            } else {
                Write-Host "No flow found with the name: $flowName" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve flow GUID. Error: $($_.Exception.Message)" -ForegroundColor Red
            return $null
        }
    }
    
    
    # Function to activate a Power Automate flow
    function Activate-Flow {
        param (
            [string]$DataverseUrl,  # Dataverse environment URL
            [string]$accessToken,   # Access token for authentication
            [string]$flowId         # GUID of the flow to activate
        )
    
        # Construct the request body
        $body = @{
            "statecode" = 1  # Activated
            "statuscode" = 2 # Activated
        } | ConvertTo-Json -Depth 1 -Compress
    
        # Construct the API endpoint
        $uri = "$DataverseUrl/api/data/v9.2/workflows($flowId)"
    
        # Make the API call
        try {
            Invoke-RestMethod -Method Patch `
                -Uri $uri `
                -Headers @{
                    Authorization = "Bearer $accessToken"
                    "Content-Type" = "application/json"
                } `
                -Body $body
    
            Write-Host "Flow activated successfully." -ForegroundColor Green
        } catch {
            Write-Host "Failed to activate flow. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
    
    function Get-ConnectionRefIdFromLogicalName  {
        param (
            [string]$accessToken,
            [string]$connectionRefLogicalName
        )
        $uri = "$DataverseUrl/api/data/v9.2/connectionreferences?$filter=connectionreferencelogicalname eq '$connectionRefLogicalName'"
        $response = Invoke-RestMethod -Method Get `
        -Uri $uri `
        -Headers @{
            Authorization = "Bearer $accessToken"
            "Content-Type" = "application/json"
        }
    
        if ($response -ne $null) {
            write-host "Connection reference id found: $($response.value[0].connectionreferenceid) " -ForegroundColor Green
            return $response.value[0].connectionreferenceid
        }
        else {
            Write-Host "No connection reference found for logical name: $connectionRefLogicalName" -ForegroundColor Red
            return $null
        }
    }
    
    function Get-ConnectionId {
        param (
            [string]$userProvidedName,
            [string]$providerName
        )
    
        try {
            $matchedConnectionId = $null
            # Added -ErrorAction Stop to ensure the catch block is triggered on failure
            $connections = Get-PowerAppConnection -EnvironmentName $DataverseEnvironmentId -ConnectorNameFilter $providerName -ErrorAction Stop
            
            foreach ($con in $connections) {
                if (($con.ConnectionName -eq $userProvidedName) -or ($con.DisplayName -eq $userProvidedName)) {
                    $matchedConnectionId = $con.ConnectionName
                    break
                }
            }
    
            if ($null -eq $matchedConnectionId) {
                # Use 'throw' to create a terminating error that the calling function can catch
                throw "Unable to find connection '$userProvidedName' for provider '$providerName'."
            }
    
            return $matchedConnectionId
        }
        catch {
            # Catch any errors from Get-PowerAppConnection or the 'throw' statement above
            Write-Error "Failed to get connection ID for '$userProvidedName'. Error: $_"
            throw # Re-throw the error to stop the script if this step is critical
        }
    }
    
    function Get-ConnectionReferenceId {
        param(
            [string]$connectionReferenceLogicalName,
            [securestring]$accessToken
        )
    
        try {
            $uri = "$DataverseUrl/api/data/v9.2/connectionreferences?$filter=connectionreferencelogicalname eq '$connectionReferenceLogicalName'"
            
            # Added -ErrorAction Stop for clarity, though Invoke-RestMethod often terminates on HTTP errors
            $response = Invoke-RestMethod -Method Get -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -ErrorAction Stop
                
            if ($null -eq $response -or $response.value.Count -eq 0) {
                throw "Connection reference not found for logical name '$connectionReferenceLogicalName'."
            }
    
            $connectionReferenceDisplayName = $response.value[0].connectionreferencedisplayname
            $connectionReferenceId = $response.value[0].connectionreferenceid
    
            Write-Host "updating connection $connectionReferenceDisplayName for logical name $connectionReferenceLogicalName)"
            return $connectionReferenceId
        }
        catch {
            Write-Error "Failed to get connection reference ID for '$connectionReferenceLogicalName'. Error: $_"
            throw # Re-throw to notify the calling function
        }
    }
    
    function Set-ConnectionReferenceConnection {
        param (
            [string]$connectionReferenceLogicalName,
            [string]$userProvidedConnectionName,
            [string]$providerName,
            [securestring]$accessToken
        )
    
        try {
    
            # These functions will now throw terminating errors if they fail
            $connectionReferenceId = Get-ConnectionReferenceId -connectionReferenceLogicalName $connectionReferenceLogicalName -accessToken $accessToken
            $connectionId = Get-ConnectionId -userProvidedName $userProvidedConnectionName -providerName $providerName
    
            $body = @{
                "connectionid" = "$connectionId"
            } | ConvertTo-Json -Depth 1
    
            $uri = "$DataverseUrl/api/data/v9.2/connectionreferences($connectionReferenceId)"
            # Write-Host "Updating connection reference URI: $uri with connection id $connectionId"
    
            Invoke-RestMethod -Method Patch -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body -ErrorAction Stop
        
            Write-Host "Connection reference updated successfully." -ForegroundColor Green
        }
        catch {
            # This block will catch errors from any of the functions called within the try block
            Write-Error "Failed to set connection reference for '$connectionReferenceLogicalName'. Error: $_"
            throw
        }
    }
    
    function Activate-Flows {
        param (
            [string]$accessToken,
            [array]$expenseAIFlows
        )
    
        foreach ($flowName in $expenseAIFlows) {
             Write-Host "Activating flow: $flowName" -ForegroundColor Yellow
    
            # Call the Get-FlowGuidByName function to get the flow GUID
            $flowGuid = Get-FlowGuidByName -dataverseUrl $DataverseUrl -accessToken $accessToken -flowName $flowName
    
            if ($flowGuid -ne $null) {
                # Write-Host "Flow Name: $flowName, Flow GUID: $flowGuid" -ForegroundColor Green
                Activate-Flow -dataverseUrl $DataverseUrl -accessToken $accessToken -flowId $flowGuid
                # Write-Host "Flow Name: $flowName, Flow GUID: $flowGuid Activated" -ForegroundColor Green
            } else {
                Write-Host "Flow Name: $flowName not found." -ForegroundColor Red
            }
        }
    }
    
    
    # Function to retrieve the Agent ID by name
    function Get-AgentIdBySchemaName {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentSchemaName
        )
    
        Write-Host "Retrieving agent ID for agent schema: $agentSchemaName" -ForegroundColor Yellow
    
        # Construct the API endpoint to retrieve the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots?$filter=schemaname eq '$agentSchemaName'"
    
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            if ($response.value.Count -gt 0) {
                $agentId = $response.value[0].botid
                return $agentId
            } else {
                Write-Host "No agent found with the name: $agentSchemaName" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve agent ID. Error: $($_)" -ForegroundColor Red
            return $null
        }
    }
    
    function Check-BotSyncErrors {
            param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$botId
        )
    
        Write-Host "Retrieving Sync Status for bot ID: $botId" -ForegroundColor Yellow
    
        # Construct the API endpoint to retrieve the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($botId)"
        try {
            # Make the API call
            $response = Invoke-RestMethod -Method Get -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            if ($null -ne $response.synchronizationstatus) {
                # Parse the JSON string in synchronizationstatus
                $syncStatusObj = $response.synchronizationstatus | ConvertFrom-Json
                $state = $syncStatusObj.currentSynchronizationState.state
                $provisioningStatus = $syncStatusObj.currentSynchronizationState.provisioningStatus
    
                Write-Host "Synchronization State: $state" -ForegroundColor Green
                Write-Host "Provisioning Status: $provisioningStatus" -ForegroundColor Green
    
                if ( $state -contains "Error" -or $provisioningStatus -contains "Error") {
                    Write-Host "Bot has synchronization errors." -ForegroundColor Red
                    return 0
                } else {
                    if ( $state -eq "Synchronized" -or $state -eq 'Synchronizing' -and ($provisioningStatus -eq  "Provisioned" -or $provisioningStatus -eq  "ProvisionedWithoutRegistration")) {
                        Write-Host "Bot synchronization is done." -ForegroundColor Yellow
                        return 1
                    } else {
                        Write-Host "Bot synchronization is in progress." -ForegroundColor Green
                        return 2
                    }
                }
            } else {
                Write-Host "No synchronization status found for bot ID: $botId" -ForegroundColor Red
                return $null
            }
        } catch {
            Write-Host "Failed to retrieve agent ID. Error: $($_)" -ForegroundColor Red
            return $null
        }
    }
    
    
    # Function to provision a PVA bot
    function Provision-Agent {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentId
        )
    
        # Construct the API endpoint for publishing the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($agentId)/Microsoft.Dynamics.CRM.PvaProvision"
    
        try {
            # Make the API call
            Invoke-RestMethod -Method Post -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            Write-Host "Agent Provisioning successfully!" -ForegroundColor Green
            # Add 30 second delay to allow the publish process to complete
            Start-Sleep -Seconds 30
            return $true
        } catch {
            Write-Host "Failed to Provision Agent. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
        return $false
    }
    
    
    # Function to publish a PVA bot
    function Publish-Agent {
        param (
            [string]$DataverseUrl,
            [string]$accessToken,
            [string]$agentId
        )
    
        Write-Host "Publishing agent with ID: $agentId" -ForegroundColor Yellow
    
        # Construct the API endpoint for publishing the bot
        $uri = "$DataverseUrl/api/data/v9.2/bots($agentId)/Microsoft.Dynamics.CRM.PvaPublish"
    
        try {
            # Make the API call
            Invoke-RestMethod -Method Post -Uri $uri -Headers @{
                Authorization = "Bearer $accessToken"
                "Content-Type" = "application/json"
            }
    
            Write-Host "Agent published successfully!" -ForegroundColor Green
            # Add 30 second delay to allow the publish process to complete
            Start-Sleep -Seconds 30
        } catch {
            Write-Host "Failed to publish Agent. Error: $($_.Exception.Message)" -ForegroundColor Red
        }
    }
    
    function Publish-Agents {
        param (
            [string]$accessToken,
            [array]$agentSchemas
        )
    
        if (-not $agentSchemas -or $agentSchemas.Count -eq 0) {
            Write-Host "No agent schemas provided. Skipping agent publishing." -ForegroundColor Yellow
            return
        }
    
        foreach ($agentSchema in $agentSchemas) {
            #Write-Host "Publishing agent schema: $agentSchema" -ForegroundColor Yellow
    
            try {
                    # Construct the API endpoint for publishing the agent schema
                    $agentId = Get-AgentIdBySchemaName -dataverseUrl $DataverseUrl -accessToken $accessToken -agentSchemaName $agentSchema
    
                    if ($agentId -ne $null) {
                        # check for sync errors
                        if ($CheckBotSyncStatusAndProvisionBots) {
                            $syncStatus = Check-BotSyncErrors -dataverseUrl $DataverseUrl -accessToken $accessToken -botId $agentId
                            if (0 -eq $syncStatus) {
                                Write-Host "Agent has sync errors. Skipping the publish process. Please check the bot: $agentId details" -ForegroundColor Red
                                continue
                            } elseif (2 -eq $syncStatus) {
                                Write-Host "Agent synchronization is still in progress. reprovisioning the agent." -ForegroundColor Yellow
                                if (Provision-Agent -dataverseUrl $DataverseUrl -accessToken $accessToken -agentId $agentId -eq $false) {
                                    Write-Host "Agent reprovisioning failed. Skipping the publish process. Please check the bot: $agentId details" -ForegroundColor Red
                                    continue
                                }
                            } else {
                                Write-Host "Agent synchronization is done. Proceeding to publish." -ForegroundColor Green
                            }
                        }
                        # Step 4: Publish the bot
                        Publish-Agent -dataverseUrl $DataverseUrl -accessToken $accessToken -agentId $agentId
                    } else {
                        Write-Host "Agent not found. Cannot proceed with publishing.Skipping the step" -ForegroundColor Yellow
                    }
            }
            catch {
                Write-Host "An error occurred while publishing agent schema: $agentSchema. Error: $_" -ForegroundColor Red
            }
        }
    
    }
    
    
    # Main script execution
    try {
    
        $expenseAIFlows = $flows
        $agentSchemas = $agents
    
        # Step 1: Interactive login to Azure
        Connect-AzAccount -UseDeviceAuthentication
        $accessToken = Get-AccessToken
        $accessTokenPlainText = Get-AccessTokenPlainText -accessToken $accessToken
    
        # Step 2: Setup ennviornment variables
        update_EnvironmentVariablesForExpense -accessToken $accessTokenPlainText 
        Write-Host "Environment variables updated successfully!" -ForegroundColor Green
    
        # Step 3: Check active connections
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftDataverseConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" -connectionReferenceLogicalName "msdyn_sharedcommondataserviceforapps_2c2d4" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftCopilotStudioConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_microsoftcopilotstudio" -connectionReferenceLogicalName "msdyn_sharedmicrosoftcopilotstudio_26d9d" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $Office365OutlookConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_office365" -connectionReferenceLogicalName "msdyn_sharedoffice365_9b471" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $MicrosoftTeamsConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_teams" -connectionReferenceLogicalName "msdyn_sharedteams_8ea9c" -accessToken $accessToken
    
        Set-ConnectionReferenceConnection -userProvidedConnectionName $Office365UsersConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_office365users" -connectionReferenceLogicalName "msdyn_sharedoffice365users_909b9" -accessToken $accessToken
        
    
        # Step 4: Activate flows
        Activate-Flows -accessToken $accessTokenPlainText -expenseAIFlows $expenseAIFlows
    
        # step 5: publish the agents
        Publish-Agents -accessToken $accessTokenPlainText -agentSchemas $agentSchemas
    
        # Step 6: Publish the solution 
        Publish-Solution -accessToken $accessTokenPlainText
    
        Write-Host "Agent setup completed successfully!" -ForegroundColor Green
    
    } catch {
        Write-Host "An error occurred: $_" -ForegroundColor Red
    }
    
    

    PowerShell ファイルをトリガーするには、次の手順に従います。

    1. PowerShell を開きます (必要な最小バージョン - PowerShell 7)。
    2. ファイルを保存した場所に移動します。 (コマンド cd <ファイルの場所> を使用します)
    3. インストール スクリプトをトリガーします。 (コマンド '.\Install.ps1' を使用します)
    4. 指示に従って Azure にサインインします。
    5. サインイン後、もう一度承認する必要がある場合があります。 (作成されたエージェント ユーザー ID を使用します)。

    スクリプトが完全に実行されるまで待ち、エージェントのセットアップが正常に完了したというメッセージを探します。

    上記のスクリプトは、次のアクションを実行します。

    • 環境変数を設定します。
    • 接続参照を検証してリンクします。
    • Power Automate フローを有効にします。
    • 必要な Copilot エージェントを公開します。
    • Dataverse ソリューションを発行します。

    スクリプトが正常に実行されると、経費エージェントが完全に構成され、使用する準備が整います。

    オプション B: Power Apps で手動で設定する (PowerShell なし)

    PowerShell スクリプトを使用しない場合は、Power Apps を使用して Expense Agent を手動で構成できます。 このプロセスには、環境変数の更新、Power Automate フローの有効化、ソリューションの公開が含まれます。

    環境変数の更新

    環境変数を更新するには、次の手順に従います。

    1. Power Apps にログインし、環境を選択します。

    2. ソリューション を選択し、既定のソリューション (またはエージェントがインストールされているソリューション) を開きます。

    3. 環境変数 に移動し、次の値を設定します。

      変数名 説明
      経費エージェントのOutlookフォルダパス 共有メールボックス (既定では 受信トレイ) で監視するフォルダー パスを指定します。
      経費エージェント共有メールボックス アドレス ID 共有メールボックスのメール アドレスを指定します。 サインインしているユーザーのメールボックスを使用するには、NA と入力します。
      財務と運用のインスタンス Url 財務と運用アプリ環境の URL (https://org123.contoso.com など) を指定します。

    Power Automate フローを有効にする

    経費エージェントは、次の Power Automate フローに依存します。

    • 経費入力再試行チェック
    • 経費の構成
    • 経費の Outlook フォルダーを取得する
    • 経費報告書を生成する
    • 経費報告書アダプティブ カードを送信する
    • 経費を自動的にマッチング
    • メールを処理
    • コパイロット呼び出し用のアタッチされていない領収書 ID を抽出する
    • Dataverse プラグインを使用して未添付領収書の出力を抽出する
    • 経費明細行を生成する
    • プロジェクト ID と状態 ID なしで経費明細行を生成する
    • プロジェクト ID を識別する
    • ユーザー カレンダー イベント
    • コパイロットを使用して経費報告書を処理する
    • 領収書処理のために経費エージェントを呼び出す

    フローを有効にするには、次の手順に従います。

    1. Power Automate にサインインし、環境を選択します。

    2. 自分のフローを選択します。

    3. 前の一覧の 15 フローごとに、次の手順を実行します。

      1. フローを見つけます。
      2. [編集] を選択します。
      3. 新しいデザイナー オプションをオフにして、古いデザイナー ビューに切り替えます。
      4. 必要な接続を認証します (緑色のチェック マークが表示されるまで)。
      5. 継続 を選択し、保存 を選択します。
      6. オンにする を選択して、フローを有効にします。

    ソリューションの公開

    すべての環境変数とフローの構成が完了したら、次の手順に従ってソリューションを発行します。

    1. Power Apps で、ソリューション に移動します。
    2. 環境とソリューションを選択します。
    3. すべてのカスタマイズの公開を選択します。

    これらの手順を完了すると、Expense Agent が完全に構成され、使用できる状態になります。

    ステップ 6: Microsoft Teams で経費エージェントを有効にする (オプション)

    Expense Agent の Teams ベースの通信を有効にするには、Power Apps で Teams チャネルをエージェントに追加します。 エージェントは、Teams を介してアダプティブ カードを送信できます。

    Teams チャネルを有効にする

    Teams チャネルを有効にするには、次の手順に従います。

    1. Copilot Studio にサインインし、適切な環境を選択します。
    2. エージェント タブで、経費入力エージェント を選択します。
    3. エージェント ビューの チャネル タブで、 Teams と Microsoft 365 Copilot を選択します。
    4. チャネルの追加 を選択して Teams 統合を有効にし、「Teams アプリの可用性の構成」セクションの手順に従って、アプリを共有するユーザーを構成します。

    詳細については、「Teams + Microsoft 365 チャネルの構成パネルを開く」を参照してください。

    Teams アプリの可用性を構成する

    Teams アプリの可用性を構成するには、次の手順に従います。

    1. Teams アプリが作成されたら、[ 可用性オプション] を選択します。

    2. アプリを共有するユーザーを選択します。

      • 組織内の特定のユーザー
      • 組織全体
    3. 承認のためにアプリを提出します。

    Teams 管理センターでアプリを発行する

    Teams 管理センターでアプリを発行するには、次の手順に従います。

    1. Teams 管理センター にサインインします。
    2. [アプリの管理] > Teams アプリに移動します。 "expense" を検索し、アプリの状態がブロックされている 経費入力エージェント アプリを選択します。
    3. 公開 を選択してアプリのブロックを解除します。 発行アクションが正常に完了したら、アプリの状態がブロック解除に変わります。

    詳細については、「エージェントを Teams と Microsoft 365 に接続して構成する」を参照してください。

    これらの手順を完了すると、 Expense Agent を使用する準備が整います。

    Dynamics 365 Finance 環境内のサムアップ アイコンとサムダウン アイコンとフィードバック ポップアップを使用して、エージェントによって生成された経費明細行とレポートに関するフィードバックを提供することもできます。

    経費エージェントをアンインストールする

    Expense Agent を アンインストール するには、次の手順に従います。

    1. Microsoft Power Apps Maker ポータルにサインインします。
    2. ソリューション を選択し、msdyn_ExpenseAI を検索し、3 つのドットを選択して、削除 を選択します。
    3. msdyn_FnOCopilotAnchorを検索し、ソリューションを削除します。