Claude Media
winget importのキッティング手順書をClaude Codeで再実行可能にする

winget importのキッティング手順書をClaude Codeで再実行可能にする

現行端末のwinget exportから構成ファイルを起こし、手順書と再実行できるPowerShellスクリプトをClaude Codeで作り、検証用VMで2回流して冪等性を確かめる流れをまとめます。

Windows端末のキッティング手順書は、Wordや表計算に手で書くと、次の端末で実際に入っているアプリと食い違いがちです。winget import用の構成ファイル(JSON)を正にして、手順書とセットアップスクリプトをそこから起こせば、この食い違いは構造的に減らせます。この記事では、現行端末から構成ファイルを作り、Claude Codeで手順書とスクリプトを生成し、検証用VMで2回流して冪等性を確かめるまでを順に書きます。

winget exportとimportは何を受け渡すのか

winget exportは端末にインストール済みのアプリ一覧をJSONファイルに書き出し、winget importはそのJSONを読んでアプリをまとめて入れ直します。PCイメージの構築や開発環境の共有に使うコマンドです。

JSONの階層は次のとおりです。

項目内容
Sources内容アプリのマニフェストの取得元
Packages内容インストール対象の集まり
PackageIdentifier内容wingetのパッケージ識別子
Version内容任意。入れるバージョンを固定する場合に使う

importはアプリを1つずつ順番にインストールします。入れられないアプリや、すでに入っているアプリがあった場合は、その旨を表示します。

押さえておく点が2つあります。1つ目は、exportが端末上の全アプリを対象にすることです。wingetのソースに一致するものが見つからないアプリは、警告が出て一覧に入りません。一致の判定にはソース側のマニフェストと、Windowsの「プログラムの追加と削除」にあるメタデータが使われます。2つ目は、Versionが入るのは--include-versionsを付けたときだけで、付けなければimportは最新版を入れることです。

現行端末から構成ファイルを起こす

基準にする端末で、PowerShellから書き出します。

winget export -o apps.json --accept-source-agreements

バージョンを固定したいときは--include-versionsを足します。キッティング直後の状態を全台で揃えたいなら固定、常に最新を入れたいなら付けない、という選び方です。Claude Codeをwinget install Anthropic.ClaudeCodeで入れた場合、WinGet経由のインストールは自動更新されません。固定した版のまま残るので、更新はwinget upgrade Anthropic.ClaudeCodeを手順書の定期作業に書いておく必要があります。

書き出したJSONは、そのまま使わずに編集します。不要なアプリを削ってから使えます。個人用のアプリ、検証で一時的に入れたツール、会社の標準に含めないものを外し、残りを「標準構成」として版管理(Git)に置きます。

取得元を限定して書き出す-s(--source)オプションもあります。wingetソースのアプリだけを標準構成にしたいときに使います。

Claude Codeに手順書の元データを読ませる

構成ファイルができたら、Claude Codeに2つの成果物を作らせます。手順書(Markdown)とセットアップスクリプトです。

apps.json は winget export で作った構成ファイルです。次の3つを行ってください。
1. PackageIdentifier を用途別(開発・業務・ユーティリティ)に分類した表を kitting.md に作る
2. apps.json で入れられない手作業(サインイン、ライセンス入力など)を別の節に分ける
3. apps.json を読んで winget import を実行する kitting.ps1 を作る
実行はせず、ファイルの作成だけにしてください。

「実行はせず」と明示するのは、本番に近い端末でClaude Codeがインストールまで走らせないためです。出力された表は、見た目の整形に頼らず、PackageIdentifierがapps.jsonと1対1で対応しているかをdiffや目視で照合します。Claude Codeが「便利そうなアプリ」を一覧に足していないかを見る作業です。

import用スクリプトの骨格

スクリプトの中心はwinget import1行で、周りに確認抜きで最後まで走るための引数とログを置きます。次はkitting.ps1の例です。

param([string]$Config = "$PSScriptRoot\apps.json")
 
$log = Join-Path $PSScriptRoot ("kitting-{0:yyyyMMdd-HHmmss}.log" -f (Get-Date))
Start-Transcript -Path $log | Out-Null
 
