WinPEでのWindows 11セットアップ時にドライブレターが勝手に変わる問題とレター固定のベストプラクティス

WinPEからWindows 11セットアップを自動化すると、毎回ドライブレターの並びが変わってしまい、スクリプトが失敗する――そんな経験はないでしょうか。本記事では、WinPE経由のセットアップで「CATUD → CGDEF」のようにレターが勝手に入れ替わる理由と、その根本対策を、winpeshl.ini と AutoUnattend.xml(応答ファイル)を軸に詳しく解説します。

目次

WinPEでWindows 11セットアップ時にドライブレターが変わる理由

まず、今回の事象を整理します。

  • boot.wim に必要なファイル一式を入れ、WinPE から Windows 11 セットアップを実行した
  • パーティションのドライブレターが、想定していた CATUD ではなく、実際には CGDEF のように変わってしまう
  • その結果、スクリプト内で指定しているドライブレターと実際のドライブレターが合わず、処理に失敗する

この現象の本質は、Windows セットアップ/WinPE 環境における「ドライブレターは固定ではなく動的に割り当てられる」という仕様にあります。

WinPEのドライブレター割り当ての特徴

WinPE と通常のインストール済み Windows では、同じディスク構成でもドライブレターの付き方が変わることがあります。主な理由は次の通りです。

  • デバイスの検出順序(HDD/SSD、USBメモリ、光学ドライブなど)
  • パーティション種別(EFI/MSR/基本/回復/リムーバブルなど)
  • ブート属性やシステムパーティションであるかどうか
  • マウントのタイミング(wpeinit 前後など)

さらに、WinPE では通常 X: が RAM ディスクとして予約されるため、C: から順番に割り振られるとは限りません。結果として、

  • WinPE 中:D: が OS 用パーティション、E: がデータ用、F: が別ディスク…
  • インストール後:C: が OS、D: がデータ…

のように、セットアップ中とインストール後でドライブレターが一致しない状況が普通に発生します。

環境典型的なシステムドライブドライブレターの安定性
WinPE(boot.wim 起動)X:(RAMディスク)低い(毎回変わり得る)
インストール後のWindows 11C:(OSパーティション)比較的高い(C: はほぼ固定)

このため、「WinPE上で C ドライブだったから、本番 Windows でも C になるはずだ」といった期待は、基本的に成り立ちません。

なぜ「CATUD → CGDEF」のような変化が起きるのか

今回のように、CATUD という順番でレターを決めたつもりが、実際には CGDEF になってしまうケースでは、次のような要素が影響していることが多いです。

  • USB メモリや別ディスクが先にマウントされ、想定より早いレターを奪う
  • 光学ドライブ(物理/仮想)が D: を取りに来る
  • 以前のアサインが残っていて、DiskPartの assign letter= が失敗している
  • wpeinit 前にスクリプトを走らせてしまい、まだボリュームが出揃っていない

つまり、OS任せにしている限りレターは「勝手に変わる」ものであり、スクリプトで確実に扱いたければ、こちらから明示的にルールを押し付ける必要があるということです。

対策の全体像:3つのアプローチ

WinPE 経由の Windows 11 セットアップでドライブレター問題を回避するための代表的なアプローチは次の3つです。

  • winpeshl.ini または startnet.cmd からスクリプトを起動し、セットアップ前にレターを強制割り当て
  • AutoUnattend.xml(応答ファイル)の DiskConfiguration / ModifyPartition でレターを指定
  • そもそもスクリプトを「ドライブレターに依存しない構造」にする
方法実装場所メリット向いているケース
WinPEスクリプトwinpeshl.ini / startnet.cmd手軽、メディア単体で完結カスタムWinPEメディアを配布している場合
応答ファイルAutoUnattend.xml(windowsPE パス)構成の一元管理がしやすい既に応答ファイル運用をしている環境
レター非依存設計スクリプト本体環境差に強く、長期運用向き多数拠点・長期運用を前提とする企業環境

実務的には、

  • パーティションの作成とラベル付けは AutoUnattend.xml で行う
  • WinPE 起動直後に winpeshl.ini からラベルに基づいてレターを再割り当てする

という二段構えが、管理しやすく再現性も高い構成です。

winpeshl.iniでセットアップ前にドライブレターを固定する

もっとも分かりやすい対策は、boot.wim 内にスクリプトと winpeshl.ini を配置し、setup.exe を起動する前にレターを決め打ちする方法です。

boot.wim をマウントしてスクリプトを配置する

