force-link-environment について
Power Platform Pipelines の環境を別のホストへ移行する管理者向けスキルです。移行先の関連付けを検証し、スタンプ移動前に確認を求めます。移行後は旧ホスト経由のパイプラインにアクセスできなくなります。
主な機能
- 01移行先ホストとソース環境の特定
- 02ホスト環境レコードの検索または作成
- 03Force Link の実行と検証ポーリング
- 04ホスト間移行前の確認
- 05結果マーカーと概要の記録
活用シーン
- 01環境の新しい Pipelines ホストへの移行
- 02別ホストに関連付け済みというエラーの解消
- 03ホスト関連付けの成功確認
MCP 対応
Dataverse を呼び出す前に、MCP ツールで Microsoft Learn のドキュメントを取得し、最新のガイダンスを手順に反映します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ power-platform-skills --skill force-link-environmentインストール後、Claude Code で/force-link-environmentを入力して読み込まれたか確認します。
同梱ファイルscripts/validate-force-link.js
詳細
プラグインの確認:
node "${PLUGIN_ROOT}/scripts/check-version.js"を実行します。メッセージが出力された場合は、続行する前にユーザーに表示してください。
force-link-environment
開発環境またはターゲット環境の Power Platform Pipelines ホストとの関連付けを、あるホストから別のホストへ移動します。deploymentenvironments の作成時に "this environment is already associated with another pipelines host" というエラーが発生した場合に推奨される修正方法です。また、環境を意図的に別のホストへ移行する際にも適したツールです。
Microsoft Learn(信頼できる情報源): Force Link を使用して環境を新しいホストに関連付ける
このスキルが変更する内容
ターゲットホスト(ユーザーが新たに使用するホスト)では:
- 既存の
deploymentenvironmentsレコードを、BAP 環境のアクティブなスタンプとしてマークします。 - 検証を再実行します。成功すると、
validationstatusはSucceeded(200000001)に切り替わります。
以前のホスト(環境が以前にリンクされていたホスト)では:
- 対応する
deploymentenvironments行のリンクが解除されます。validationstatusは以前のホストの UI で更新されるまで古いままです。 - 以前のホストで、その環境を通じてパイプラインを実行できたメーカーは、その環境経由でのパイプラインへのアクセスを失います。
以前のホストから Force Link を再度実行すれば、この操作を元に戻せます。
フェーズ 1.5 — Microsoft Learn による根拠の確認(必須)
Dataverse を呼び出す前に、上記のドキュメントを mcp__plugin_power-pages_microsoft-learn__microsoft_docs_fetch で取得して、エージェントの根拠情報を更新してください。ドキュメントに動作の変更(新しい権限要件や警告文など)がある場合は、続行する前にユーザーに伝えてください。共通の手順については ${PLUGIN_ROOT}/references/alm-docs-grounding.md を参照してください。
フェーズ
| # | フェーズ | 出力 |
|---|---|---|
| 1 | 前提条件 | ホスト環境用の Azure CLI トークン、認証済み PAC CLI |
| 1.5 | MCP Learn による根拠の確認 | Force Link/ManageEnvironmentStamp の現在の動作を確認 |
| 2 | ホストと開発環境の特定 | hostEnvUrl、ターゲットホストの deploymentEnvironmentId、ソース BAP 環境 GUID |
| 3 | deploymentenvironments レコードの特定 | 新しいホスト上の既存レコード、または新規作成したレコード |
| 4 | 破壊的な操作の確認 | AskUserQuestion による明示的なユーザーの同意 |
| 5 | Force Link の実行 | ManageEnvironmentStamp からの 204 と、事後検証での Succeeded |
| 6 | マーカーの書き込みと概要の作成 | docs/alm/last-force-link.json と人が読める概要 |
フェーズ 1 の開始時に TaskCreate ですべてのタスクを作成してください。各タスクは、開始時に in_progress、完了時に completed に設定してください。
フェーズ 1 — 前提条件
共通の検証ツールを再利用してください。
node "${PLUGIN_ROOT}/scripts/lib/verify-alm-prerequisites.js"
特に以下が必要です。
- PAC CLI 認証 —
pac env whoで認証済みの環境が表示される必要があります(--dev-envの自動検出に使用)。 - Azure CLI 認証 —
az account showが成功する必要があります。 - ホストスコープのトークン — 呼び出し元はターゲットホスト(環境のリンク先となるホスト)の Deployment Pipeline Administrator である必要があります。この権限がない場合、
ManageEnvironmentStampは 403 を返します。
ホストの Dataverse URL をリソースとして指定し、Azure CLI からホストトークンを取得してください。scripts/lib/validation-helpers.js の getAuthToken を再利用してください。
フェーズ 1.5 — MCP Learn による根拠の確認
以下を呼び出してください。
mcp__plugin_power-pages_microsoft-learn__microsoft_docs_fetch(url=
"https://learn.microsoft.com/en-us/power-platform/alm/custom-host-pipelines")
続行する前に、"Force Link を使用して…" セクションの現在の警告を確認してください。スキルに記載されていない新しい前提条件やロールバック上の制約がセクションに追加されている場合は、ユーザーに伝えてください。
フェーズ 2 — ホストと開発環境を特定する
🚦 ゲート(計画 · force-link-environment:2.host-url): 引数/マーカーによる解決方法ですべて値が見つからなかった場合、対象のホスト環境 URL を選択します。「
--host引数なし、last-host-check.jsonなし、last-pipeline.jsonなし」の分岐(以下のステップ 4)でのみ実行されます。トリガー: フェーズ 2 の解決順序のステップ 1~3 ですべて値が見つかりませんでした。 確認する理由: 誤ったホストを自動選択すると、
ManageEnvironmentStampが誤ったテナントに対して実行され、同意なくスタンプが元に戻せない形で移動されます。 キャンセルした場合: 何も起こりません。API 呼び出しはまだありません。
🚦 ゲート(計画 · force-link-environment:2.dev-env):
--dev-env引数がなく、pac env whoでも確認できなかった場合、ソース開発環境の BAP 環境 GUID を選択(または貼り付け)します。「引数なし + 確認なし」の分岐(以下のステップ 3)でのみ実行されます。トリガー: フェーズ 2 の BAP GUID 解決ステップ 1~2 ですべて値が見つかりませんでした。 確認する理由: 誤った開発環境を自動選択すると、別の環境が新しいホストに再リンクされ、誤った環境の作成者がパイプラインにアクセスできなくなります。 キャンセルした場合: 何も起こりません。API 呼び出しはまだありません。
hostEnvUrl の解決順序:
- 指定されている場合は、
--host <url>引数。 docs/alm/last-host-check.json(ensure-pipelines-hostによって書き込まれます)。finalHostEnvUrlを読み取ります。docs/alm/last-pipeline.json。hostEnvUrlを読み取ります。AskUserQuestionを使ってユーザーに確認します。
ソース開発環境の BAP 環境 GUID の解決順序:
- 指定されている場合は、
--dev-env <guid>引数。 pac env who(現在の PAC CLI 環境)。ただし、再リンクする環境がこれであることをユーザーが確認した場合のみです。AskUserQuestionを使ってユーザーに確認します。
フェーズ 3 — 新しいホスト上の deploymentenvironments レコードを解決する
このフェーズの目標: レコードがすでに存在する場合、新たに作成された場合、または Failed 状態で作成された場合のいずれであっても、deploymentEnvironmentId(新しいホストのレコード ID)を取得します。この GUID がなければ、フェーズ 5 の Force Link を実行できません。
ステップ 3.1 — BAP 環境 GUID で検索する
GET {hostEnvUrl}/api/data/v9.1/deploymentenvironments?$filter=environmentid eq '{bapEnvId}'&$select=deploymentenvironmentid,name,environmenttype,validationstatus,errormessage
| 結果 | アクション |
|---|---|
1 件ヒットし、validationstatus = 200000001(Succeeded) | すでにこのホストにリンクされています。何も行わない旨の要約を示してフェーズ 6 に進みます。Force Link は不要です。 |
1 件ヒットし、validationstatus = 200000002(Failed) | これは「すでに別のパイプラインホストに関連付けられている」状態です。deploymentenvironmentid と errormessage を取得します。それらの値を使ってフェーズ 4 に進みます。 |
1 件ヒットし、validationstatus = 200000000(Pending) | 少し待って(3~5 秒)から再検索します。約 20 秒経過しても Pending の場合は、「検証がまだ進行中です。後でもう一度お試しください」というメッセージを表示して中止します。 |
| 0 件ヒット | ステップ 3.2 に進みます。まずレコードを作成する必要があります。 |
ステップ 3.2 — 新しいホストにレコードを作成する(ステップ 3.1 の結果が 0 件だった場合)
node "${PLUGIN_ROOT}/scripts/lib/create-deployment-environment.js" \
--hostEnvUrl <hostEnvUrl> \
--token <hostToken> \
--name "<display name>" \
--bapEnvId <bapEnvId> \
--environmentType <200000000|200000001>
ヘルパーは validationstatus をポーリングし、Failed の場合は、新しいレコードの GUID をエラーペイロードに含めずに例外をスローします。対処すべき結果は 3 つあります。
| ヘルパーの結果 | 対応 |
|---|---|
validationStatus = Succeeded で解決する | レコードは完全にリンクされています。フェーズ 6 に進みます。Force Link は不要です。 |
| 「already associated with another pipelines host」(または同様のホストの所有権に関する文言)を含むメッセージで例外がスローされる | レコードは Failed 状態で作成されていますが、ヘルパーのエラーに新しい GUID が表示されません。ステップ 3.1 の GET を再実行して、作成されたばかりのレコードの deploymentenvironmentid を取得し、その ID と取得した errormessage を使ってフェーズ 4 に進みます。作成を再試行してはいけません。name が重複して記録されます。 |
| その他のメッセージで例外がスローされる | エラーをそのまま表示して中止します。Force Link は適切な対処法ではありません。これは別の失敗です(例:作成時の 403 = 呼び出し元にホスト上のロールがない、400 = bapEnvId が不正)。 |
再クエリが必要な理由: create-deployment-environment.js は、以降の呼び出しでは冪等に動作し(findExistingByBapId によって処理を早期終了します)、最初の呼び出しで検証結果が Failed になった場合は、戻り値を返す前に例外を発生させます。environmentid eq '{bapEnvId}' で再クエリするのが標準的な復旧方法です。これはステップ 3.1 で使ったものと同じクエリです。
このフェーズの終了時には、null ではない deploymentEnvironmentId を保持している必要があります。取得できていない場合は、「新しいホスト上のレコードを解決できませんでした」という明確なメッセージを表示してフェーズ 4 を中止してください。
フェーズ 4 — 破壊的操作の確認
🚦 ゲート(同意 · force-link-environment:4.destructive):
ManageEnvironmentStampによるホスト間のスタンプ移動の前に、必ず同意を取得します。移動すると、以前のホストはこの環境のパイプラインアクセスを失います。以前のホストから Force Link を再実行することでのみ元に戻せます。スキルを呼び出すたびに、毎回新たに確認します。 1 回の呼び出しで Force Link するのは、1 つのホスト上の 1 つの環境のみです。複数の環境をホスト間で移行する必要があるメーカーは、環境ごとにこのスキルを呼び出します。呼び出しごとに、その環境の情報を明示した個別の同意プロンプトが必要です。--yesフラグ、バッチモード、同意の引き継ぎはありません。
これは必須のゲートです。両方の選択肢と、破壊的操作についての明確な警告を質問文に含めて、AskUserQuestion を使ってください。質問する前に、次の必須情報を表示してください。
- 対象ホスト(新しいホスト)
- ソース環境の名前と BAP 環境 GUID
- 以前のホストのスタンプに関するエラーメッセージ(フェーズ 3 から取得したもの。存在する場合)
- 文書化されている副作用:
- 「以前のホストのメーカーは、この環境のパイプラインアクセスを失います」
- 「以前のホストの環境レコードには、古い検証ステータスが残ります」
- 「以前のホストから Force Link を実行すれば元に戻せます」
質問の構成:
question: "Force-link this environment to <host name>? This will remove its association with the previous host."
options:
- "Yes — force link" (Recommended only if user is intentionally migrating)
- "Cancel"
ユーザーがキャンセルを選択した場合は、問題なく終了し(マーカーファイルは書き込みません)、さらに診断を行うには /power-pages:ensure-pipelines-host detect-only を推奨してください。
フェーズ 5 — Force Link の実行
node "${PLUGIN_ROOT}/scripts/lib/force-link-environment.js" \
--hostEnvUrl <hostEnvUrl> \
--token <hostToken> \
--deploymentEnvironmentId <guid>
ヘルパーは次の処理を行います。
ManageEnvironmentStampを呼び出します(成功時は 204 No Content を返します)。- 同じレコードの
validationstatusを 3 秒ごとに最大 20 回、再ポーリングします。 - Succeeded(200000001)の場合は解決し、Failed(200000002)の場合は取得済みの
errormessageを含めて例外をスローします。
ステータス 403 でヘルパーが例外をスローした場合、呼び出し元に対象ホストの Deployment Pipeline Administrator ロールがありません。その旨を対処方法のメッセージとして表示してください。
ステータス 404 でヘルパーが例外をスローした場合、対象ホストに deploymentenvironments レコードがありません。フェーズ 3 が通知なく失敗したはずなので、ループバックしてください。
フェーズ 6 — マーカーと概要の書き込み
docs/alm/ ディレクトリが存在することを確認し(node -e "require('fs').mkdirSync('docs/alm',{recursive:true})")、その後 docs/alm/last-force-link.json を書き込みます。
{
"schemaVersion": 1,
"hostEnvUrl": "https://...",
"deploymentEnvironmentId": "...",
"bapEnvId": "...",
"previousHostEnvUrl": "https://...",
"validationStatus": 200000001,
"forcedAt": "2026-05-11T..."
}
previousHostEnvUrl はベストエフォートで設定します。次の順序で導出し、いずれからも値を取得できない場合は null のままにします。
docs/alm/last-host-check.jsonから(ensure-pipelines-hostによって書き込まれます):finalHostEnvUrlが設定されていて、現在のhostEnvUrlと異なる場合、検出フローですでにこの環境がその以前のホストにバインドされていたことを示すため、その値を記録します。- フェーズ 3 の errormessage から:取得した
errormessageを調べ、パターンhttps?://[^\s'"]+\.(crm\d*\.dynamics\.com|dynamics-int\.com|crm\.microsoftdynamics\.us)に一致し、現在のhostEnvUrlではない最初の値を選びます。「すでに関連付けられている」場合の Microsoft のエラー文には、以前のホストの URL が含まれることもあれば、表示名のみの場合もあります。この正規表現は参考として使用し、確定的なものとして扱わないでください。 - それ以外の場合:
nullのままにします。このマーカーのスキーマでは許可されており、バリデーターはこのフィールドを必須としていません。
previousHostEnvUrl の入力をユーザーに求めてはいけません。これは実行後の概要に表示する情報にすぎません。
次の内容を含む概要テーブルを提示します。
- 強制リンクされた環境
- 以前のホスト → 新しいホスト
- 検証ステータス
- リマインダー:「以前のホストから
/power-pages:force-link-environmentを実行すると、元に戻せます。」
${PLUGIN_ROOT}/references/skill-tracking-reference.md に従ってスキルの使用状況を記録します。
失敗モードと対処方法
| 失敗 | ユーザーへの表示 | 次のステップ |
|---|---|---|
ManageEnvironmentStamp で 403 Forbidden | 「 の Deployment Pipeline Administrator ロールが必要です。」 | ホスト管理者にロールの付与を依頼します。詳細はパイプライン管理者との共有に記載されています。 |
デプロイ環境レコードで 404 Not Found | 「このホストには deploymentenvironments レコードがまだありません。」 | フェーズ 3 の作成手順を再実行します。 |
| リンク後の検証ステータスが Failed に変わる | errormessage をそのまま表示します。 | メッセージに環境がまだホストに関連付けられていると記載されている場合、以前のホストに即時再適用ポリシーが設定されている可能性があります。以前のホストの管理者に確認してください。 |
| ユーザーがフェーズ 4 でキャンセルする | 「強制リンクは実行されませんでした。以前の関連付けは維持されています。」 | より広範な診断を行うには、/power-pages:ensure-pipelines-host detect-only を提案します。 |
このスキルで行わないこと
- 新しいホストへの Pipelines アプリケーションのインストールは行いません。その場合は
/power-pages:ensure-pipelines-hostを使用します。 - 新しいホスト環境自体は作成しません。
- パイプライン定義の再リンクは行いません。移動するのは env↔host のスタンプのみです。以前のホストでこの環境を参照していたパイプラインはそこに残り、この環境を参加環境として使用できなくなります。
- ユーザーのソリューションは変更しません。
.solution-manifest.jsonの更新も、AddSolutionComponentの呼び出しも行いません。
進捗状況
| フェーズ | ステータス |
|---|---|
| 1 — 前提条件 | ⏳ |
| 1.5 — MCP Learn による根拠の確認 | ⏳ |
| 2 — ホストと開発環境の特定 | ⏳ |
| 3 — deploymentenvironments レコードの解決 | ⏳ |
| 4 — 破壊的操作の確認 | ⏳ |
| 5 — Force Link の実行 | ⏳ |
| 6 — マーカーと概要の書き込み | ⏳ |
フェーズの完了に合わせて、このテーブルを更新します。