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

Discussion in 'MDL Projects and Applications' started by rpo, Mar 18, 2019.

  1. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    Do you mean hide the USB hard disk as shown by post #407?
    You want only keep the USB devices defined as "Removable Media" (the USB hard disks are considered as fixed disks) , right?
     
  2. garf02

    garf02 MDL Member

    Sep 15, 2007
    189
    73
    10
    Yes, i want to keep only the Removable Media. But if it is not possible to do so, I will be careful which peripheral I select
     
  3. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    #423 rpo, Feb 26, 2025
    Last edited: Feb 27, 2025
    (OP)
    Try the following script :
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Win10+ Setup Disk 3.2&color 3E
    @powershell -noprofile "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))" &exit/b
    #>
    $OnlyUSBsticks=$False
    #              $False    # All USB connected devices
    #              $True    # Only USB sticks
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    #   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"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        if ($param -eq $uac_error) {
        read-host "$uac_error`r`nRight click on the script and select ""Run as administrator""`r`nPress Enter to exit...";exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    $pswindow = $host.ui.rawui          # create a reference to the console’s UI.RawUI child object
    $title=$pswindow.windowtitle -Replace "^.*:\s+"
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function MsgBox {[System.Windows.Forms.MessageBox]::Show($Args[0],$Title,$Args[1],$Args[2])}
    #
    Function Update_bcd ($usbpartition)
    {
    #    Set bootmenupolicy Legacy for $usbpartition
    bcdedit /store "$usbpartition\boot\bcd" /set '{default}' bootmenupolicy Legacy |Out-Null
    bcdedit /store "$usbpartition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy |Out-Null
    remove-item "$usbpartition\boot\bcd.*" -force
    remove-item "$usbpartition\EFI\Microsoft\boot\bcd.*" -force
    }
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    #$Form.ShowIcon=$False
    $Form.ControlBox=$False
    # Set the title and size of the window:
    $Form.Text="$Title"
    $Form.Font='Consolas,10'
    $Form.Width=1 ; $Form.Height=1 # AutoSize determines the minumum window size
    $Form.AutoSize = $True 
    $Form.StartPosition = "CenterScreen"
    $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.SizeGripStyle = "Hide"
    $form.FormBorderStyle = 'Fixed3D'
    $form.ShowInTaskbar = $False
    #$form.MaximizeBox = $False
    #$form.MinimizeBox = $False
    $Form.TopMost = $True
    
    [System.Windows.Forms.Application]::EnableVisualStyles();
    #
    # Add usage informations
    $Usage=New-Object System.Windows.Forms.Label
    $Usage.Font='Arial,9'
    $Usage.Location=New-Object System.Drawing.Point(7,10)
    $Usage.AutoSize=$True
    $Usage.text=@"
    1. Click "Select ISO" to select your source Windows ISO`r`n
    2. Select your "Target USB disk" from the drop-down menu`r`n
    3. Click "Create Setup Disk" to start creating your Windows setup disk
    "@
    $Usage.Size=New-Object System.Drawing.Size(404,65)
    $Usage.Backcolor = "LightBlue"
    $Usage.BorderStyle = 'Fixed3D'
    $Form.Controls.Add($Usage)
    #
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,110)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,130)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = [System.Drawing.Color]::White
    $ISOFile.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle
    $Form.Controls.Add($ISOFile)
    
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,180)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    
    # Create a USB Disk 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,200)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    #
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    If(!$OnlyUSBsticks){$filter="$filter or MediaType='External hard disk media'"}
    #
    $Disks=$Null;While(!($Disks=Get-CimInstance -ClassName `
        Win32_DiskDrive -Filter $filter)){   
        If((MsgBox "Plug in your USB disk first. `n`nClick OK to continue." `
            "OKCancel" "Information") -eq "Cancel"){exit}}
    #
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,265)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,265)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,265)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    #
    $SelectISOButton.Add_Click({
        If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
            $Global:ImagePath = $FileBrowser.filename    # return the file name
            $ISOFile.Text= Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
            if (($ISOFile.Text).length -gt 44) {$ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."}
            $CreateDiskButton.Enabled = $true
            $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.Caption).PadRight(40," ").substring(0,35)
        $USBDisks+=$USBDisk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
    <#
        Foreach ($Partition in (Get-Partition $USBDisk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "} Else {$AccessPath=$Partition.DriveLetter+":"}   
            $USBDisks+=$USBDisk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|Get-Volume).FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,90)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,215)
    $Form.Controls.Add($Groupbox)
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg="WARNING! `n`nYour USB disk will be converted to MBR scheme, repartitioned and reformatted.`n`nAll partitions and data currently stored in the USB disk will be erased.`r`n`r`nAre you sure you want to continue?"
    If((MsgBox $msg "YESNO" "Warning") -eq "NO"){exit}
    # Mount the image file if not already mounted and get the drive letter
    #
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter){$Mounted=$True}    Else
    #    Mount iso and get drive letter
        {$Mounted=$False; Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
         If(!($ISO=(Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Clear-Host
    Stop-Service ShellHWDetection -erroraction silentlycontinue|out-null
    #    Clear the USB disk
    Try{Clear-Disk $USB -RemoveData -RemoveOEM -Confirm:$False -ErrorAction Stop
        Set-Disk $USB -PartitionStyle MBR -ErrorAction Stop}
    Catch{"Select disk $USB`nclean`nconvert MBR`nrescan`nexit`n"|diskpart}
    #   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 "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue|out-null
    #    Copy needed files to the fat32 boot partition
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi /a-:R
    robocopy $iso"\boot" $usbfat32"\boot" /e /a-:R
    robocopy $iso"\efi" $usbfat32"\efi" /e /a-:R
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim /a-:R
    Update_BCD $usbfat32
    #     Remove the drive letter to hide the device
    Get-Volume -DriveLetter $usbfat32.substring(0,$usbfat32.Length-1) | Get-Partition | Remove-PartitionAccessPath -accesspath $usbfat32
    #    Copy needed files to the NTFS install partition
    robocopy $iso $usbntfs /e   /a-:R
    Update_BCD $usbntfs
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage -ImagePath $ImagePath |out-null}
    MsgBox "$Title was created successfully." "OK" "Information" >$Null;exit
    

    Replace line 5 :
    Code:
    $OnlyUSBsticks=$False
    by :
    Code:
    $OnlyUSBsticks=$True
    and let me know.
     
  4. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    This is an update of post #420
    The value of the variable $OnlyUSBsticks defines at script line 5 determines if only USB stick are taking into account or if USB connected HDD/SDD are also eligible.

    Code:
    $OnlyUSBsticks=$TRUE  : only USB sticks
    $OnlyUSBsticks=$FALSE  : USB sticks and external HDD/SSDconnected on a USB port 
    It is also possible to select preference at runtime. Search the string :

    Code:
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    and remove the # character to uncomment the statement.

    At runtime a pop-up screen displays :

    Consider only USB sticks and ignore external disks ?

    Clicking "YES" sets $OnlyUSBsticks=$TRUE
    Clicking "NO" sets $OnlyUSBsticks=$False

    The following screenshot illustrtates the case $OnlyUSBsticks=$FALSE
    upload_2025-3-10_15-30-37.png

    IMHO, using a HDD/SSD is not the best solution; I suggest creating a customized WinPE device and copying Windows ISO images on the ntfs partition.

    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @powershell -noprofile -c "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))"&exit/b
    #> 
    $title="Win10+ Setup Disk 3.2"
    $OnlyUSBsticks=$False
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    $host.ui.rawui.windowtitle=$title
    #
    $Host.UI.RawUI.BackgroundColor = "Blue"
    $Host.UI.RawUI.ForegroundColor = "White"
    Clear-Host
    #
    Add-Type -AssemblyName Microsoft.VisualBasic
    Function MsgBox {
    # learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
    [Microsoft.VisualBasic.Interaction]::MsgBox(
        $Args[0],"$($Args[1]),$($Args[2]),SystemModal",$title)}
    #   
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        If($param -eq $uac_error){
            $msg="$uac_error.`r`nRight click on the script and select ""Run as administrator""."
            MsgBox $msg    "OKOnly" "Critical" >$Null;exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false                 # Only one file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function Update_bcd ($partition){
    #    Set bootmenupolicy Legacy for $partition
    bcdedit /store "$partition\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    bcdedit /store "$partition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    remove-item "$partition\boot\bcd.*" -force
    remove-item "$partition\EFI\Microsoft\boot\bcd.*" -force
    }
    # **************************************************
    $msg="Consider only USB sticks and ignore external disks ?"
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    # YES : consider only usb sticks
    # NO  : consider usb sticks and external disks
    $OnlyUSBsticks="NO"
    # To ask user's preference, uncomment the following statement
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    If($OnlyUSBsticks -eq "NO"){$filter="$filter or MediaType='External hard disk media'"}
    # **************************************************
    $delay=20
    While(!($Disks=Get-CimInstance -ClassName Win32_DiskDrive -Filter $filter)){
        $msg="Plug in your USB disk first.`n`nRetry after $delay s or  Cancel  to exit."
        If((MsgBox $msg    "RetryCancel" "Question") -eq "Cancel"){exit}
        Start-Sleep $delay >$Null}
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    #$Form.ShowIcon=$False
    $Form.ControlBox=$False
    # Set the title and size of the window :
    $Form.Text="$Title"
    $Form.Font='Consolas,10'
    $Form.Width=$Form.Height=1 # AutoSize determines the minumum window size
    $Form.AutoSize = $True
    $Form.StartPosition = "CenterScreen"
    $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.SizeGripStyle = "Hide"
    $form.FormBorderStyle = 'Fixed3D'
    $form.ShowInTaskbar = $False
    #$form.MaximizeBox = $False
    #$form.MinimizeBox = $False
    [System.Windows.Forms.Application]::EnableVisualStyles();
    #
    # Add usage informations
    $Usage=New-Object System.Windows.Forms.Label
    $Usage.Font='Arial,9'
    $Usage.Location=New-Object System.Drawing.Point(7,10)
    $Usage.AutoSize=$True
    $Usage.text=@"
    1. Click "Select ISO" to select your source Windows ISO`r`n
    2. Select your "Target USB disk" from the drop-down menu`r`n
    3. Click "Create Setup Disk" to start creating your Windows setup disk
    "@
    $Usage.Size=New-Object System.Drawing.Size(404,65)
    $Usage.Backcolor = "White"
    $Usage.BorderStyle = 'Fixed3D'
    $Form.Controls.Add($Usage)
    #
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,110)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    #
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,130)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = "White"
    $ISOFile.BorderStyle = "FixedSingle"
    $Form.Controls.Add($ISOFile)
    #
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,180)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    #
    # Create a USB Disk 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,200)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    #
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,265)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    #
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,265)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = "OK"
    #
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,265)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = "Cancel"
    #
    $SelectISOButton.Add_Click({
    If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
        $Global:ImagePath=$FileBrowser.filename    # return the file name
        $ISOFile.Text=Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
        if(($ISOFile.Text).length -gt 44){
            $ISOFile.Text=$ImagePath.PadRight(100).substring(0,43)+"..."}
        $CreateDiskButton.Enabled = $true
        $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($Disk in $Disks){
        $FriendlyName=($Disk.Caption).PadRight(40).substring(0,35)
        $USBDisks+=$Disk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($Disk.Size/1GB))) >$Null
    <#
        Foreach ($Partition in (Get-Partition $Disk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "}Else{$AccessPath=$Partition.DriveLetter+":"}   
            $USBDisks+=$Disk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|
                Get-Volume).FileSystemLabel.PadRight(25).substring(0,25),($Partition.Size/1GB))) >$Null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,90)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,215)
    $Form.Controls.Add($Groupbox)
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg=@"
    WARNING!`r`n
    Your USB disk will be converted to MBR scheme, repartitioned and reformatted.
    All partitions and data currently stored in the USB disk will be erased.`r`n
    Are you sure you want to continue?
    "@
    If((MsgBox $msg "YESNO" "Exclamation") -eq "NO"){exit}
    "`r`nMount/Check if mounted the ISO image file"
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter){$Mounted=$True}Else
    #    Mount iso and get drive letter
        {$Mounted=$False;Mount-DiskImage $ImagePath >$Null
         If(!($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Stop-Service ShellHWDetection -ErrorAction SilentlyContinue >$Null
    $ProgressPreference="SilentlyContinue"
    "`r`nClear the USB disk and set MBR partition with diskpart"
    @"
    Select disk $USB
    clean
    convert MBR
    exit
    "@|diskpart >$Null
    If($LASTEXITCODE -ne 0){
        $msg="Diskpart operations failed with error code $LASTEXITCODE."
        MsgBox $msg "OKOnly" "Critical" >$Null
        exit}
    "`r`nCreate the FAT32 boot partition"
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter|
        Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    "`r`nCreate the NTFS setup partition & set active"
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive|
        Format-Volume -FileSystem NTFS -NewFileSystemLabel "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue >$Null
    "`r`nCopy needed files to the fat32 boot partition $usbfat32"
    robocopy "$iso\" "$usbfat32\" bootmgr.* /a-:R /NJH /NJS
    robocopy "$iso\boot" "$usbfat32\boot" /e /a-:R /NJH /NJS
    robocopy "$iso\efi" "$usbfat32\efi" /e /a-:R /NJH /NJS
    robocopy "$iso\sources" "$usbfat32\sources" boot.wim /a-:R /NJH /NJS
    Update_BCD $usbfat32
    "`r`nRemove the drive letter to hide the fat32 partition"
    Get-Volume ($usbfat32 -replace ".$")|Get-Partition|
        Remove-PartitionAccessPath -accesspath $usbfat32
    "`r`nCopy needed files to the NTFS install partition $usbntfs"
    robocopy $iso $usbntfs /e /a-:R /NJH /NJS
    Update_BCD $usbntfs
    bootsect /nt60 $usbntfs /force /mbr >$Null
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage $ImagePath >$Null}
    MsgBox "$Title was created successfully." "OKOnly" "Information" >$Null
    
    
     
  5. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    #426 freddie-o, Mar 10, 2025
    Last edited: Mar 10, 2025

    Is it doable to hide the console window altogether and just use the GUI Window for the whole process?
    Where the progess of the script will show in the GUI Window instead of the console window?

    We can uncomment these line so the user does not have to concern themselves with it anymore
    Code:
    $OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    I only added these lines because the console windows was already there
    Code:
    1.) Click "Select ISO" to select your source Windows ISO
    
    2.) Select your "Target USB disk" from the drop-down menu
    
    3.) Click "Create Setup Disk" to start creating your Windows setup disk
    Do you think these lines are even needed?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    Just try and enjoy :

    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @powershell -noprofile -Window Hidden -c "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))"&exit/b
    #> 
    $title="Win10+ Setup Disk 3.2"
    $OnlyUSBsticks=$False
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    $host.ui.rawui.windowtitle=$title
    #
    $Host.UI.RawUI.BackgroundColor = "Blue"
    $Host.UI.RawUI.ForegroundColor = "White"
    Clear-Host
    #
    Add-Type -AssemblyName Microsoft.VisualBasic
    Function MsgBox {
    # learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
    [Microsoft.VisualBasic.Interaction]::MsgBox(
        $Args[0],"$($Args[1]),$($Args[2]),SystemModal",$title)}
    #   
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        If($param -eq $uac_error){
            $msg="$uac_error.`r`nRight click on the script and select ""Run as administrator""."
            MsgBox $msg    "OKOnly" "Critical" >$Null;exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false                 # Only one file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function Update_bcd ($partition){
    #    Set bootmenupolicy Legacy for $partition
    bcdedit /store "$partition\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    bcdedit /store "$partition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    remove-item "$partition\boot\bcd.*" -force
    remove-item "$partition\EFI\Microsoft\boot\bcd.*" -force
    }
    # **************************************************
    $msg="Consider only USB sticks and ignore external disks ?"
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    # YES : consider only usb sticks
    # NO  : consider usb sticks and external disks
    $OnlyUSBsticks="NO"
    # To ask user's preference, uncomment the following statement
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    If($OnlyUSBsticks -eq "NO"){$filter="$filter or MediaType='External hard disk media'"}
    # **************************************************
    $delay=20
    While(!($Disks=Get-CimInstance -ClassName Win32_DiskDrive -Filter $filter)){
        $msg="Plug in your USB disk first.`n`nRetry after $delay s or  Cancel  to exit."
        If((MsgBox $msg    "RetryCancel" "Question") -eq "Cancel"){exit}
        Start-Sleep $delay >$Null}
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    # Set the title and size of the window:
    $Form.Text=$ShortTitle
    $Form.Font='Consolas,10'
    $Form.Width=420 ; $Form.Height=270
    $Form.StartPosition = "CenterScreen"
    $Form.SizeGripStyle = "Hide"
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,30)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,50)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = [System.Drawing.Color]::White
    $ISOFile.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle
    $Form.Controls.Add($ISOFile)
    
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,100)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    
    # Create a USB Disk 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,120)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    $USBDisks=@() # array with USB disk number
    
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,185)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,185)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,185)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    #
    $SelectISOButton.Add_Click({
        If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
            $Global:ImagePath = $FileBrowser.filename    # return the file name
            $ISOFile.Text= Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
            if (($ISOFile.Text).length -gt 44) {$ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."}
            $CreateDiskButton.Enabled = $true
            $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($Disk in $Disks){
        $FriendlyName=($Disk.Caption).PadRight(40).substring(0,35)
        $USBDisks+=$Disk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($Disk.Size/1GB))) >$Null
    <#
        Foreach ($Partition in (Get-Partition $Disk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "}Else{$AccessPath=$Partition.DriveLetter+":"}   
            $USBDisks+=$Disk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|
                Get-Volume).FileSystemLabel.PadRight(25).substring(0,25),($Partition.Size/1GB))) >$Null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,0)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,225)
    $Form.Controls.Add($Groupbox)
    #
    $msg=@"
    
    1.) Click "Select ISO" to select your source Windows ISO
    
    2.) Select your "Target USB disk" from the drop-down menu
    
    3.) Click "Create Setup Disk" to start creating your Windows setup disk
    "@
    #$msg
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg=@"
    WARNING!`r`n
    Your USB disk will be converted to MBR scheme, repartitioned and reformatted.
    All partitions and data currently stored in the USB disk will be erased.`r`n
    Are you sure you want to continue?
    "@
    If((MsgBox $msg "YESNO" "Exclamation") -eq "NO"){exit}
    #"`r`nMount/Check if mounted the ISO image file"
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter){$Mounted=$True}Else
    #    Mount iso and get drive letter
        {$Mounted=$False;Mount-DiskImage $ImagePath >$Null
         If(!($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Stop-Service ShellHWDetection -ErrorAction SilentlyContinue >$Null
    $ProgressPreference="SilentlyContinue"
    #"`r`nClear the USB disk and set MBR partition with diskpart"
    @"
    Select disk $USB
    clean
    convert MBR
    exit
    "@|diskpart >$Null
    If($LASTEXITCODE -ne 0){
        $msg="Diskpart operations failed with error code $LASTEXITCODE."
        MsgBox $msg "OKOnly" "Critical" >$Null
        exit}
    #"`r`nCreate the FAT32 boot partition"
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter|
        Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #"`r`nCreate the NTFS setup partition & set active"
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive|
        Format-Volume -FileSystem NTFS -NewFileSystemLabel "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue >$Null
    #"`r`nCopy needed files to the fat32 boot partition $usbfat32"
    robocopy "$iso\" "$usbfat32\" bootmgr.* /a-:R /NJH /NJS  >$Null
    robocopy "$iso\boot" "$usbfat32\boot" /e /a-:R /NJH /NJS >$Null
    robocopy "$iso\efi" "$usbfat32\efi" /e /a-:R /NJH /NJS >$Null
    robocopy "$iso\sources" "$usbfat32\sources" boot.wim /a-:R /NJH /NJS >$Null
    Update_BCD $usbfat32
    #"`r`nRemove the drive letter to hide the fat32 partition"
    Get-Volume ($usbfat32 -replace ".$")|Get-Partition|
        Remove-PartitionAccessPath -accesspath $usbfat32
    #"`r`nCopy needed files to the NTFS install partition $usbntfs"
    robocopy $iso $usbntfs /e /a-:R /NJH /NJS >$Null
    Update_BCD $usbntfs
    bootsect /nt60 $usbntfs /force /mbr >$Null
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage $ImagePath >$Null}
    MsgBox "$Title was created successfully." "OKOnly" "Information" >$Null
    
    
     
  7. shhnedo

    shhnedo MDL Expert

    Mar 20, 2011
    1,884
    2,528
    60
    @rpo the title of the script window is missing. No progress shown anywhere after pressing Create button(intended?).
     
  8. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    #429 freddie-o, Mar 11, 2025
    Last edited: Mar 11, 2025

    Something like this... and...
    Can we add a "Write-Progress" displaying the activity/progress of the script?


    Edited
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @powershell -noprofile -Window Hidden -c "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))"&exit/b
    #>
    $title="Win10+ Setup Disk 3.2"
    $OnlyUSBsticks=$False
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    $host.ui.rawui.windowtitle=$title
    Add-Type -AssemblyName Microsoft.VisualBasic
    Function MsgBox {
    # learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
    [Microsoft.VisualBasic.Interaction]::MsgBox(
        $Args[0],"$($Args[1]),$($Args[2]),SystemModal",$title)}
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        If($param -eq $uac_error){
            $msg="$uac_error.`r`nRight click on the script and select ""Run as administrator""."
            MsgBox $msg    "OKOnly" "Critical" >$Null;exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false                 # Only one file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function Update_bcd ($partition){
    #    Set bootmenupolicy Legacy for $partition
    bcdedit /store "$partition\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    bcdedit /store "$partition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    remove-item "$partition\boot\bcd.*" -force
    remove-item "$partition\EFI\Microsoft\boot\bcd.*" -force
    }
    # **************************************************
    $msg="Would you like to show only USB sticks and hide external hard disks?"
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    # YES : show only usb sticks
    # NO  : show usb sticks and external hard disks
    $OnlyUSBsticks="NO"
    $OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    If($OnlyUSBsticks -eq "NO"){$filter="$filter or MediaType='External hard disk media'"}
    # **************************************************
    $delay=15
    While(!($Disks=Get-CimInstance -ClassName Win32_DiskDrive -Filter $filter)){
        $msg="No USB sticks were detected. Plug in your USB stick first and retry after $delay seconds or Cancel to exit."
        If((MsgBox $msg    "RetryCancel" "Question") -eq "Cancel"){exit}
        Start-Sleep $delay >$Null}
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    #$Form.ShowIcon=$False
    $Form.ControlBox=$False
    # Set the title and size of the window:
    $Form.Text="$Title"
    $Form.Font='Consolas,10'
    $Form.Width=420 ; $Form.Height=270
    $Form.AutoSize = $True
    $Form.StartPosition = "CenterScreen"
    $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.SizeGripStyle = "Hide"
    $form.ShowInTaskbar = $False
    #$form.MaximizeBox = $False
    #$form.MinimizeBox = $False
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,30)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    #
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,50)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = "White"
    $ISOFile.BorderStyle = "FixedSingle"
    $Form.Controls.Add($ISOFile)
    #
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,100)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    #
    # Create a USB Disk 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,120)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    #
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,185)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    #
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,185)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = "OK"
    #
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,185)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = "Cancel"
    #
    $SelectISOButton.Add_Click({
    If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
        $Global:ImagePath=$FileBrowser.filename    # return the file name
        $ISOFile.Text=Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
        if(($ISOFile.Text).length -gt 44){
            $ISOFile.Text=$ImagePath.PadRight(100).substring(0,43)+"..."}
        $CreateDiskButton.Enabled = $true
        $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($Disk in $Disks){
        $FriendlyName=($Disk.Caption).PadRight(40).substring(0,35)
        $USBDisks+=$Disk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($Disk.Size/1GB))) >$Null
    <#
        Foreach ($Partition in (Get-Partition $Disk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "}Else{$AccessPath=$Partition.DriveLetter+":"}
            $USBDisks+=$Disk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|
                Get-Volume).FileSystemLabel.PadRight(25).substring(0,25),($Partition.Size/1GB))) >$Null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,0)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,225)
    $Form.Controls.Add($Groupbox)
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg=@"
    WARNING!`r`n
    Your USB disk will be converted to MBR scheme, repartitioned and reformatted.`r`n
    All partitions and data currently stored in the USB disk will be erased.`r`n
    Are you sure you want to continue?
    "@
    If((MsgBox $msg "YESNO" "Exclamation") -eq "NO"){exit}
    "`r`nMount/Check if mounted the ISO image file"
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter){$Mounted=$True}Else
    #    Mount iso and get drive letter
        {$Mounted=$False;Mount-DiskImage $ImagePath >$Null
         If(!($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Stop-Service ShellHWDetection -ErrorAction SilentlyContinue >$Null
    $ProgressPreference="SilentlyContinue"
    "`r`nClear the USB disk and set MBR partition with diskpart"
    @"
    Select disk $USB
    clean
    convert MBR
    exit
    "@|diskpart >$Null
    If($LASTEXITCODE -ne 0){
        $msg="Diskpart operations failed with error code $LASTEXITCODE."
        MsgBox $msg "OKOnly" "Critical" >$Null
        exit}
    "`r`nCreate the FAT32 boot partition"
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter|
        Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    "`r`nCreate the NTFS setup partition & set active"
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive|
        Format-Volume -FileSystem NTFS -NewFileSystemLabel "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue >$Null
    "`r`nCopy needed files to the fat32 boot partition $usbfat32"
    robocopy "$iso\" "$usbfat32\" bootmgr.* /a-:R /NJH /NJS
    robocopy "$iso\boot" "$usbfat32\boot" /e /a-:R /NJH /NJS
    robocopy "$iso\efi" "$usbfat32\efi" /e /a-:R /NJH /NJS
    robocopy "$iso\sources" "$usbfat32\sources" boot.wim /a-:R /NJH /NJS
    Update_BCD $usbfat32
    "`r`nRemove the drive letter to hide the fat32 partition"
    Get-Volume ($usbfat32 -replace ".$")|Get-Partition|
        Remove-PartitionAccessPath -accesspath $usbfat32
    "`r`nCopy needed files to the NTFS install partition $usbntfs"
    robocopy $iso $usbntfs /e /a-:R /NJH /NJS
    Update_BCD $usbntfs
    bootsect /nt60 $usbntfs /force /mbr >$Null
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage $ImagePath >$Null}
    MsgBox "$Title was created successfully." "OKOnly" "Information" >$Null
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    #430 rpo, Mar 11, 2025
    Last edited: Mar 11, 2025
    (OP)
    My proposal :

    The value of the variable $OnlyUSBsticks defines at script line 5 determines if only USB stick are taking into account or if USB connected HDD/SDD are also eligible.

    Code:
    $OnlyUSBsticks="YES"  : only USB sticks (default)
    $OnlyUSBsticks="NO"  : USB sticks and external HDD/SSDconnected on a USB port 
    It is also possible to select preference at runtime. Search the string :

    Code:
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    and remove the # character to uncomment the statement.

    At runtime a pop-up screen displays :

    Consider only USB sticks and ignore external disks ?

    Clicking "YES" sets $OnlyUSBsticks="YES"
    Clicking "NO" sets $OnlyUSBsticks="NO"

    Hiding the console is too drastic; hence I propose to minimize the console; click on the shortcut in the taskbar to restore it to show the progress.
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Win10+ Setup Disk 3.2 &color 3E
    @powershell -noprofile -Window Minimized -c "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))"&exit/b
    #>
    $OnlyUSBsticks="NO"
    #
    $host.ui.rawui.windowtitle = ($title=$host.ui.rawui.windowtitle -replace "^.*  ")
    #
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    Add-Type -AssemblyName Microsoft.VisualBasic
    Function MsgBox {
    # learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
    [Microsoft.VisualBasic.Interaction]::MsgBox(
        $Args[0],"$($Args[1]),$($Args[2]),SystemModal",$title)}
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        If($param -eq $uac_error){
            $msg="$uac_error.`r`nRight click on the script and select ""Run as administrator""."
            MsgBox $msg    "OKOnly" "Critical" >$Null;exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false                 # Only one file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function Update_bcd ($partition){
    #    Set bootmenupolicy Legacy for $partition
    bcdedit /store "$partition\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    bcdedit /store "$partition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    remove-item "$partition\boot\bcd.*" -force
    remove-item "$partition\EFI\Microsoft\boot\bcd.*" -force
    }
    # **************************************************
    $msg="Would you like to show only USB sticks and hide external hard disks?"
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    # YES : show only usb sticks
    # NO  : show usb sticks and external hard disks
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    If($OnlyUSBsticks -eq "NO"){$filter="$filter or MediaType='External hard disk media'"}
    # **************************************************
    $delay=15
    While(!($Disks=Get-CimInstance -ClassName Win32_DiskDrive -Filter $filter)){
        $msg="No USB sticks were detected. Plug in your USB stick first and retry after $delay seconds or Cancel to exit."
        If((MsgBox $msg    "RetryCancel" "Question") -eq "Cancel"){exit}
        Start-Sleep $delay >$Null}
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    $Form.ShowIcon=$False
    $Form.ControlBox=$False
    # Set the title and size of the window:
    $Form.Text="$Title"
    $Form.Font='Consolas,10'
    $Form.Width=$Form.Height=1 # AutoSize determines the minumum window size
    $Form.AutoSize = $True
    $Form.StartPosition = "CenterScreen"
    $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.SizeGripStyle = "Hide"
    $form.ShowInTaskbar = $False
    #$form.MaximizeBox = $False
    #$form.MinimizeBox = $False
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,30)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    #
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,50)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = "White"
    $ISOFile.BorderStyle = "FixedSingle"
    $Form.Controls.Add($ISOFile)
    #
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,100)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    #
    # Create a USB Disk 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,120)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    #
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,185)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    #
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,185)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = "OK"
    #
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,185)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = "Cancel"
    #
    $SelectISOButton.Add_Click({
    If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
        $Global:ImagePath=$FileBrowser.filename    # return the file name
        $ISOFile.Text=Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
        if(($ISOFile.Text).length -gt 44){
            $ISOFile.Text=$ImagePath.PadRight(100).substring(0,43)+"..."}
        $CreateDiskButton.Enabled = $true
        $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($Disk in $Disks){
        $FriendlyName=($Disk.Caption).PadRight(40).substring(0,35)
        $USBDisks+=$Disk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($Disk.Size/1GB))) >$Null
    <#
        Foreach ($Partition in (Get-Partition $Disk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "}Else{$AccessPath=$Partition.DriveLetter+":"}
            $USBDisks+=$Disk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|
                Get-Volume).FileSystemLabel.PadRight(25).substring(0,25),($Partition.Size/1GB))) >$Null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,0)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,225)
    $Form.Controls.Add($Groupbox)
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg=@"
    WARNING!`r`n
    Your USB disk will be converted to MBR scheme, repartitioned and reformatted.`r`n
    All partitions and data currently stored in the USB disk will be erased.`r`n
    Are you sure you want to continue?
    "@
    If((MsgBox $msg "YESNO" "Exclamation") -eq "NO"){exit}
    "`r`nMount/Check if mounted the ISO image file"
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter){$Mounted=$True}Else
    #    Mount iso and get drive letter
        {$Mounted=$False;Mount-DiskImage $ImagePath >$Null
         If(!($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Stop-Service ShellHWDetection -ErrorAction SilentlyContinue >$Null
    $ProgressPreference="SilentlyContinue"
    "`r`nClear the USB disk and set MBR partition with diskpart"
    @"
    Select disk $USB
    clean
    convert MBR
    exit
    "@|diskpart >$Null
    If($LASTEXITCODE -ne 0){
        $msg="Diskpart operations failed with error code $LASTEXITCODE."
        MsgBox $msg "OKOnly" "Critical" >$Null
        exit}
    "`r`nCreate the FAT32 boot partition"
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter|
        Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    "`r`nCreate the NTFS setup partition & set active"
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive|
        Format-Volume -FileSystem NTFS -NewFileSystemLabel "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue >$Null
    "`r`nCopy needed files to the fat32 boot partition $usbfat32"
    robocopy "$iso\" "$usbfat32\" bootmgr.* /a-:R /NJH /NJS
    robocopy "$iso\boot" "$usbfat32\boot" /e /a-:R /NJH /NJS
    robocopy "$iso\efi" "$usbfat32\efi" /e /a-:R /NJH /NJS
    robocopy "$iso\sources" "$usbfat32\sources" boot.wim /a-:R /NJH /NJS
    Update_BCD $usbfat32
    "`r`nRemove the drive letter to hide the fat32 partition"
    Get-Volume ($usbfat32 -replace ".$")|Get-Partition|
        Remove-PartitionAccessPath -accesspath $usbfat32
    "`r`nCopy needed files to the NTFS install partition $usbntfs"
    robocopy $iso $usbntfs /e /a-:R /NJH /NJS
    Update_BCD $usbntfs
    bootsect /nt60 $usbntfs /force /mbr >$Null
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage $ImagePath >$Null}
    MsgBox "$Title was created successfully." "OKOnly" "Information" >$Null
    
     
  10. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    This is why I'm asking if we can instead show the progress in the GUI Window
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    #432 rpo, Mar 12, 2025
    Last edited: Mar 12, 2025
    (OP)
    Presently, I don't know how to do that.

    As an intermediate solution, we could hide the powershell console for the GUI part and restore it to show the progress after pressing Create button. This was feasible in Windows 10, but on Windows 11, when you set Windows Console Host as the "Default terminal application" in the Startup setting of Windows Terminal, this solution doesn't work anymore.
    What we can do is hide the console during the GUI part and reenter the script to show the progress. Let me know your opinion.
     
  12. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    #433 freddie-o, Mar 12, 2025
    Last edited: Mar 13, 2025
    I think it's better to just remove the # character and give them the option to choose to show only USB sticks and hide external hard disks from the start
    I think it's also safer this way



    Or just go back to how it was in previous versions -- keep the console window open (don't hide or minimize)
    I think it's simpler this way :D



    It's better to keep the width and height fixed
    Code:
    $Form.Width=420 ; $Form.Height=270
    Autosize makes the (Groupbox) margins uneven
    Code:
    $Form.Width=$Form.Height=1 # AutoSize determines the minumum window size
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    Final 3.2 release
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Win10+ Setup Disk 3.2 &color 3E
    @powershell -noprofile -Window Normal -c "$param='%*';$ScriptPath='%~f0';iex((Get-Content('%~f0') -Raw))"&exit/b
    #>
    $OnlyUSBsticks="NO"
    #
    $host.ui.rawui.windowtitle = ($title=$host.ui.rawui.windowtitle -replace "^.*  ")
    #
    #
    #   Homepage: https://forums.mydigitallife.net/threads/win10-setup-disk-works-with-uefi-secure-boot-bios-install-wim-over-4-gb.79268/
    #   Credits: @rpo, @freddie-o, @BAU & @abbodi1406
    #
    Add-Type -AssemblyName Microsoft.VisualBasic
    Function MsgBox {
    # learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/msgbox-function
    [Microsoft.VisualBasic.Interaction]::MsgBox(
        $Args[0],"$($Args[1]),$($Args[2]),SystemModal",$title)}
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        If($param -eq $uac_error){
            $msg="$uac_error.`r`nRight click on the script and select ""Run as administrator""."
            MsgBox $msg    "OKOnly" "Critical" >$Null;exit}
    #   Restart the script to get Administrator privileges and exit
        Start-Process "$ScriptPath" $uac_error -Verb runAs; exit
    }
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    # Filebrowser dialog object
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        Multiselect = $false                 # Only one file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    #
    Function Update_bcd ($partition){
    #    Set bootmenupolicy Legacy for $partition
    bcdedit /store "$partition\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    bcdedit /store "$partition\EFI\Microsoft\boot\bcd" /set '{default}' bootmenupolicy Legacy >$Null
    remove-item "$partition\boot\bcd.*" -force
    remove-item "$partition\EFI\Microsoft\boot\bcd.*" -force
    }
    # **************************************************
    $msg="Would you like to show only USB sticks and hide external hard disks?"
    $filter="Status='OK' and (InterfaceType='usb'and MediaType='Removable Media')"
    # YES : show only usb sticks
    # NO  : show usb sticks and external hard disks
    #$OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    If($OnlyUSBsticks -eq "NO"){$filter="$filter or MediaType='External hard disk media'"}
    # **************************************************
    $delay=15
    While(!($Disks=Get-CimInstance -ClassName Win32_DiskDrive -Filter $filter)){
        $msg="No USB sticks were detected. Plug in your USB stick first and retry after $delay seconds or Cancel to exit."
        If((MsgBox $msg    "RetryCancel" "Question") -eq "Cancel"){exit}
        Start-Sleep $delay >$Null}
    #
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    $Form.TopMost = $True
    $Form.ShowIcon=$False
    $Form.ControlBox=$False
    # Set the title and size of the window:
    $Form.Text="$Title"
    $Form.Font='Consolas,10'
    $Form.Width=420 ; $Form.Height=270
    $Form.StartPosition = "CenterScreen"
    $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.SizeGripStyle = "Hide"
    $form.ShowInTaskbar = $False
    #$form.MaximizeBox = $False
    #$form.MinimizeBox = $False
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
    # Add a Source Windows ISO label on the form
    $SourceISO=New-Object System.Windows.Forms.Label
    $SourceISO.Location=New-Object System.Drawing.Point(20,30)
    $SourceISO.Size=New-Object System.Drawing.Size(200,20)
    $SourceISO.text="Source Windows ISO"
    $Form.Controls.Add($SourceISO)
    #
    # Add the ISO file name on the form
    $ISOFile=New-Object System.Windows.Forms.Label
    $ISOFile.Location=New-Object System.Drawing.Point(20,50)
    $ISOFile.Text=" "
    $ISOFile.Size=New-Object System.Drawing.Size(364,24)
    $ISOFile.Backcolor = "White"
    $ISOFile.BorderStyle = "FixedSingle"
    $Form.Controls.Add($ISOFile)
    #
    # Add a Target USB Disk label on the form
    $TargetUSB=New-Object System.Windows.Forms.Label
    $TargetUSB.Location=New-Object System.Drawing.Point(20,100)
    $TargetUSB.Text="Target USB Disk"
    $TargetUSB.Size=New-Object System.Drawing.Size(200,20)
    $Form.Controls.Add($TargetUSB)
    #
    # Create a USB Disk 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,120)
    $USBDiskList.Size=New-Object System.Drawing.Size(363,22)
    $Form.Controls.Add($SelectUSBDiskList)
    #
    # Add a Select ISO button on the form
    $SelectISOButton=New-Object System.Windows.Forms.Button
    $SelectISOButton.Location=New-Object System.Drawing.Point(20,185)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Size=New-Object System.Drawing.Size(110,26)
    $Form.Controls.Add($SelectISOButton)
    #
    # Add a Create Setup Disk button on the form
    $CreateDiskButton=New-Object System.Windows.Forms.Button
    $CreateDiskButton.Location=New-Object System.Drawing.Point(140,185)
    $CreateDiskButton.Text="Create Setup Disk"
    $CreateDiskButton.Size=New-Object System.Drawing.Size(155,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = "OK"
    #
    # Add a Cancel button on the form
    $CancelButton=New-Object System.Windows.Forms.Button
    $CancelButton.Location=New-Object System.Drawing.Point(305,185)
    $CancelButton.Text="Cancel"
    $CancelButton.Size=New-Object System.Drawing.Size(80,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = "Cancel"
    #
    $SelectISOButton.Add_Click({
    If ($FileBrowser.ShowDialog() -ne "Cancel"){ # if Cancel, just ignore
        $Global:ImagePath=$FileBrowser.filename    # return the file name
        $ISOFile.Text=Split-Path -Path $ImagePath -leaf # extract filename and extension (iso)
        if(($ISOFile.Text).length -gt 44){
            $ISOFile.Text=$ImagePath.PadRight(100).substring(0,43)+"..."}
        $CreateDiskButton.Enabled = $true
        $CreateDiskButton.Focus()}})
    #
    $USBDisks=@() # array with USB disk number
    Foreach ($Disk in $Disks){
        $FriendlyName=($Disk.Caption).PadRight(40).substring(0,35)
        $USBDisks+=$Disk.Index
        $USBDiskList.Items.Add(("{0,-30}{1,10:n2} GB" -f $FriendlyName,($Disk.Size/1GB))) >$Null
    <#
        Foreach ($Partition in (Get-Partition $Disk.Index)) {
            If(!$Partition.DriveLetter){$AccessPath="  "}Else{$AccessPath=$Partition.DriveLetter+":"}
            $USBDisks+=$Disk.Index
            $USBDiskList.Items.Add((" ({0,2}){1,-30}{2,10:n2} GB" -f $AccessPath,($Partition|
                Get-Volume).FileSystemLabel.PadRight(25).substring(0,25),($Partition.Size/1GB))) >$Null
        }
    #>
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    $Groupbox=New-Object System.Windows.Forms.Groupbox # Add a group box on the form
    $Groupbox.Location=New-Object System.Drawing.Point(7,0)
    $Groupbox.Text=""
    $Groupbox.Size=New-Object System.Drawing.Size(390,225)
    $Form.Controls.Add($Groupbox)
    #
    if($form.ShowDialog() -eq "Cancel") {exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $msg=@"
    WARNING!`r`n
    Your USB disk will be converted to MBR scheme, repartitioned and reformatted.`r`n
    All partitions and data currently stored in the USB disk will be erased.`r`n
    Are you sure you want to continue?
    "@
    If((MsgBox $msg "YESNO" "Exclamation") -eq "NO"){exit}
    "`r`nMount/Check if mounted the ISO image file"
    #   Check if iso already mounted by getting driveletter
    If($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter){$Mounted=$True}Else
    #    Mount iso and get drive letter
        {$Mounted=$False;Mount-DiskImage $ImagePath >$Null
         If(!($ISO=(Get-DiskImage $ImagePath|Get-Volume).DriveLetter)){Exit}}
    $ISO=$ISO+":"
    #
    Stop-Service ShellHWDetection -ErrorAction SilentlyContinue >$Null
    $ProgressPreference="SilentlyContinue"
    "`r`nClear the USB disk and set MBR partition with diskpart"
    @"
    Select disk $USB
    clean
    convert MBR
    exit
    "@|diskpart >$Null
    If($LASTEXITCODE -ne 0){
        $msg="Diskpart operations failed with error code $LASTEXITCODE."
        MsgBox $msg "OKOnly" "Critical" >$Null
        exit}
    "`r`nCreate the FAT32 boot partition"
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter|
        Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    "`r`nCreate the NTFS setup partition & set active"
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive|
        Format-Volume -FileSystem NTFS -NewFileSystemLabel "SETUP").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue >$Null
    "`r`nCopy needed files to the fat32 boot partition $usbfat32"
    robocopy "$iso\" "$usbfat32\" bootmgr.* /a-:R /NJH /NJS
    robocopy "$iso\boot" "$usbfat32\boot" /e /a-:R /NJH /NJS
    robocopy "$iso\efi" "$usbfat32\efi" /e /a-:R /NJH /NJS
    robocopy "$iso\sources" "$usbfat32\sources" boot.wim /a-:R /NJH /NJS
    Update_BCD $usbfat32
    "`r`nRemove the drive letter to hide the fat32 partition"
    Get-Volume ($usbfat32 -replace ".$")|Get-Partition|
        Remove-PartitionAccessPath -accesspath $usbfat32
    "`r`nCopy needed files to the NTFS install partition $usbntfs"
    robocopy $iso $usbntfs /e /a-:R /NJH /NJS
    Update_BCD $usbntfs
    bootsect /nt60 $usbntfs /force /mbr >$Null
    # Eject the mounted iso image if it was loaded by the script
    If(!$Mounted){DisMount-DiskImage $ImagePath >$Null}
    MsgBox "$Title was created successfully." "OKOnly" "Information" >$Null
    

    Everything works as before but some users can ignore usb connected hdd/ssd; this was requested by @garf02.
     
  14. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    #435 freddie-o, Mar 13, 2025
    Last edited: Mar 14, 2025
    I think it's safer to just remove the # character from
    Code:
    $OnlyUSBsticks=MsgBox $msg "YESNO" "Question"
    One mistake might cause you to erase the wrong disk drive
    For those who always have an external hard disk plugged in
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    #436 freddie-o, Mar 13, 2025
    Last edited: Mar 13, 2025
    Edited

    Reupdated the OP to v3.2
    Made a few minor changes to the script
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  16. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
  17. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  18. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,503
    1,512
    60
    Write-Progress displays on console.
     
  19. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,605
    2,676
    60
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...