作業用PC(管理端末)で、以下のように boot.wim をマウントします。

REM 作業用フォルダは環境に合わせて変更
dism /Mount-Wim /WimFile:C:\WinPE\media\sources\boot.wim /Index:1 /MountDir:C:\Mount

mkdir C:\Mount\Windows\System32\Scripts
copy C:\Work\SetDriveLetters.cmd C:\Mount\Windows\System32\Scripts\

notepad C:\Mount\Windows\System32\winpeshl.ini

ここでは例として、DiskPart ベースの SetDriveLetters.cmd を配置するものとします。

winpeshl.ini の例:wpeinit → スクリプト → setup.exe の順で起動

WinPEでは通常、X: がシステムドライブとしてマウントされます。
winpeshl.ini には次のように記述します。

[LaunchApps]
wpeinit
X:\Windows\System32\Scripts\SetDriveLetters.cmd
X:\setup.exe
  • 1 行につき 1 コマンド
  • wpeinit でデバイス初期化 → スクリプト実行 → Windows セットアップの流れ
  • スクリプト内でドライブレターを CATUD など目的の配列に整えてから、setup.exe を起動

DiskPart版スクリプト:パーティション番号ベースでレターを付ける

もっともシンプルなのが DiskPart スクリプトです。

SetDriveLetters.cmd(例)

@echo off
diskpart /s X:\Windows\System32\Scripts\letters.txt

letters.txt(例:Disk 0 の Part.1〜5 を C A T U D に割り当て)

select disk 0

select partition 1
assign letter=C

select partition 2
assign letter=A

select partition 3
assign letter=T

select partition 4
assign letter=U

select partition 5
assign letter=D

注意点:

  • 実際の構成に合わせて「どのパーティションにどのレターを振るか」を調整する
  • UEFI構成では、EFI/MSR/回復用パーティションには通常レターを付けないほうが良い
  • 既に他デバイスが同じレターを使用している場合、assign が失敗するため、先に別レターに退避させる等の工夫が必要

PowerShell版スクリプト:ボリュームラベル基準で割り当てる

より堅牢な方法は、ボリュームラベルで対象を特定してレターを振り直すやり方です。これにより、パーティション番号やディスク順序が多少変わっても耐えられます。

前提:

  • WinPE イメージに WinPE-PowerShell コンポーネントを追加していること(ADK で追加)

X:\Windows\System32\Scripts\SetDriveLetters.ps1(例)

$map = @{
  'OS'   = 'C'  # ラベル "OS" のボリューム → C:
  'APPS' = 'A'
  'TEMP' = 'T'
  'USER' = 'U'
  'DATA' = 'D'
}

foreach ($kv in $map.GetEnumerator()) {
    $label = $kv.Key
    $letter = $kv.Value

    $vol = Get-Volume -FileSystemLabel $label -ErrorAction SilentlyContinue
    if ($null -eq $vol) {
        Write-Host "Volume with label $label not found." 
        continue
    }

    $part = $vol | Get-Partition
    Set-Partition -DiskNumber $part.DiskNumber -PartitionNumber $part.PartitionNumber -NewDriveLetter $letter -ErrorAction Stop
    Write-Host "Assigned $letter: to volume $label"
}

このスクリプトを winpeshl.ini から呼び出す例は次の通りです。

[LaunchApps]
wpeinit
powershell.exe -ExecutionPolicy Bypass -File X:\Windows\System32\Scripts\SetDriveLetters.ps1
X:\setup.exe

ポイント:

  • 応答ファイルや別スクリプトで、事前に各パーティションにラベル(OS/APPS/USER/DATA など)を付けておく
  • スクリプトは「ラベル → レター」のマッピングだけを担当するので、構成変更に強い
  • ログを X:\logs\drive-letter.log のように出力しておくと検証が楽

boot.wim を閉じて変更を確定する

編集が終わったら、boot.wim をアンマウントします。

dism /Unmount-Wim /MountDir:C:\Mount /Commit

これで、作成した WinPE メディアから起動すると、setup.exe が動き出す前にドライブレターが期待通りにそろうようになります。

AutoUnattend.xml(応答ファイル)でドライブレターを制御する

既に応答ファイル(AutoUnattend.xml)でディスク構成を管理している環境では、windowsPE パスの DiskConfiguration / ModifyPartition でレターを指定する方法も有効です。

以下は構造イメージです(実際の XML では名前空間や wcm 属性などが必要です)。

