Windows PEでバックアップ・リストア(8)
全体としてはこのような感じになります。これをWindows PEで実行すればバックアップ・リストアができます。
Set-ExecutionPolicy Bypass -ExecutionPolicy RemoteSigned -Scope Process -Force
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# ============================================================
# Main Form
# ============================================================
$form = New-Object System.Windows.Forms.Form
$form.Text = "FFU Backup / Restore Tool"
$form.Size = New-Object System.Drawing.Size(520,380)
$form.StartPosition = "CenterScreen"
# Path Label
$label = New-Object System.Windows.Forms.Label
$label.Text = "Path:"
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(50,20)
$form.Controls.Add($label)
# Path TextBox
$PathBox = New-Object System.Windows.Forms.TextBox
$PathBox.Location = New-Object System.Drawing.Point(60,18)
$PathBox.Size = New-Object System.Drawing.Size(320,20)
$form.Controls.Add($PathBox)
# Browse Button
$BrowseBtn = New-Object System.Windows.Forms.Button
$BrowseBtn.Text = "Browse"
$BrowseBtn.Location = New-Object System.Drawing.Point(390,16)
$BrowseBtn.Size = New-Object System.Drawing.Size(80,25)
$form.Controls.Add($BrowseBtn)
# Backup Button
$BackupBtn = New-Object System.Windows.Forms.Button
$BackupBtn.Text = "Backup FFU"
$BackupBtn.Location = New-Object System.Drawing.Point(10,60)
$BackupBtn.Size = New-Object System.Drawing.Size(460,40)
$form.Controls.Add($BackupBtn)
# Restore Button
$RestoreBtn = New-Object System.Windows.Forms.Button
$RestoreBtn.Text = "Restore FFU"
$RestoreBtn.Location = New-Object System.Drawing.Point(10,110)
$RestoreBtn.Size = New-Object System.Drawing.Size(460,40)
$form.Controls.Add($RestoreBtn)
# Log Box
$LogBox = New-Object System.Windows.Forms.TextBox
$LogBox.Multiline = $true
$LogBox.ScrollBars = "Vertical"
$LogBox.Location = New-Object System.Drawing.Point(10,160)
$LogBox.Size = New-Object System.Drawing.Size(460,130)
$form.Controls.Add($LogBox)
# Progress Bar
$Progress = New-Object System.Windows.Forms.ProgressBar
$Progress.Location = New-Object System.Drawing.Point(10,300)
$Progress.Size = New-Object System.Drawing.Size(460,20)
$form.Controls.Add($Progress)
# Logging
function Log($msg){
$LogBox.AppendText("$msg`r`n")
}
# ============================================================
# 自作ドライブ選択ダイアログ(WinPE完全対応)
# ============================================================
function Select-Drive {
$drivedlg = New-Object System.Windows.Forms.Form
$drivedlg.Text = "Select Drive"
$drivedlg.Size = New-Object System.Drawing.Size(360,260)
$drivedlg.StartPosition = "CenterScreen"
$drvList = New-Object System.Windows.Forms.ListBox
$drvList.Location = New-Object System.Drawing.Point(10,10)
$drvList.Size = New-Object System.Drawing.Size(320,170)
$drvList.SelectionMode = "One"
$drivedlg.Controls.Add($drvList)
$drvokBtn = New-Object System.Windows.Forms.Button
$drvokBtn.Text = "OK"
$drvokBtn.Location = New-Object System.Drawing.Point(170,190)
$drivedlg.Controls.Add($drvokBtn)
$drvcancelBtn = New-Object System.Windows.Forms.Button
$drvcancelBtn.Text = "Cancel"
$drvcancelBtn.Location = New-Object System.Drawing.Point(250,190)
$drivedlg.Controls.Add($drvcancelBtn)
$choiceDrive = @()
#容量付きでディスクドライブ列挙
$diskdrv=get-disk | select-object -property Number,FriendlyName,SerialNumber,Size | sort-object Number
foreach ($d in $diskdrv) {
$driveNo = $d.Number
$driveName =$d.FriendlyName
$drvsizeGB = [math]::Round($d.Size/(1024*1024*1024),1)
$drvList.Items.Add("$driveNo $driveName $drvsizeGB GB")
$choiceDrive += $driveNo
}
# MouseUp で選択確定(WinPE対策)
$drvList.Add_MouseUp({
$idxx = $drvList.IndexFromPoint($drvList.PointToClient([System.Windows.Forms.Cursor]::Position))
if ($idxx -ge 0) { $drvList.SelectedIndex = $idxx }
})
$drvokBtn.Add_Click({
if ($drvList.SelectedIndex -ge 0) {
$drivedlg.Tag = $diskdrv[$drvList.SelectedIndex].Number
} else {
$drivedlg.Tag = $null
}
$drivedlg.Close()
})
$drvcancelBtn.Add_Click({
$drivedlg.Tag = $null
$drivedlg.Close()
})
$drivedlg.ShowDialog() | Out-Null
$resultdrv = $drivedlg.Tag
if ($resultdrv -is [array]) { $resultdrv = $resultdrv[-1] }
return $resultdrv
}
# ============================================================
# 自作フォルダ選択ダイアログ(WinPE完全対応)
# ============================================================
function Select-Folder {
$dlg = New-Object System.Windows.Forms.Form
$dlg.Text = "Select Drive"
$dlg.Size = New-Object System.Drawing.Size(360,260)
$dlg.StartPosition = "CenterScreen"
$driveList = New-Object System.Windows.Forms.ListBox
$driveList.Location = New-Object System.Drawing.Point(10,10)
$driveList.Size = New-Object System.Drawing.Size(320,170)
$driveList.SelectionMode = "One"
$dlg.Controls.Add($driveList)
$okBtn = New-Object System.Windows.Forms.Button
$okBtn.Text = "OK"
$okBtn.Location = New-Object System.Drawing.Point(170,190)
$dlg.Controls.Add($okBtn)
$cancelBtn = New-Object System.Windows.Forms.Button
$cancelBtn.Text = "Cancel"
$cancelBtn.Location = New-Object System.Drawing.Point(250,190)
$dlg.Controls.Add($cancelBtn)
$DrivePaths = @()
# 容量付きでドライブ列挙(ルートのみ)
$vols = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq 2 -or $_.DriveType -eq 3 }
foreach ($v in $vols) {
$drive = $v.DeviceID + "\"
$sizeGB = [math]::Round(($v.Size / 1GB), 1)
$freeGB = [math]::Round(($v.FreeSpace / 1GB), 1)
$driveList.Items.Add("$drive ($freeGB GB free / $sizeGB GB)")
$DrivePaths += $drive
}
# MouseUp で選択確定(WinPE対策)
$driveList.Add_MouseUp({
$idx = $driveList.IndexFromPoint($driveList.PointToClient([System.Windows.Forms.Cursor]::Position))
if ($idx -ge 0) { $driveList.SelectedIndex = $idx }
})
$okBtn.Add_Click({
if ($driveList.SelectedIndex -ge 0) {
$dlg.Tag = $DrivePaths[$driveList.SelectedIndex]
} else {
$dlg.Tag = $null
}
# ★ 配列なら最後の要素に正規化
if ($dlg.Tag -is [array]) {
$dlg.Tag = $dlg.Tag[-1]
}
$dlg.Close()
})
$cancelBtn.Add_Click({
$dlg.Tag = $null
$dlg.Close()
})
$dlg.ShowDialog() | Out-Null
$result = $dlg.Tag
if ($result -is [array]) { $result = $result[-1] }
return $result
}
# Browse Click
$BrowseBtn.Add_Click({
$folder = Select-Folder
if ($folder) {
if ($folder -is [array]) { $folder = $folder[-1] }
$PathBox.Text = Join-Path $folder "backup.ffu"
Log "Selected folder: $folder"
}
})
# Backup
$BackupBtn.Add_Click({
$choose = Select-Drive
if ($choose) {
if ($choose -is [array]) { $choose = $choose[-1] }
$chooseDrv=$choose
#$PathBox.Text = Join-Path $folder "backup.ffu"
Log "Selected Drive: $chooseDrv"
}
$path = $PathBox.Text
if (-not $path) { Log "No path specified."; return }
$folder = Split-Path $path -Parent
if (-not (Test-Path $folder)) {
Log "Folder does not exist: $folder"
return
}
Log "Starting backup..."
#$Progress.Value = 10
$args = "/capture-ffu /imagefile:`"$path`" /capturedrive:\\.\PhysicalDrive$chooseDrv /name:`"FullDisk`""
Log $args
Start-Process dism -ArgumentList $args -Wait -NoNewWindow
$Progress.Value = 100
Log "Backup completed."
})
$RestoreBtn.Add_Click({
$choose = Select-Drive
if ($choose) {
if ($choose -is [array]) { $choose = $choose[-1] }
$chooseDrv=$choose
#$PathBox.Text = Join-Path $folder "backup.ffu"
Log "Selected Drive: $chooseDrv"
}
$path = $PathBox.Text
if (-not $path) { Log "No path specified."; return }
if (-not (Test-Path $path)) {
Log "File not found: $path"
return
}
Log "Starting restore..."
$Progress.Value = 10
$args = "/apply-ffu /imagefile:`"$path`" /applydrive:\\.\PhysicalDrive$chooseDrv"
Log $args
Start-Process dism -ArgumentList $args -Wait -NoNewWindow
$Progress.Value = 100
Log "Restore completed."
})
$form.ShowDialog() | Out-Null
