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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です