<unattend>
  <settings pass="windowsPE">
    <component name="Microsoft-Windows-Setup">
      <DiskConfiguration>
        <Disk wcm:action="add">
          <DiskID>0</DiskID>
          <WillWipeDisk>true</WillWipeDisk>

          <ModifyPartitions>
            <ModifyPartition wcm:action="add">
              <Order>1</Order>
              <PartitionID>3</PartitionID>   <!-- 例:OS パーティション -->
              <Label>OS</Label>
              <Letter>C</Letter>
              <Format>NTFS</Format>
            </ModifyPartition>

            <ModifyPartition wcm:action="add">
              <Order>2</Order>
              <PartitionID>4</PartitionID>   <!-- データ用パーティション -->
              <Label>DATA</Label>
              <Letter>D</Letter>
              <Format>NTFS</Format>
            </ModifyPartition>
          </ModifyPartitions>
        </Disk>
      </DiskConfiguration>

      <RunSynchronous>
        <RunSynchronousCommand wcm:action="add">
          <Order>1</Order>
          <Path>cmd /c X:\Windows\System32\Scripts\SetDriveLetters.cmd</Path>
        </RunSynchronousCommand>
      </RunSynchronous>

    </component>
  </settings>
</unattend>

ポイント:

  • windowsPE パスで DiskConfiguration を設定すると、インストール開始前にディスク構成が確定する
  • OSパーティション(C:)、データパーティション(D:)など、基本レターをここで決めておくと分かりやすい
  • それでも WinPE 中の一時的なレターが気になる場合は、RunSynchronous からスクリプト(SetDriveLetters.cmd)を呼び出して再調整する

応答ファイルでレターを制御する際の注意点

  • WillWipeDisk=true の指定は、既存データが削除されるため本番環境に適用する前に必ず検証環境でテストする
  • PartitionID は CreatePartitions の定義と対応している必要がある
  • EFI/MSR/回復パーティションには通常レターを割り当てない(トラブルの元になる)
  • OSパーティションは基本的に C: にしておくことで後工程の運用が楽になる

winpeshl.ini と AutoUnattend.xml、どちらに書くべきか

「どこに書くのが正解か?」という問いに対しては、用途によって使い分けるというのが実務的な答えになります。

観点winpeshl.iniAutoUnattend.xml
適用タイミングWinPE起動直後セットアップ処理(windowsPEパス)
構成管理メディア単位(boot.wimごと)XMLファイルで一元管理しやすい
変更のしやすさboot.wim の再マウントが必要XML を差し替えるだけでよい場合が多い
おすすめ用途簡易ツール、単独メディア運用企業内標準イメージ、長期運用

まとめると、

  • メディア単体で完結させたい・構成がシンプル → winpeshl.ini で [LaunchApps] に記述
  • 既に応答ファイルでディスク設計を管理している → AutoUnattend.xml の windowsPE/RunSynchronous からスクリプトを呼ぶ

いずれの場合も、ゴールは同じで、「setup.exe を動かす前にドライブレターを確定させる」ことです。

スクリプト設計のベストプラクティス

ドライブレター問題を根本から安定させるには、スクリプト側の設計も重要です。以下のポイントを押さえておくと、環境差に強い構成になります。

ドライブレターに過度に依存しない

  • 対象ボリュームの指定は、パーティション番号やレターではなく、ラベルや GPT タイプ、Volume GUID で行う
  • 最終的にユーザーが使うドライブレターだけを、最後に Set-Partition -NewDriveLetter で付与する

例えば、PowerShell から GPT タイプで OS パーティションを見つけて C: にする、というようなアプローチも可能です(例は簡略版)。

$osPart = Get-Partition | Where-Object {
    $_.GptType -eq "{EBD0A0A2-B9E5-4433-87C0-68B6B72699C7}" -and
    $_.IsBoot -eq $true
}

if ($null -ne $osPart) {
    Set-Partition -DiskNumber $osPart.DiskNumber -PartitionNumber $osPart.PartitionNumber -NewDriveLetter "C"
}

A/B ドライブは特別扱いに注意

  • 最新の Windows では A: / B: にもレターを割り当て可能ですが、古いツールやスクリプトがフロッピーディスクを想定していることがあります
  • 業務利用では、C/D/E… の一般的な並びを使う方がトラブルが少ない

光学ドライブとの競合を考慮する

  • 物理/仮想の光学ドライブは、よく D: を取りに来ます
  • データ用パーティションを D: にしたい場合は、光学ドライブのレターを先に Z: などに退避させると安定します
