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. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    Brought improvement (?) to the combobox :
    Code:
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-36}|{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-7}|{1,1}:|{2,-3}|{3:n2} GB" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
    The disk name is displayed, followed by partition informations if present. User can select disk or partition.
    A non-proportional font should be used for displaying. I use Courier New.
     
  2. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    You can get the disk number by executing diskpart and entering list disk. IMHO it's not usefull to display this information.
     
  3. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    Modified how the partitions are displayed in the combobox a bit

    Code:
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-80}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-1}{1,1}:{2,-60}{3:n2} GB )" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
     
  4. MMIKEE

    MMIKEE MDL Senior Member

    Oct 6, 2012
    380
    361
    10
    This does not work properly for me... :confused: :confused::confused:
    It creates the BOOT 700MB FAT32 partition on an 8GB USB Drive, closes the CMD window and QUITS...
    No NTFS partition is created therefore, the .iso files are not copied to the USB Drive...
    The remaining unused portion of the USB Drive is a 6.78 GB Unallocated partition...
    I ran CMD as Admin...
    The .iso is a LTSC 2019 w/ CU .678 created with W10UI_6.6 and is located in a folder on Desktop with the Windows Installation Disk v1.4.cmd
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
  6. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    Added a pop up after the script finishes.
    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
    #
    $pswindow = $host.ui.rawui          # create a reference to the console’s UI.RawUI child object
    $pswindow.windowtitle = "Script by: rpo/abbodi1406/BAU/freddie-o [forums.mydigitallife.net]"
    [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
    #
    $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 v1.4'
    $Form.Width=475 ; $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
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(30,35)
    $USBDiskList.Width=400;$USBDiskList.height=20
    $Form.Controls.Add($SelectUSBDisk)
    $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("Plug in your USB disk first, then click ""OK"", to continue. `r`n`r`nTo close this script, click ""Cancel"".",0,"Plug in the USB disk",1+64)
            if ($result -eq 2) {Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-80}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-1}{1,1}:{2,-60}{3:n2} GB )" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    
    $SelectUSB=New-Object System.Windows.Forms.Label # Put the SelectUSB label on the form
    $SelectUSB.Location=New-Object System.Drawing.Size(30,15)
    $SelectUSB.Text="Select USB disk";$SelectUSB.Font='Default Font,9'
    $SelectUSB.width=380;$SelectUSB.height=15;
    $Form.Controls.Add($SelectUSB)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(295,135)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Default Font,9'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,20)
    $SelectISOButton.width=130;$SelectISOButton.height=25;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(155,135)
    $CancelButton.Text="Cancel";$CancelButton.Font='Default Font,9'
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=130;$CancelButton.height=25;
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    #
    $result = $form.ShowDialog()
    if ($result -eq "Cancel"){$wshell.Popup("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    [void]$FileBrowser.ShowDialog()
    #
    $ImagePath = $FileBrowser.FileName;
    if ($ImagePath -eq ""){$wshell.Popup("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
    $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("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
    #
    $Result=$wshell.Popup("Warning! Your USB disk will be converted to the MBR scheme. It will be repartitioned and reformatted. All data will be lost. `r`n`r`nAre you sure you want to continue? `r`n`r`nTo continue, click ""Yes"". To close this script, click ""No"".",0,"Create the Windows installation disk",4+48)
    if ($result -eq 7) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    set-disk $usb -partitionstyle mbr
    Stop-Service ShellHWDetection |out-null
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive | 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
    $wshell.Popup("The Windows Installation Disk is complete.",0,"Complete",0+64) | Out-Null;exit
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
    
     
  7. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    [​IMG]

    On the left, the "official" combobox display. On the right, my combobox display.
     
  8. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    As i told you before (cf post #141), a non-proportional font should be used for displaying. I use Courier New. This is what i coded:
    Code:
    ...
    $USBDiskList.Width=380;$USBDiskList.height=20;$USBDiskList.Font='Courier New,10'
    ...
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-36}|{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-7}({1,1}:){2,-3}|{3:n2} GB" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
    ....
    Some adjustements have to be made.
     
  9. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    Use only fixed fonts for the combobox. Proportional fonts are ok for the other texts.
    Change $SelectUSB.Text to "Select USB disk or partition" : click on disk or partition have the same effect; only the disk number is used.
    A timeout of 2 seconds is added for the popup cancel messages; after that the popup closes.
    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
    #
    $pswindow = $host.ui.rawui          # create a reference to the console’s UI.RawUI child object
    $pswindow.windowtitle = "Script by: rpo/abbodi1406/BAU/freddie-o [forums.mydigitallife.net]"
    [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
    #
    $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 v1.4'
    $Form.Width=475 ; $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
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(30,35)
    $USBDiskList.Width=400;$USBDiskList.height=20;$USBDiskList.Font='Lucida sans Typewriter,10'
    $Form.Controls.Add($SelectUSBDisk)
    $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("Plug in your USB disk first, then click ""OK"", to continue. `r`n`r`nTo close this script, click ""Cancel"".",0,"Plug in the USB disk",1+64)
            if ($result -eq 2) {Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-40}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-3}({1,1}:){2,-33}{3:n2} GB" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    
    $SelectUSB=New-Object System.Windows.Forms.Label # Put the SelectUSB label on the form
    $SelectUSB.Location=New-Object System.Drawing.Size(30,15)
    $SelectUSB.Text="Select USB disk or partition";$SelectUSB.Font='Consolas,10'
    $SelectUSB.width=380;$SelectUSB.height=15;
    $Form.Controls.Add($SelectUSB)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(300,135)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Consolas,10'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,20)
    $SelectISOButton.width=130;$SelectISOButton.height=25;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(160,135)
    $CancelButton.Text="Cancel";$CancelButton.Font='Consolas,10'
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=130;$CancelButton.height=25;
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    #
    if ($form.ShowDialog() -eq "Cancel"){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    if ($FileBrowser.ShowDialog() -eq "Cancel"){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $ImagePath = $FileBrowser.FileName;
    if ($ImagePath -eq ""){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    $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("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $Result=$wshell.Popup("Warning! Your USB disk will be converted to MBR scheme, repartitioned and reformatted. All data will be lost. `r`n`r`nAre you sure you want to continue? `r`n`r`nTo continue, click ""Yes"". To close this script, click ""No"".",0,"Create the Windows installation disk",4+48)
    if ($result -eq 7) {DisMount-DiskImage -ImagePath $ImagePath |out-null;$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    set-disk $usb -partitionstyle mbr
    Stop-Service ShellHWDetection |out-null
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive | 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
    $wshell.Popup("The Windows Installation Disk is complete.",0,"Complete",0+64) | Out-Null;exit
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
    
    
     
  10. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    Are there consequences to using proportional fonts for the drop box?
    The partition/s listed in the drop box are supposedly for information only. Better to just Select USB disk so less confusion.
     
  11. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    When you look at the picture on the left of post #149, you can see that it is not neat; that is the only drawback with proportional fonts. It's only "cosmetic". If you prefer proportional fonts, it's up to you.
     
  12. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
  13. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    More changes to the combo box
    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
    #
    $pswindow = $host.ui.rawui          # create a reference to the console’s UI.RawUI child object
    $pswindow.windowtitle = "Script by: rpo/abbodi1406/BAU/freddie-o [forums.mydigitallife.net]"
    [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
    #
    $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 v1.4'
    $Form.Width=420 ; $Form.Height=180
    $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
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(20,35)
    $USBDiskList.Width=365;$USBDiskList.height=20;$USBDiskList.Font='Courier New,9'
    $Form.Controls.Add($SelectUSBDisk)
    $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("Plug in your USB disk first, then click ""OK"", to continue. `r`n`r`nTo close this script, click ""Cancel"".",0,"Plug in the USB disk",1+64)
            if ($result -eq 2) {Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(36," ").substring(0,36)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-38}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-2}({1,1}:){2,-25}[{3:n2} GB]" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }     
            }
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    
    $SelectUSB=New-Object System.Windows.Forms.Label # Put the SelectUSB label on the form
    $SelectUSB.Location=New-Object System.Drawing.Size(20,18)
    $SelectUSB.Text="Select USB disk"
    $SelectUSB.width=380;$SelectUSB.height=15;
    $Form.Controls.Add($SelectUSB)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(295,100)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,20)
    $SelectISOButton.width=90;$SelectISOButton.height=25;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(190,100)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=90;$CancelButton.height=25;
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    #
    if ($form.ShowDialog() -eq "Cancel"){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    if ($FileBrowser.ShowDialog() -eq "Cancel"){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $ImagePath = $FileBrowser.FileName;
    if ($ImagePath -eq ""){$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    $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("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #
    $Result=$wshell.Popup("Warning! Your USB disk will be converted to MBR scheme, repartitioned and reformatted. All data will be lost. `r`n`r`nAre you sure you want to continue? `r`n`r`nTo continue, click ""Yes"". To close this script, click ""No"".",0,"Create the Windows installation disk",4+48)
    if ($result -eq 7) {DisMount-DiskImage -ImagePath $ImagePath |out-null;$wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    set-disk $usb -partitionstyle mbr
    Stop-Service ShellHWDetection |out-null
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive | 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
    $wshell.Popup("The Windows Installation Disk is complete.",0,"Complete",0+64) | Out-Null;exit
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    
    
     
  14. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    #160 rpo, Aug 22, 2019
    Last edited: Aug 22, 2019
    Following is the script i use for my own usage.
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Windows Installation Disk v?.? by: rpo/abbodi1406/BAU/freddie-o [forums.mydigitallife.net]
    @set "ScriptPath=%~f0" &set "__ARGS__=%*" &powershell -noprofile -c "iex(Get-Content('%~f0') -raw)" &exit/b
    #>
    #
    #    This script must be executed with admin privilege
    #
    #    Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
    #    Restart the script to get Administrator privileges and exit
         Start-Process cmd -ArgumentList ("/c call `"$Env:ScriptPath`" $Env:__ARGS__") -Verb runAs
         exit
    }
    #    We have Administrator privileges
    $Env:ScriptPath=$Env:__ARGS__=""  # delete environment variables
    #
    $pswindow = $host.ui.rawui          # create a reference to the console’s UI.RawUI child object
    # $newsize = $pswindow.buffersize   # set the buffer size
    # $newsize.height = 3000            # 3000 lines
    # $newsize.width = 150                # 150 characters
    # $pswindow.buffersize = $newsize    # set the BufferSize properties
    # $newsize = $pswindow.buffersize   # assign the BufferSize properties to a variable named $newsize
    # $pswindow.buffersize = $newsize    # assign the values to the actual console window
    # $newsize = $pswindow.windowsize    # set the window size
    # $newsize.height = [Math]::Min(50, $host.ui.rawui.MaxWindowSize.height)
    # $newsize.width = [Math]::Min(150, $host.ui.rawui.MaxWindowSize.Width)
    # $pswindow.windowsize = $newsize
    $pswindow.windowtitle = "Windows Installation Disk v?.? by: rpo/abbodi1406/BAU/freddie-o [forums.mydigitallife.net]"
    [console]::ForegroundColor = "Yellow"
    [console]::BackgroundColor = "blue"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    Function Get-FileName
    {  
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
       title="Select your ISO image file"
    #   ShowHelp = $True
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    IF ($FileBrowser.ShowDialog() -eq "Cancel"){Cancel}
    $FileBrowser.filename    # return the file name
    }
    $wshell=New-Object -ComObject Wscript.Shell
    #
    # .Net methods for hiding/showing the console in the background
    Add-Type -Name Window -Namespace Console -MemberDefinition '
    [DllImport("Kernel32.dll")]
    public static extern IntPtr GetConsoleWindow();
    
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
    '
    # Hide = 0,
    # ShowNormal = 1,
    # ShowMinimized = 2,
    # ShowMaximized = 3,
    # Maximize = 3,
    # ShowNormalNoActivate = 4,
    # Show = 5,
    # Minimize = 6,
    # ShowMinNoActivate = 7,
    # ShowNoActivate = 8,
    # Restore = 9,
    # ShowDefault = 10,
    # ForceMinimized = 11
    #
    function Show-Console
    {
        $consolePtr = [Console.Window]::GetConsoleWindow()
        [Console.Window]::ShowWindow($consolePtr, 1)
    }
    function Hide-Console
    {
        $consolePtr = [Console.Window]::GetConsoleWindow()
        [Console.Window]::ShowWindow($consolePtr, 0)
    }
    Function Cancel
    {
        $wshell.Popup("The script was cancelled.",2,"Cancel script",0+64) | Out-Null
        [Environment]::Exit(1)
    }
    clear-host
    #
    $Global:ImagePath=""
    $USB=$Null
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    # Set the size of the window:
    # $Form.FormBorderStyle = "none"
    $Form.ControlBox = $False
    $Form.Text="Select USB disk and ISO image file"
    $Form.Width=490 ; $Form.Height=250
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    $Form.KeyPreview = $True
    $Form.Add_KeyDown({if ($_.KeyCode -eq "Enter"){$OKButton.PerformClick()}})         # Enter = click OK button
    $Form.Add_KeyDown({if ($_.KeyCode -eq "Escape"){$CancelButton.PerformClick()}})    # Escape = click on Cancel button
    $Form.BackColor = "Blue"
    
    $OKButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $OKButton.Location=New-Object System.Drawing.Size(295,175)
    $OKButton.Text="OK"
    $OKButton.Font='Default Font,9'
    $OKButton.Size=New-Object System.Drawing.Size(120,20)
    $OKButton.width=130
    $OKButton.height=25
    $OKButton.Backcolor = [System.Drawing.Color]::LightGray
    $OKButton.Add_MouseHover({$OKButton.backcolor = [System.Drawing.Color]::LightGreen})
    $OKButton.Add_MouseLeave({$OKButton.backcolor = [System.Drawing.Color]::LightGray})
    $Form.Controls.Add($OKButton)
    $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(155,175)
    $CancelButton.Text="Cancel"
    $CancelButton.Font='Default Font,9'
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=130
    $CancelButton.height=25;
    $CancelButton.Backcolor = [System.Drawing.Color]::LightGray
    $CancelButton.Add_MouseHover({$CancelButton.backcolor = [System.Drawing.Color]::Red})
    $CancelButton.Add_MouseLeave({$CancelButton.backcolor = [System.Drawing.Color]::LightGray})
    $Form.Controls.Add($CancelButton)
    # $CancelButton.Add_Click({$Form.Close();cancel})
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(30,15)
    $SelectUSBDisk.Font='Consolas,10'
    $SelectUSBDisk.width=400
    $SelectUSBDisk.height=30
    $SelectUSBDisk.ForeColor = [System.Drawing.Color]::White
    $Form.Controls.Add($SelectUSBDisk)
    
    $SelectISO=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectISO.Location=New-Object System.Drawing.Size(30,110)
    $SelectISO.Font='Consolas,10'
    $SelectISO.width=400
    $SelectISO.height=30
    $SelectISO.text="Select the ISO image file :"
    $SelectISO.ForeColor = [System.Drawing.Color]::White
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(415,140)
    $SelectISOButton.Text="ISO"
    $SelectISOButton.Font='Default Font,7'
    $SelectISOButton.Size=New-Object System.Drawing.Size(20,20)
    $SelectISOButton.width=30
    $SelectISOButton.height=20;
    $SelectISOButton.Backcolor = [System.Drawing.Color]::LightGray
    $SelectISOButton.Add_MouseHover({$SelectISOButton.backcolor = [System.Drawing.Color]::LightGreen})
    $SelectISOButton.Add_MouseLeave({$SelectISOButton.backcolor = [System.Drawing.Color]::LightGray})
    
    $ISOFile=New-Object System.Windows.Forms.Label # Put the ISO file name on the form
    $ISOFile.Location=New-Object System.Drawing.Size(30,140)
    $ISOFile.Text=" "
    $ISOFile.Font='Courier New,10'
    $ISOFile.Size=New-Object System.Drawing.Size(20,20)
    $ISOFile.width=385
    $ISOFile.height=20;
    $ISOFile.Backcolor = [System.Drawing.Color]::White
    $ISOFile.ForeColor = [System.Drawing.Color]::Black
    
    $Warning=New-Object System.Windows.Forms.Label
    $Warning.Location=New-Object System.Drawing.Size(30,15)
    $Warning.Font='Consolas,10'
    $Warning.width=430
    $Warning.height=75
    $Warning.text="All partitions and data on the USB disk will be lost! `r`n`r`nAre you sure you want to start creating the Windows installation disk?"
    $Warning.ForeColor = [System.Drawing.Color]::White
    
    #
    #    Select the USB disk
    # Create a drop-down list and fill it
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $USBDiskList.Location=New-Object System.Drawing.Point(30,45)
    $USBDiskList.Width=415
    $USBDiskList.height=20
    $USBDiskList.Font='Courier New,10'
    $Form.Controls.Add($SelectUSBDiskList)
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    Hide-Console # Hide console display
    
    While (!$Disks) {
        $SelectUSBDisk.Text="Please mount USB disk. Click ""OK"" when ready`r`nor ""Cancel"" to exit."
        if ($form.ShowDialog() -eq "Cancel"){cancel}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    
    $Form.Controls.Add($SelectISO)
    $Form.Controls.Add($ISOFile)
    $Form.Controls.Remove($OKButton)
    $SelectISOButton.Add_Click(
        {$Global:ImagePath = Get-FileName # get the iso image path with file browser dialog
         $ImagePath= Split-Path -Path $Global:ImagePath -leaf # extract filename and extension (iso)
         $ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."
         $OKButton.Text="Create USB disk"
         $Form.Controls.Add($OKButton)})
       
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(40," ").substring(0,40)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-41}|{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $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,-7}({1,1}:){2,-3}|{3:n2} GB" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }    
            }
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    
    $SelectUSBDisk.Text="Select the USB disk/partition :"
    #
    $Form.Controls.Add($SelectISOButton)
    #
    if ($form.ShowDialog() -eq "Cancel") {Cancel}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    # Mount the image file if not already mounted and get the drive letter
    #
    if (ImagePath -eq ""){Cancel} # this can't happen, but keep the test
    #  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 ":") {Cancel}
    #
    # Ready to create the USB disk. Ask for confirmation
    #
    $Form.Controls.Remove($USBDiskList)
    $Form.Controls.Remove($SelectUSBDisk)
    $Form.Controls.Remove($SelectISOButton)
    $Form.Controls.Remove($ISOFile)
    $Form.Controls.Remove($SelectISO)
    $OKButton.Text="Continue"
    $Form.Controls.Add($OKButton)
    $Form.Controls.Add($Warning)
    if ($form.ShowDialog() -eq "Cancel") {DisMount-DiskImage -ImagePath $ImagePath |out-null;Cancel}
    Clear-Host
    $pswindow.windowtitle = "Create Windows Installation Disk"
    Show-Console | Out-Null # Restore console display
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    set-disk $usb -partitionstyle mbr
    Stop-Service ShellHWDetection  |out-null
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size  1GB -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection |out-null
    #
    robocopy $iso $usbntfs /e /xf $iso\boot\bcd $iso\efi\microsoft\boot\bcd
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e /xf $iso\boot\bcd
    robocopy $iso"\efi" $usbfat32"\efi" /e /xf $iso\efi\microsoft\boot\bcd
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    
    Copy-Item $ISO"\boot\bcd" $env:temp -Force
    & bcdedit /store ($env:temp + "\bcd") /set '{default}' bootmenupolicy Legacy
    Set-ItemProperty -Path ($env:temp + "\bcd") -Name IsReadOnly -Value $true
    Copy-Item ($env:temp + "\bcd") $usbfat32"\boot\bcd" -Force
    Copy-Item ($env:temp + "\bcd") $usbntfs"\boot\bcd" -Force
    Copy-Item $ISO"\EFI\Microsoft\boot\bcd" $env:temp -Force
    & bcdedit /store ($env:temp + "\bcd") /set '{default}' bootmenupolicy Legacy
    Set-ItemProperty -Path ($env:temp + "\bcd") -Name IsReadOnly -Value $true
    Copy-Item ($env:temp + "\bcd") $usbfat32"\EFI\Microsoft\boot\bcd" -Force
    Copy-Item ($env:temp + "\bcd") $usbntfs"\EFI\Microsoft\boot\bcd" -Force
    remove-item ($env:temp + "\bcd") -force
    remove-item ($env:temp + "\bcd.*") -force
    
    # Eject the mounted iso image
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    $wshell.Popup("The Windows Installation Disk is complete.",0,"Complete",0+64) | Out-Null
    #done - keep a comment on the last line so the previous useful crlf never gets eaten