winget import -i $Config `
  --accept-package-agreements `
  --accept-source-agreements `
  --disable-interactivity `
  --no-upgrade `
  --ignore-unavailable
 
Stop-Transcript | Out-Null

各引数の役割は次のとおりです。

引数役割
--accept-package-agreements役割パッケージのライセンス同意のプロンプトを抑える
--accept-source-agreements役割ソースの利用条件の同意プロンプトを抑える
--disable-interactivity役割対話プロンプトを無効にする
--no-upgrade役割すでに入っていれば更新をスキップする
--ignore-unavailable役割入れられないアプリがあってもエラーにしない

--accept-package-agreementsが受け入れるのは、パッケージ自身の使用許諾だけです。インストーラーが勧める同梱ソフトやオプション部品には作用しません。完全にサイレントにしたいときは、winget install側の説明にあるとおり--silentとの併用が前提で、importの引数一覧には--silentがありません。

--ignore-unavailableは、利用者側で見落としにつながる引数でもあります。入らなかったアプリがあってもスクリプトは最後まで進むので、ログで未導入のIDを確認する工程を手順書に残します。

Claude Codeに触らせる範囲を決める

キッティングは端末の状態を変える作業なので、Claude Codeの権限も絞っておきます。WindowsでPowerShellツールが使えるかどうかは構成で変わります。Git for Windowsが入っていないWindowsでは自動で有効になり、入っている場合はclaude.aiやConsoleのアカウントなら既定で有効です。Bedrockなどの経由ではCLAUDE_CODE_USE_POWERSHELL_TOOL=1で有効にします。

PowerShellの権限ルールはBashと同じ形で書けます。次は、読み取り系だけ許可して、アンインストールと削除を拒否する例です。

{
  "permissions": {
    "allow": [
      "PowerShell(winget list *)",
      "PowerShell(winget export *)"
    ],
    "deny": [
      "PowerShell(winget uninstall *)",
      "PowerShell(Remove-Item *)"
    ]
  }
}

Remove-Itemの拒否が実際にどう効くかは、PowerShell Remove-ItemがClaude Codeでブロックされる条件に詳しくあります。

リポジトリのCLAUDE.mdには、作業の約束事を短く書いておきます。

## キッティング作業の規約
- 構成ファイルは apps.json だけを正とし、アプリの増減は JSON の編集で行う
- winget import には --accept-package-agreements と
  --accept-source-agreements と --disable-interactivity を必ず付ける
- スクリプトは同じ端末で2回実行しても追加の変更が出ないこと
- import の実行は検証用VMでのみ行い、本番端末では行わない

検証用VMで冪等性を確かめる

冪等性とは、同じスクリプトを何度流しても結果が同じになる性質です。キッティングでは、途中で失敗して流し直した端末と、一発で通った端末が同じ状態になることを意味します。検証用VMで次の順に確かめます。

手順

検証用VMでの確認手順

  1. 1

    素の状態を保存する

    アプリを何も入れていないVMのスナップショットを取り、いつでも戻せるようにします。

  2. 2

    1回目を流す

    kitting.ps1を実行し、ログとwinget listの結果を保存します。

  3. 3

    2回目を流す

    同じVMで再実行します。2回目のログに「すでにインストール済み」の通知だけが並び、新規インストールが出ないことを見ます。

  4. 4

    途中失敗を再現する

    素の状態に戻し、ネットワークを切って1回目を中断してから、つなぎ直して流し直します。最終的なwinget listが正常な1回目と一致するかを比べます。

  5. 5

    結果をClaude Codeに読ませる

    ログと2つのwinget list出力を渡して、差分と未導入のIDを一覧にさせます。

1回目と2回目の差が出たときは、ログをClaude Codeに読ませて原因を切り分けさせます。たとえば、--no-upgradeを付け忘れて2回目に更新が走った、といった原因が見つかります。

--ignore-unavailableで隠れた未導入IDは、ログとapps.jsonの突き合わせで拾えます。依頼文は次のように、範囲を限って書きます。

kitting-20261013-101500.log と apps.json を読んでください。
apps.json の PackageIdentifier のうち、ログ上でインストールされた形跡も
「すでにインストール済み」の通知も見当たらないものを一覧にしてください。
ファイルは変更せず、一覧と、ログのどの行を根拠にしたかだけを返してください。

一覧に出たIDは、winget searchで今も検索できるかをVMで確かめ、手順書の手作業欄かapps.jsonの修正に回します。

winget importの終了コードの扱いは、importのページに記載がありません。スクリプトの成否を終了コードだけで判定する前に、VMで失敗パターンを作って実際の値を確かめます。

固定した版や取得元で詰まったとき

--include-versionsで版を固定すると、apps.jsonに書かれた版が取得元から後で消える可能性があります。固定した版が取得元に残っているかはimportのページに記載がないので、VMでの実行結果で確かめます。最新版で構わなければ--ignore-versionsを付けると、JSONの版を無視して最新を入れます。固定を保ちたいアプリだけ別のJSONに分ける運用もあります。

同じアプリが複数のソースに一致する場合もあります。ソースが複数設定されていると重複が起きうるので、winget install --id Git.Git -e --source wingetのようにソースを指定して切り分けます。msstoreソースのIDは独自の形式で、XP9KHM4BK9FZ7Qのように英数字の並びになります。標準構成を作るときはexportに-s wingetと-s msstoreを別々に指定して、取得元ごとにJSONを分けておくと、どちらで入れたアプリかが手順書から追えます。

構成ファイルに入らないものを手順書に残す

winget importで再現できるのは、wingetで管理できるアプリだけです。次の作業は手順書に手作業として残します。

  • exportの警告で一覧から漏れたアプリの導入
  • Claude Codeの初回起動とサインイン
  • 部署ごとに違うアプリの追加(このあと説明するとおり、JSONを分ければ手作業は減らせます)

部署ごとのアプリは、共通用のapps.jsonと部署用のapps-sales.jsonのようにJSONを分け、スクリプトでimportを2回呼ぶ構成にできます。kitting.ps1のparamを次のように広げます。

param(
  [string]$Config = "$PSScriptRoot\apps.json",
  [string]$DeptConfig = ""
)
 
foreach ($f in @($Config, $DeptConfig) | Where-Object { $_ }) {
  winget import -i $f `
    --accept-package-agreements --accept-source-agreements `
    --disable-interactivity --no-upgrade --ignore-unavailable
}

部署用を渡すときは.\kitting.ps1 -DeptConfig .\apps-sales.jsonと実行します。共通と部署用で同じIDが重なっても、--no-upgradeがあれば2回目はスキップされるだけです。

Claude Codeを組織で配る場合は、管理設定ファイルで方針を固定する方法があります。Windowsでの置き場所はC:\Program Files\ClaudeCode\managed-settings.jsonで、旧パスのC:\ProgramData\ClaudeCode\managed-settings.jsonは読まれません。配布の考え方はClaude Code組織管理ガイドにまとめています。

Claude Codeのネイティブインストールには管理者権限が要りません。Git for Windowsは任意で、入れるとBashツールとMonitorツールが使えるようになります。この2点は、キッティング対象の標準アプリにGitを含めるかを決める材料になります。

手順書が古くなるのを防ぐ運用

手順書と構成ファイルを別々に更新すると、また食い違います。次の運用にすると、食い違いが出にくくなります。

  • アプリの追加はapps.jsonの編集から始め、kitting.mdの表はClaude Codeに再生成させる
  • 再生成後は、PackageIdentifierの増減だけをコミットの差分で確認する
  • 四半期ごとに基準端末でwinget exportし直し、標準構成との差を見て、意図しない追加を拾う

Ansibleのように構成管理ツールで冪等性を検証する考え方は、Claude CodeでAnsibleのPlaybookを書く手順が参考になります。Windowsのインストール方法そのものはClaude Code Windowsインストールにあります。

まとめ

キッティングの正は手順書の文章ではなく、apps.jsonです。そこから手順書の表とスクリプトを生成し、VMで2回流して差が出ないことを確かめると、手順書は読み物から再実行できる資産に変わります。wingetで入らないものは手作業として手順書に明記し、--ignore-unavailableで隠れた未導入はログで拾います。

この記事を共有:XはてブLinkedIn