select volume <光学ドライブのボリューム番号>
assign letter=Z

EFI/MSR/回復パーティションにはレターを付けない

  • これらのパーティションにドライブレターを付けると、誤操作で中身を消してしまうリスクが高まります
  • 通常は「レターなし」が正解です。どうしても必要なときだけ、一時的に付与して作業後に削除するようにします。

ログ出力とエラー処理を入れておく

  • スクリプトのログを X:\Logs\ やインストール先ディスク上に出力すると、原因調査が圧倒的に楽になります
  • PowerShell では -ErrorAction Stop と try / catch を組み合わせ、失敗時にメッセージを残すようにしておきましょう

トラブルシューティング:思った通りにレターが付かない場合

「CATUD のはずが CGDEF になってしまう」といった場合、次の手順で原因を切り分けます。

WinPE 上で DiskPart の状況を確認する

WinPE のコマンドプロンプトから、以下を順番に実行します。

diskpart
list disk
list volume
list partition
  • どのディスク/ボリュームにどのレターが付いているか
  • EFI/回復パーティションにレターが付いてしまっていないか
  • 光学ドライブや USB が想定外のレターを確保していないか

を確認します。

スクリプトが実際に実行されているか確認する

  • winpeshl.ini のパスやファイル名の typo がないか
  • PowerShell スクリプトの場合、ExecutionPolicy でブロックされていないか
  • ログファイルが出力されているか(出ていなければそもそも呼ばれていない可能性)

テストとして、WinPE 上で手動で以下を実行し、同じ結果になるかを確認するのも有効です。

X:\Windows\System32\Scripts\SetDriveLetters.cmd
REM もしくは
powershell.exe -ExecutionPolicy Bypass -File X:\Windows\System32\Scripts\SetDriveLetters.ps1

AutoUnattend.xml の DiskConfiguration を見直す

  • PartitionID と実際のパーティション番号の対応が崩れていないか
  • 複数ディスク環境で DiskID の指定が期待通りか
  • ModifyPartitions の Order が重複していないか

構成変更のたびに PartitionID がずれてしまうようであれば、構成をシンプルに整理するか、ラベルベースのスクリプトへ寄せることを検討してください。

実運用でのおすすめ構成例

中〜大規模環境での運用を想定して、現実的な構成例を示します。

パーティション構成の一例(UEFI/GPT)

順番用途サイズ目安ラベル例最終レター備考
1EFI システム100〜300MBEFIなしブート用、レター不要
2MSR16MBMSRなしレター不要
3OS100GB〜OSC:Windows 11 本体
4データ残り全てDATAD:ユーザーデータ・アプリデータ
5回復500MB〜1GBRecoveryなしレター不要

構成例:AutoUnattend.xml + winpeshl.ini の二段構え

  • AutoUnattend.xml で上記のようなパーティション構成とラベルを定義
  • WinPE 起動時に winpeshl.ini の [LaunchApps] から PowerShell スクリプトを起動
  • スクリプトは「ラベル → レター」のマッピング(OS→C, DATA→D…)だけを行う

こうすることで、

  • ディスク容量や構成の変更は AutoUnattend.xml を修正
  • レターの割り当てルールの変更は PowerShell スクリプトを修正

と、役割を分離して管理しやすくなります。

まとめ:WinPEではドライブレターは「勝手に変わる」前提で設計する

本記事で扱ったポイントを改めて整理します。

  • WinPE/セットアップ環境では、ドライブレターは環境や起動ごとに変動するのが前提仕様
  • 「CATUD → CGDEF」のような変化は珍しいことではなく、OS の挙動として正しい範囲
  • ドライブレターを安定させるには、setup.exe を起動する前に、スクリプトで明示的にレターを割り当てる必要がある
  • その実装場所として、winpeshl.ini と AutoUnattend.xml(RunSynchronous) が選択肢になる
  • スクリプトの内部では、レターよりラベル/GPTタイプ/Volume GUID で対象を特定する設計が再現性が高い
  • インストール後には、ディスクの管理や DiskPart で最終的なレターを確認し、必要に応じて光学ドライブなどとの競合を解消する

この流れを組んでおけば、質問にあったような任意のレター配列(CATUD など)でも、WinPE 経由の Windows 11 自動展開で安定して再現できるようになります。ドライブレターを「たまたま」ではなく、「設計どおり」に制御できるようになれば、その上に乗るスクリプトや運用も大幅にシンプルになるはずです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次