Win10+ Setup Disk (Works with UEFI Secure Boot / BIOS / Install.wim over 4 GB)

Discussion in 'Scripting' started by freddie-o, Mar 21, 2019.

  1. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60
    #61 freddie-o, Jul 31, 2019
    Last edited: Jul 31, 2019
    (OP)
    EDIT: The problem with that script are the "Select ISO" and "Create USB Disk" buttons. I cannot figure out how to make them do what they're supposed to.

    After selecting the ISO, the window should just close, but it starts the script. The "Create USB Disk" button should start the script.

    Also the "Select USB Disk" drop down list starts out blank.
     
  2. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    I had a look at your modified script to have only one gui and modified it as follows :
    Code:
    @echo off
    (
    echo #
    echo #    This script must be executed with admin privilege
    echo #
    echo #    Test Administrator privileges
    echo If ^(-NOT ^([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent^(^)^).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"^)^)
    echo {
    echo #    Restart the script to get Administrator privileges and exit
    echo     Start-Process 'powershell.exe' -Verb runAs -ArgumentList ^("-NoLogo -WindowStyle Normal -noprofile -file " + """" + $PSCommandPath + """"^)
    echo     exit
    echo }
    echo #    We have Administrator privileges
    echo #
    echo [console]::ForegroundColor = "Yellow"
    echo [console]::BackgroundColor = "blue"
    echo #
    echo Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    echo # Filebrowser dialog
    echo $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
    echo    Multiselect = $false # One file can be chosen
    echo     Filter = 'ISO images ^(*.iso^)^|*.iso' # Select iso files
    echo }
    echo #
    echo $wshell=New-Object -ComObject Wscript.Shell
    echo clear-host
    
    echo #    Select the USB disk
    
    echo $global:SelectISO=$False
    echo $global:Cancel=$False
    
    echo $Form=New-Object System.Windows.Forms.Form # Create the screen form ^(window^)
    echo # $Form ^|gm;pause
    echo # Set the title and size of the window:
    echo $Form.Text='Windows installation disk^'
    echo $Form.Width=490 ; $Form.Height=210
    echo $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    echo # Create a drop-down list and fill it
    echo $USB=$Null
    echo $USBDisks=@^(^) # array with USB disk number
    echo $Disks=Get-Disk ^| Where-Object {^($_.BusType -eq "USB"^) -and ^($_.OperationalStatus -eq "Online"^)}
    
    echo $USBDiskList=New-Object System.Windows.Forms.ComboBox
    echo # $USBDiskList^|gm
    echo $USBDiskList.Width=450
    echo Foreach ^($USBDisk in $Disks^) {
    echo     $FriendlyName=^($USBDisk.FriendlyName^).PadRight^(30," "^).substring^(0,30^)   
    echo     $Partitions = Get-Partition ^| Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
    echo     If ^($Partitions^) {
    echo         Foreach ^($Partition in $Partitions^) {
    echo         $Volumes=get-volume ^| Where-Object {$Partition.AccessPaths -contains  $_.path }
    echo         Foreach ^($Volume in $Volumes^) {
    echo             $USBDisks+=$USBDisk.DiskNumber
    echo             $USBDiskList.Items.Add^(^(" {0,-30}| {1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ^($Partition.DriveLetter^), $Volume.FileSystemLabel.PadRight^(30," "^).substring^(0,30^), ^($Partition.Size/1GB^)^)^)^|out-null
    echo             }       
    echo         }
    echo     } Else {
    echo         $USBDisks+=$USBDisk.DiskNumber
    echo         $USBDiskList.Items.Add^(^(" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",^($USBDisk.Size/1GB^)^)^)^|out-null
    echo     }
    echo }
    
    echo $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    echo $SelectUSBDisk.Location=New-Object System.Drawing.Size^(10,20^)
    echo $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10'
    echo $SelectUSBDisk.width=200;$SelectUSBDisk.height=20;
    echo $Form.Controls.Add^($SelectUSBDisk^)
    
    echo $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    echo $USBDiskList.Location=New-Object System.Drawing.Point^(10,40^)
    echo $USBDiskList.width=450;$USBDiskList.height=20
    echo $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White"
    echo $USBDiskList.Font='Segoe UI,10'
    echo $Form.Controls.Add^($USBDiskList^)
    
    echo $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    echo $SelectISOButton.Location=New-Object System.Drawing.Size^(10,100^)
    echo $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10'
    echo $SelectISOButton.width=80;$SelectISOButton.height=60;
    echo $Form.Controls.Add^($SelectISOButton^)
    echo $SelectISOButton.Add_Click^({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog^(^)}^)
    echo $Form.Controls.Add^($SelectISOButton^)
    
    echo $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    echo $CreateUSBDiskButton.Location=New-Object System.Drawing.Size^(350,130^)
    echo $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10'
    echo $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30;
    echo $Form.Controls.Add^($CreateUSBDiskButton^)
    echo $CreateUSBDiskButton.Add_Click^({$Form.close^(^)}^)
    echo $Form.Controls.Add^($CreateUSBDiskButton^)
    
    echo $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    echo $CancelButton.Location=New-Object System.Drawing.Size^(260,130^)
    echo $CancelButton.Size=New-Object System.Drawing.Size^(120,20^)
    echo $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10'
    echo $CancelButton.width=60;$CancelButton.height=30;
    echo $Form.Controls.Add^($CancelButton^)
    echo $CancelButton.Add_Click^({$global:Cancel=$True;$Form.close^(^)}^)
    
    echo $result = $Form.ShowDialog^(^)
    echo $USB=$USBDisks[$USBDiskList.SelectedIndex]
    
    echo if ^($Cancel^){$wshell.Popup^("User Cancelled the script",0,"Cancel"^) ^| Out-Null;exit}
    echo if ^(!$USB^){$wshell.Popup^("No USB disk selected",0,"Error"^) ^| Out-Null;exit}
    echo if ^(!$global:SelectISO^){$wshell.Popup^("Operation cancelled. You must select a ISO image",0,"Error"^) ^| Out-Null;exit}
    echo #
    
    echo # [void]$FileBrowser.ShowDialog^(^)
    echo #
    echo $ImagePath = $FileBrowser.FileName;
    echo $ISO=":"
    echo If^($FileBrowser.FileNames -like "*\*"^) {
    echo #  Check if iso already mounted
    echo     $ISO = ^(Get-DiskImage -ImagePath $ImagePath ^| Get-Volume^).DriveLetter
    echo #    Mount iso
    echo     IF ^(!$ISO^) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO ^|out-null
    echo     $ISO = ^(Get-DiskImage -ImagePath $ImagePath ^| Get-Volume^).DriveLetter}
    echo     $ISO=$ISO+":"
    echo }
    echo if ^($ISO -eq ":"^) {$wshell.Popup^("No ISO image mounted or operation cancelled",0,"Error"^) ^| Out-Null;exit}
    
    echo #    Clear the USB stick
    echo Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    echo Stop-Service ShellHWDetection
    echo #    Create the fat32 boot partition
    echo $usbfat32=^(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter -IsActive ^| Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT"^).DriveLetter + ":"
    echo #    Create the ntfs intall partition
    echo $usbntfs=^(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter ^| Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL"^).DriveLetter + ":"
    echo Start-Service ShellHWDetection
    echo # Read-Host "Eject the iso if it is mounted. When ready press Enter"
    echo # $Volumes = ^(Get-Volume^).Where^({$_.DriveLetter}^).DriveLetter
    echo # Read-Host "Mount the iso. When ready press Enter"
    echo # $ISO = ^(Compare-Object -ReferenceObject $Volumes -DifferenceObject ^(Get-Volume^).Where^({$_.DriveLetter}^).DriveLetter^).InputObject
    echo # $ISO = ^(get-volume^| Where-Object {^($_.DriveType -eq "CD-ROM"^) -and ^($_.filesystemlabel -ne ""^) -and ^($_.OperationalStatus -eq "OK"^)} ^|Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single^).DriveLetter + ":"
    echo # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose
    echo # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose
    echo # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose
    echo # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse  -Verbose
    echo # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse  -Verbose
    echo # new-item $usbfat32"\sources" -itemType Directory
    echo # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim"  -Verbose
    echo robocopy $iso $usbntfs /e
    echo robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    echo robocopy $iso"\boot" $usbfat32"\boot" /e
    echo robocopy $iso"\efi" $usbfat32"\efi" /e
    echo robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    echo # Eject the mounted iso image
    echo # ^(New-Object -ComObject Shell.Application^).Namespace^(17^).ParseName^($ISO^).InvokeVerb^("Eject"^)
    echo DisMount-DiskImage -ImagePath $ImagePath ^|out-null
    echo Remove-item ^($env:TEMP + "\script.ps1"^)     
    )>"%temp%\script.ps1"
    powershell -noprofile -executionpolicy bypass -WindowStyle Normal -file "%temp%\script.ps1"
    
    
    I don't see a real advantage using only one gui.
     
  3. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60
    I modified the script using abbodi1406's suggestion...

    Code:
    @echo off
    ::AveYo: self-elevate passing args and preventing loop
    set "args="%~f0" %*" & call set "args=%%args:"=\""%%"
    reg query HKU\S-1-5-19>nul 2>nul||(if "%?%" neq "y" powershell -c "start cmd -ArgumentList '/c set ?=y&call %args%' -verb runas" &exit)
    title Windows installation disk
    ::Script by @rpo / @abbodi1406 / @freddie-o [forums.mydigitallife.net]
    powershell -NoLogo -NoProfile -WindowStyle Normal -ExecutionPolicy Bypass -C "$f=[io.file]::ReadAllText('%~f0') -split ':ps_usb\:.*';iex ($f[1]);" & exit/b
    
    :ps_usb: [
    [console]::ForegroundColor = "Yellow"
    [console]::BackgroundColor = "blue"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select iso files
    }
    #
    $wshell=New-Object -ComObject Wscript.Shell
    clear-host
    
    #    Select the USB disk
    
    $global:SelectISO=$False
    $global:Cancel=$False
    
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    # $Form |gm;pause
    # Set the title and size of the window:
    $Form.Text='Windows installation disk'
    $Form.Width=495 ; $Form.Height=210
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    # Create a drop-down list and fill it
    $USB=$Null
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    # $USBDiskList|gm
    $USBDiskList.Width=450
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $USBDiskList.Items.Add((" {0,-30}| {1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }    
            }
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(15,20)
    $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10'
    $SelectUSBDisk.width=200;$SelectUSBDisk.height=20;
    $Form.Controls.Add($SelectUSBDisk)
    
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(15,40)
    $USBDiskList.width=450;$USBDiskList.height=20
    $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White"
    $USBDiskList.Font='Segoe UI,10'
    $Form.Controls.Add($USBDiskList)
    
    $WARNING=New-Object System.Windows.Forms.Label # Put the WARNING label on the form
    $WARNING.Location=New-Object System.Drawing.Size(15,70)
    $WARNING.Text="WARNING: All partitions and data on the USB disk will be lost.";$WARNING.Font='Segoe UI,10'
    $WARNING.width=400;$WARNING.height=20;
    $Form.Controls.Add($WARNING)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(15,110)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10'
    $SelectISOButton.width=80;$SelectISOButton.height=50;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()})
    $Form.Controls.Add($SelectISOButton)
    
    $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form
    $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(355,130)
    $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10'
    $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30;
    $Form.Controls.Add($CreateUSBDiskButton)
    $CreateUSBDiskButton.Add_Click({$Form.close()})
    $Form.Controls.Add($CreateUSBDiskButton)
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(280,130)
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10'
    $CancelButton.width=60;$CancelButton.height=30;
    $Form.Controls.Add($CancelButton)
    $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()})
    
    $result = $Form.ShowDialog()
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    
    if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit}
    if (!$USB){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit}
    if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit}
    #
    
    # [void]$FileBrowser.ShowDialog()
    #
    $ImagePath = $FileBrowser.FileName;
    $ISO=":"
    If($FileBrowser.FileNames -like "*\*") {
    #  Check if iso already mounted
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter
    #    Mount iso
        IF (!$ISO) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter}
        $ISO=$ISO+":"
    }
    if ($ISO -eq ":") {$wshell.Popup("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit}
    
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    # Read-Host "Eject the iso if it is mounted. When ready press Enter"
    # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter
    # Read-Host "Mount the iso. When ready press Enter"
    # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject
    # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":"
    # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose
    # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse  -Verbose
    # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse  -Verbose
    # new-item $usbfat32"\sources" -itemType Directory
    # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim"  -Verbose
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    # Eject the mounted iso image
    # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject")
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    :ps_usb: ]
    
    


    I wanted to add a "WARNING" pop up message after clicking "Create USB Disk" button but couldn't make the "Cancel" button in the pop up to work. So I just added it to the GUI.
     
  4. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,692
    60
    #67 AveYo, Aug 5, 2019
    Last edited: Aug 5, 2019
    But do you see a real advantage in using a proper hybrid batch-powershell format so that users and you yourself can quickly revision the script without all that messy echo and carret escaping?
    Just noticed @freddie-o already did it above, but here's my changes that do the elevation inside powershell part as the original
    (using 544 instead of "Administrator" - think about the poor portuguese users and many others that have this string localized)
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @set "__CMD__=%~f0" &set "__ARGS__=%*" &powershell -noprofile -c "iex([io.file]::ReadAllText(\"%~f0\"))" &exit/b
    #>
    #
    #    This script must be executed with admin privilege
    #
    #    Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(544))
    {
    #    Restart the script to get Administrator privileges and exit
         Start-Process cmd -ArgumentList ("/c call `"$Env:__CMD__`" $Env:__ARGS__") -Verb runAs
         exit
    }
    
    #    We have Administrator privileges
    #
    [console]::ForegroundColor = "Yellow"
    [console]::BackgroundColor = "blue"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select iso files
    }
    #
    $wshell=New-Object -ComObject Wscript.Shell
    clear-host
    #    Select the USB disk
    $global:SelectISO=$False
    $global:Cancel=$False
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    # $Form |gm;pause
    # Set the title and size of the window:
    $Form.Text='Windows installation disk'
    $Form.Width=490; $Form.Height=210
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    # Create a drop-down list and fill it
    $USB=$Null
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    # $USBDiskList|gm
    $USBDiskList.Width=450
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)   
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $USBDiskList.Items.Add((" {0,-30}| {1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }       
            }
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(10,20)
    $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10'
    $SelectUSBDisk.width=200;$SelectUSBDisk.height=20;
    $Form.Controls.Add($SelectUSBDisk)
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(10,40)
    $USBDiskList.width=450;$USBDiskList.height=20
    $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White"
    $USBDiskList.Font='Segoe UI,10'
    $Form.Controls.Add($USBDiskList)
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(10,100)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10'
    $SelectISOButton.width=80;$SelectISOButton.height=60;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()})
    $Form.Controls.Add($SelectISOButton)
    $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(350,130)
    $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10'
    $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30;
    $Form.Controls.Add($CreateUSBDiskButton)
    $CreateUSBDiskButton.Add_Click({$Form.close()})
    $Form.Controls.Add($CreateUSBDiskButton)
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(260,130)
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10'
    $CancelButton.width=60;$CancelButton.height=30;
    $Form.Controls.Add($CancelButton)
    $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()})
    $result = $Form.ShowDialog()
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    if ($Cancel){$wshell.Popup("User Cancelled the script",0,"Cancel") | Out-Null;exit}
    if (!$USB){$wshell.Popup("No USB disk selected",0,"Error") | Out-Null;exit}
    if (!$global:SelectISO){$wshell.Popup("Operation cancelled. You must select a ISO image",0,"Error") | Out-Null;exit}
    #
    # [void]$FileBrowser.ShowDialog()
    #
    $ImagePath = $FileBrowser.FileName;
    $ISO=":"
    If($FileBrowser.FileNames -like "*\*") {
    #  Check if iso already mounted
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter
    #    Mount iso
        IF (!$ISO) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter}
        $ISO=$ISO+":"
    }
    if ($ISO -eq ":") {$wshell.Popup("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    # Read-Host "Eject the iso if it is mounted. When ready press Enter"
    # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter
    # Read-Host "Mount the iso. When ready press Enter"
    # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject
    # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":"
    # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose
    # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse  -Verbose
    # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse  -Verbose
    # new-item $usbfat32"\sources" -itemType Directory
    # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim"  -Verbose
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    # Eject the mounted iso image
    # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject")
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    Remove-item ($env:TEMP + "\script.ps1")     
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
    small edit for forensic friendliness:
    - the powershell process shows the file that got iex instead of just $env:__CMD__
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    Thanks, I like your implementation. Using echo was horrible!
     
  6. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    After line 123 of the script in the Op, just add :
    Code:
    $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",0,"Warning",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    
    BTW you can now suppress lines 72-77.
     
  7. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60
    #70 freddie-o, Aug 5, 2019
    Last edited: Aug 5, 2019
    (OP)
    Upon clicking the cancel button, I got this...
    Code:
    Dismount-DiskImage : Cannot bind argument to parameter 'ImagePath' because it is null.
    At line:99 char:51
    + if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-nul ...
    +                                                   ~~~~~~~~~~
        + CategoryInfo          : InvalidData: (:) [Dismount-DiskImage], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Dismount-DiskImage
    
     
  8. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60

    Will update the script. :shake:
     
  9. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    #72 rpo, Aug 5, 2019
    Last edited: Aug 5, 2019
    This is the script working on my system :
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @set "__CMD__=%~f0" &set "__ARGS__=%*" &powershell -noprofile -c "iex([io.file]::ReadAllText(\"%~f0\"))" &exit/b
    #>
    #
    #    This script must be executed with admin privilege
    #
    #    Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(544))
    {
    #    Restart the script to get Administrator privileges and exit
         Start-Process cmd -ArgumentList ("/c call `"$Env:__CMD__`" $Env:__ARGS__") -Verb runAs
         exit
    }
    
    #    We have Administrator privileges
    #
    [console]::ForegroundColor = "Yellow"
    [console]::BackgroundColor = "blue"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select iso files
    }
    #
    $wshell=New-Object -ComObject Wscript.Shell
    clear-host
    
    #    Select the USB disk
    
    $global:SelectISO=$False
    $global:Cancel=$False
    
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    # $Form |gm;pause
    # Set the title and size of the window:
    $Form.Text='Windows Installation Disk v3'
    $Form.Width=495 ; $Form.Height=210
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    # Create a drop-down list and fill it
    $USB=$Null
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    # $USBDiskList|gm
    $USBDiskList.Width=450
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $USBDiskList.Items.Add((" {0,-30}| {1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }
            }
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(15,20)
    $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10'
    $SelectUSBDisk.width=200;$SelectUSBDisk.height=20;
    $Form.Controls.Add($SelectUSBDisk)
    
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(15,40)
    $USBDiskList.width=450;$USBDiskList.height=20
    $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White"
    $USBDiskList.Font='Segoe UI,10'
    $Form.Controls.Add($USBDiskList)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(15,110)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10'
    $SelectISOButton.width=80;$SelectISOButton.height=50;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()})
    $Form.Controls.Add($SelectISOButton)
    
    $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form
    $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(355,130)
    $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10'
    $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30;
    $Form.Controls.Add($CreateUSBDiskButton)
    $CreateUSBDiskButton.Add_Click({$Form.close()})
    $Form.Controls.Add($CreateUSBDiskButton)
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(280,130)
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10'
    $CancelButton.width=60;$CancelButton.height=30;
    $Form.Controls.Add($CancelButton)
    $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()})
    
    $result = $Form.ShowDialog()
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    
    if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit}
    if (!$USB){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit}
    if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit}
    #
    $ImagePath = $FileBrowser.FileName;
    $ISO=":"
    If($FileBrowser.FileNames -like "*\*") {
    #  Check if iso already mounted
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter
    #    Mount iso
        IF (!$ISO) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter}
        $ISO=$ISO+":"
    }
    if ($ISO -eq ":") {$wshell.Popup("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit}
    
    $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",0,"Warning",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    # Read-Host "Eject the iso if it is mounted. When ready press Enter"
    # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter
    # Read-Host "Mount the iso. When ready press Enter"
    # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject
    # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":"
    # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose
    # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose
    # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse  -Verbose
    # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse  -Verbose
    # new-item $usbfat32"\sources" -itemType Directory
    # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim"  -Verbose
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    # Eject the mounted iso image
    # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject")
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
    
     
  10. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,692
    60
    what's with the SeT[/USER] "__CMD__=..?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    @BAU
    "what's with the SeT[/USER] "__CMD__=..?" : a copy/paste problem, but script is corrected.
    btw my Windows is a French one but i can use "Administrator" instead of 544. Windows behaviour is sometimes strange; i have a powershell script where i had to use the localized name "Administrateur" ($admin=(get-wmiobject win32_group| Where-Object {$_.sid -eq "s-1-5-32-544"}).name).
     
  12. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,692
    60
    because there is no script.ps1 to cleanup anymore since it's a self-contained hybrid batch-ps script :)
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60
    #78 freddie-o, Aug 5, 2019
    Last edited: Aug 5, 2019
    (OP)
    Updated the [Windows installation disk] script in the OP with v3. A new GUI and script elevates and runs using a hybrid batch-powershell format.
     
  14. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,445
    1,421
    60
    The script with some housekeeping
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @set "__CMD__=%~f0" &set "__ARGS__=%*" &powershell -noprofile -c "iex([io.file]::ReadAllText(\"%~f0\"))" &exit/b
    #>
    #
    #    This script must be executed with admin privilege
    #
    #    Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(544))
    {
    #    Restart the script to get Administrator privileges and exit
         Start-Process cmd -ArgumentList ("/c call `"$Env:__CMD__`" $Env:__ARGS__") -Verb runAs
         exit
    }
    #    We have Administrator privileges
    #
    [console]::ForegroundColor = "Yellow"
    [console]::BackgroundColor = "blue"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select iso files
    }
    $wshell=New-Object -ComObject Wscript.Shell
    #
    $global:SelectISO=$False
    $global:Cancel=$False
    #
    clear-host
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    # Set the title and size of the window:
    $Form.Text='Windows Installation Disk v3'
    $Form.Width=495 ; $Form.Height=220
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    #    Select the USB disk
    # Create a drop-down list and fill it
    $Combobox=New-Object System.Windows.Forms.ComboBox
    $Combobox.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $Combobox.Location=New-Object System.Drawing.Point(15,40)
    $Combobox.Width=450;$Combobox.height=20 
    $USB=$Null
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    While (!$Disks) {
        $Result=$wshell.Popup("Please mount USB stick. Click ""OK"" when ready`r`nor ""Cancel"" to exit.",0,"Warning",1+48)
        if ($result -eq 2) {exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    # $USBDiskList|gm
    $USBDiskList.Width=450
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)   
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $Combobox.Items.Add((" {0,-30}|{1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }       
            }   
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(15,20)
    $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10'
    $SelectUSBDisk.width=200;$SelectUSBDisk.height=20;
    $Form.Controls.Add($SelectUSBDisk)
    $form.Controls.Add($Combobox)
    $Combobox.SelectedIndex=0
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(355,130)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10'
    $SelectISOButton.width=110;$SelectISOButton.height=30;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()})
    $Form.Controls.Add($SelectISOButton)
    
    $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form
    $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(15,130)
    $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10'
    $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30;
    $Form.Controls.Add($CreateUSBDiskButton)
    $CreateUSBDiskButton.Add_Click({$Form.close()})
    $Form.Controls.Add($CreateUSBDiskButton)
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(230,130)
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10'
    $CancelButton.width=110;$CancelButton.height=30;
    $Form.Controls.Add($CancelButton)
    $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()})
    #
    [void]$Form.ShowDialog()
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit}
    if ($USB -eq $Null){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit}
    if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit}
    #
    $ImagePath = $FileBrowser.FileName;
    $ISO=":"
    If($FileBrowser.FileNames -like "*\*") {
    #  Check if iso already mounted
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter
    #    Mount iso
        IF (!$ISO) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter}
        $ISO=$ISO+":"
    }
    if ($ISO -eq ":") {$wshell.Popup("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit}
    #
    $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",0,"Warning",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    #
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    # Eject the mounted iso image
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
     
  15. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,375
    2,277
    60
    So we don't need this anymore?
    Code:
    if ($USB -eq $Null){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit}
    Can this scenario
    Code:
    $Result=$wshell.Popup("Please mount USB stick. Click ""OK"" when ready`r`nor ""Cancel"" to exit.",0,"Warning",1+48)
        if ($result -eq 2) {exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    be applied here too?
    Code:
    if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit}
    so instead of exiting the script, you can go back to the GUI to select the ISO?