2022年11月23日水曜日

Win11のブートOS選択タイムはわずか0.05秒に過ぎない。ではOS選択プロセスをもう一度見てみよう。

ずっと前に宇宙刑事の蒸着並みに素早く PC をシャットダウン,再起動等できるスクリプトを作って使用していたが,これに OS 選択・ブートデバイス選択・UEFI セットアップ起動 機能を付けたら便利だと思った.
で,やってみる.以下のコマンドはほとんど管理者モードでしか機能しないので注意.

●boot デバイスの選択
bcdedit /enum all の「ファームウェアのブート マネージャー」にブート可能なデバイスの ID 一覧が列挙されている.その ID が具体的に何なのかは,description を見ればだいたい分かる.

C:\Users\yoshi>bcdedit /enum all

ファームウェアのブート マネージャー
--------------------------------
identifier              {fwbootmgr}
displayorder            {f1255e61-6696-11ed-bf20-806e6f6e6963}
                        {c16a79f0-67b4-11ed-bf38-806e6f6e6963} ---+
                        {0d22d0c4-5a00-11ed-bed1-806e6f6e6963}    |
                        {f5f177c6-6ad7-11ed-bf4c-806e6f6e6963}    |
                        {f5f177c7-6ad7-11ed-bf4c-806e6f6e6963}    |
                        {f5f177c8-6ad7-11ed-bf4c-806e6f6e6963}    |
timeout                 0                                         |
                                                                  |
ファームウェア アプリケーション (101fffff                         |
--------------------------------                                  |
identifier              {0d22d0c4-5a00-11ed-bed1-806e6f6e6963}    |
device                  partition=\Device\HarddiskVolume1         |
path                    \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI          |
description             Windows Boot Manager                      |
                                                                  |
ファームウェア アプリケーション (101fffff                         |
--------------------------------                                  |
identifier              {c16a79f0-67b4-11ed-bf38-806e6f6e6963} ←-+
device                  unknown
description             UEFI: Generic-Multi-Card 1.00, Partition 1
bcdedit /set {fwbootmgr} bootsequence {デバイスのID}
shutdown /r /t 0

を実行すると,再起動後に指定したデバイスがブートする.

●マルチブート OS の選択
BCD でマルチブートを構成している場合,bcdedit /enum all の「Windows ブート マネージャー」にブート可能な OS の ID 一覧が列挙されている.

その ID が具体的に何なのかは,description を見ればだいたい分かる.で

bcdedit /bootsequence {ID}
shutdown /r /t 0

を実行すると,再起動後に指定した OS がブートする.

●UEFI setup 起動

shutdown /r /t 0 /fw

を実行すると,再起動後に UEFI セットアップが起動する (はず).

で powershell でスクリプト組んで作ってみた.で使ってみたら我ながら超便利.
UEFI setup のための [DEL] キー連打に失敗してストレスが溜まる,なんてことが皆無だし,ブート OS 変更のために何回もマウスクリックしてたのが一発だし.超快適ヽ(´ー`)ノ

というわけで以下 powershell のコード.

##############################################################################
# -*- mode: powershell -*-
$Debug = $False
#$Debug = $True
Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop" # エラーで即停止
$global:Selected = ''
$DialogWidth = 300
$DialogButtonHeight = 50
##############################################################################
# BCD リード
function ReadBCD {
$BcdItems = @{}
foreach($Line in (bcdedit /enum all) -Split '`n'){
if($Line -eq ''){
if(Test-Path Variable:BcdItem){
$BcdItems.Add($BcdItem."identifier", $BcdItem)
Remove-Variable BcdItem
}
}
elseif(!(Test-Path Variable:BcdItem)){
$BcdItem = @{"title" = $Line}
}
elseif($Line -cmatch "^(\w+) +(.*)"){
if($Matches[1] -eq "displayorder"){
$BcdItem.Add($Matches[1], @($Matches[2]))
}else{
$BcdItem.Add($Matches[1], $Matches[2])
}
}
elseif($Line -cmatch "^ +(.*)" -and ($BcdItem.ContainsKey("displayorder"))){
$BcdItem."displayorder" += $Matches[1]
}
}
return $BcdItems
}
##############################################################################
# ボタン追加
function AddButton( $Table, [ref]$Pos, $Label, $OnClick ){
$Button = New-Object System.Windows.Forms.Button
$Button.Dock = "Fill"
$Button.Margin = 0
$Button.text = $Label
$Button.DialogResult = "OK"
$Button.Add_Click($OnClick)
$Table.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Percent, 100))) | Out-Null
$Table.Controls.Add($Button, 0, $Pos.Value)
++$Pos.Value
}
##############################################################################
# Form 作成
Add-Type -Assembly PresentationCore
Add-Type -AssemblyName System.Windows.Forms
$Form = New-Object System.Windows.Forms.Form
# Form のサイズ
$Form.StartPosition = "CenterScreen"
$Form.MinimizeBox = $False
$Form.MaximizeBox = $False
$Form.TopMost = $True
$Form.Add_Shown({$Form.WindowState = [System.Windows.Forms.FormWindowState]::Normal})
$Table = New-Object System.Windows.Forms.TableLayoutPanel
$Table.ColumnCount = 1
$Table.Dock = "Fill"
# BCD ブートメニューボタン
$ButtonNum = 0
$Form.Font = New-Object System.Drawing.Font("Segoe UI Emoji", 12)
$Form.Text = "BootNext Menu"
# UEFI setup
AddButton $Table ([ref]$ButtonNum) `
"(&A) UEFI Setup" `
({$global:Selected = "setup"}.GetNewClosure())
$BcdItems = ReadBCD
# bootmgr
for($i = 1; $i -lt $BcdItems."{bootmgr}"."displayorder".Length; ++$i){
$BcdItem = $BcdItems.($BcdItems."{bootmgr}"."displayorder"[$i])
AddButton $Table ([ref]$ButtonNum) `
('(&' + [System.Convert]::ToChar(65 + $ButtonNum) + ') ' + $BcdItem."description") `
({$global:Selected = $BcdItem}.GetNewClosure())
}
# disk
for($i = 1; $i -lt $BcdItems."{fwbootmgr}"."displayorder".Length; ++$i){
$BcdItem = $BcdItems.($BcdItems."{fwbootmgr}"."displayorder"[$i])
$Title = ('(&' + [System.Convert]::ToChar(65 + $ButtonNum) + ') ' + $BcdItem."description")
if($BcdItem.ContainsKey("device") -and ($BcdItem."device" -cmatch "Volume(\d+)$")){
$Title += " [Vol:" + $Matches[1] + "]"
}
AddButton $Table ([ref]$ButtonNum) $Title ({$global:Selected = $BcdItem}.GetNewClosure())
}
$Form.ClientSize = [string]$DialogWidth + ',' + ($ButtonNum * $DialogButtonHeight)
$Form.Controls.Add($Table)
# シャットダウン処理
if($Form.Showdialog() -eq 'OK'){
# UEFI setup
if($Selected -eq 'setup'){shutdown /r /f /t 0 /fw}
# 次回ブート設定 (Disk)
elseif($Selected."title" -cmatch "Firmware Application"){
bcdedit /set '{fwbootmgr}' bootsequence $Selected."identifier"
Restart-Computer -Force
}
# 次回ブート設定
else{
bcdedit /bootsequence $Selected."identifier"
Restart-Computer -Force
}
}
view raw bootnext.ps1 hosted with ❤ by GitHub

0 件のコメント:

コメントを投稿