🕌

windowsが起動するディスクの作成

2022/12/07に公開

自組PC用にwindowsが起動するディスクを作りたかったり、
他のPCのwindowsが壊れたので、そのPC用に新たにwindowsが起動するディスクを作りたかったり、
する場合に役に立つと思います。

英語で検索してもdiskpartを使う方法ばかり引っ掛かりますが、
diskpartを使わずにpowershellだけで、
パーティションを区切るところから、windowsのインストールまですべて完結できます。

準備

あらかじめMediacreationからなり、なんなりからwindowsのisoファイルは用意されているとします。
windowsのライセンスがなくて、試したいなら、windowsの評価版をダウンロードしましょう。
検証用なので、用途としてはあっているはずです。

当たり前ですが、windowsをインストール用のディスクも用意してください。

windows install用のwimファイル取り出し

windowsのisoファイルをマウントして、sources/install.wimファイルを取り出してください。

このファイルの中にwindowsのimageが圧縮されています。

windowsインストール用ディスクの準備

外部ディスクとしてUSBで接続します。
仮想ディスクを使う場合は、
下記のようにPowershellから仮想ディスクを作っておきます。

# vhdxと拡張子をつけておくと、vhdxでちゃんと作成してくれる
New-VHD -Path .\Desktop\windisk.vhdx -SizeBytes 64GB

作ったディスクをMount-VHDでマウントすると、
通常の物理ディスクと同じように扱うことができます。

Mount-VHD .\Desktop\windisk.vhdx

下のコマンドレットで、どのディスク番号として接続されているか調べてください。
ディスクの容量で区別がつくはずです。

Get-Disk

今後操作用にディスクのオブジェクトを取得しておきます。
$DiskNumをディスク番号に置き換えて実行してください。

Get-disk $DiskNum | Set-Variable Disk

ディスクの初期化

ディスクを初期化します。
もしすでにディスクにOSがインストールされていてマルチブートがしたいなら
この処理は飛ばしてください

まず、offlineにします。

# onlineにしとく。しないとディスクを初期化できない。
Write-Output $Disk | Set-Disk -IsOffline $false 

物理ディスクの場合

# Initializeでいい感じの予約領域のパーティションを作ってくれる。
Write-Output $Disk |
    Clear-Disk -RemoveData -PassThru |
    Initialize-Disk

仮想ディスクの場合

仮想ディスクの場合はClear-Diskが動作しないので、下記のように
直接Initialize-Diskを行います。

もし、仮想ディスクでClear-Diskしたい場合は直接仮想ディスくのファイルを削除してください。

# Initializeでいい感じの予約領域のパーティションを作ってくれる。
Write-Output $Disk |
    Initialize-Disk

パーティションをフォーマット

回復パーティションは今の時代に作る必要あるのか?
という気がしますが、必要と感じるなら作るといいかと。

Format-Volume時の-NewFileSystemLabelですが、実はどんな名前でもちゃんと動きます。

windowsでもwindows11でもwindows11_22h2でも好きな名前にしてください。
今後windowsでマルチブートを行うことも考えるなら、区別がつく名前にしておいたほうがいいです。

efi recovery領域ともにguidが pwshとしてもcsharpとしてもenumで用意されてなく、
swith parameterとしても用意されていないので、guidで指定することになる。
(いやいやpowershellでもcsharpでもその作りおかしいやろ...しょっちゅうguid変わるわけでもないし...)

efi
回復パーティション

ここに各パーティションのGUIDがまとまっています(なぜこんな所にまとめる...)。
New-Parition

windowsのパーティションについては必ず下記指定の順番で作ること。
そうでなくてもwindowsなので気をつけましょうね...

下記のコマンドを実行すると、仮想ディスクの場合は
E:\ is not accessible. The parameter is incorrectのような
エラーウィンドウが出ますが、無視して大丈夫です。

Set-Variable reserved -Scope local -Value "{e3c9e316-0b5c-4db8-817d-f92df00215ae}" -Option Constant
Set-Variable efi -Scope local -Value "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}" -Option Constant
Set-Variable recovery -Scope local -Value "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}" -Option Constant

# 別になくてもよい。
# 上の初期化をしたならすでに作られているので処理は不要。
# 予約領域
Write-Output $Disk |
    New-Partition -Size 500MB -GptType $recovery |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "Recovery patition" |
    Out-Null

# 必須
# System領域
Write-Output $Disk |
    New-Partition -Size 500MB -GptType $efi -AssignDriveLetter |
    Format-Volume -FileSystem FAT32 -NewFileSystemLabel "SYSTEM" |
    Select-Object -ExpandProperty DriveLetter |
    Set-Variable BootDriveLetter -Scope local -Option Constant

# べつに無くてもよい。
# 回復パーティション
Write-Output $Disk |
    New-Partition -Size 500MB -GptType $recovery |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "Recovery patition" |
    Out-Null

# windowsをインストール用のパーティションを作成して、フォーマット。
# new-partition -UseMaximumSizeとするとディスクの残り容量すべてを使う。
Write-Output $Disk | 
    New-Partition -UseMaximumSize -AssignDriveLetter |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel "Windows" |
    Select-Object -ExpandProperty DriveLetter |
    Set-Variable WindowsDriveLetter -Scope local -Option Constant

windowsを展開する

準備して置いたwimを先ほどフォーマットしたNTFSパーティションに展開する。

下のコマンドレットでwindows imageのリストを取得。

Get-WindowsImage -ImagePath .\Desktop\install.wim

先ほどフォーマットしたNTFSパーティションに展開。

# indexが1の場合
Expand-WindowsImage -ImagePath .\Desktop\install.wim -ApplyPath "${WindowsDriveLetter}:\" -Index 1

ディスクがブートするように設定

先ほど設定したEFP領域からwindowsを起動できるように設定します。

Start-Process "${WindowsDriveLetter}:\Windows\System32\bcdboot.exe" `
    -ArgumentList "${WindowsDriveLetter}:\Windows",/s,"${BootDriveLetter}:",/f,UEFI `
    -Confirm `
    -Wait

あとはディスクを外して、他のPCにセットしたらちゃんと起動します。

仮想ディスクの場合は下のようにマウントを解除します。

Dismount-VHD .\Desktop\windisk.vhdx

まとめ

特にdiskpartを使用しなくてもpowershellで全部できることが分かったと
思う。
powershellでやったほうがいいことは検索したらすぐ引っ掛かるようになってほしいな...
googleさんもっと頑張るのだ...!

Discussion