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
    Can't reproduce the error when starting the script. Perhaps a problem witl the directory name?
    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 = "Windows Installation Disk v1.3 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 size of the window:
    $Form.FormBorderStyle = "none"
    $Form.Width=450 ; $Form.Height=120
    $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"){$SelectISOButton.PerformClick()}})
    $Form.Add_KeyDown({if ($_.KeyCode -eq "Escape"){$CancelButton.PerformClick()}})
    #
    #    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=380;$USBDiskList.height=20
    $Form.Controls.Add($SelectUSBDiskList)
    $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("No USB disk was detected. `r`n`r`Plug in your USB disk first. Click ""OK"" after you have plugged in your disk or ""Cancel"" to exit.",0,"Plug in the USB",1+64)
            if ($result -eq 2) {$wshell.Popup("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $USBDiskList.Items.Add((" {0,-30}|{1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }     
            }
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(30,15)
    $SelectUSBDisk.Text="Select the USB disk";$SelectUSBDisk.Font='Consolas,10'
    $SelectUSBDisk.width=150;$SelectUSBDisk.height=15;
    $Form.Controls.Add($SelectUSBDisk)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(300,70)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Consolas,10'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,20)
    $SelectISOButton.width=110;$SelectISOButton.height=30;
    $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(180,70)
    $CancelButton.Text="Cancel";$CancelButton.Font='Consolas,10'
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=110;$CancelButton.height=30;
    $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 operation",0+64) | Out-Null;exit}
    #
    $Result=$wshell.Popup("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?",0,"Warning",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter | 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
    
    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
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    

    With UEFI/GPTE systems the fat32 partition is used and the partition doesn't need to be activated. With legacy bios MBR systems you can boot with an ntfs partition, the fat32 partition isn't needed, but on older computers (all my systems) the partition has to be set as active.
    AFAIK, you have no progress bar if you don't modify the BCD whatever windows boot disk you use.
     
  2. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    Still shows
    Code:
    H:\> : standard way of doing hybrid batch + powershell scripts 0<#
    The system cannot find the file specified.
    Renamed the file without spaces and put it in the root of the partition but still the same... never had to do this with past scripts.

    So when booting on an MBR system, the installation disk doesn't use the FAT32 partition but goes straight to the NTFS partition? You mean you couldn't boot into the installation disk?

    All my Windows 10 ISOs have a progress bar when loading into the boot.wim. Maybe it's just on older PCs and/or versions of Windows?
     
  3. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,685
    60
    That's just your fault for saving the batch file in an incompatible format.
    Make sure you always use a 7-8 bit format such as OEM(DOS) / ANSI ( Windows 1250 ) / ISO-8859 etc and NOT unicode or utf with bom
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    On a MBR system, the boot process searchs for an active partition : if the ntfs partition is set active (the fat32 partition is not active : only one partition can be set active on a volume), it will be used. If no partition is set active your system may not boot (depends on the bios).
     
  5. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    I too use notepad++, downloaded the uploaded file and executed the script without issue.
     
  6. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    I was thinking though. The script was originally meant just to automate the job of formatting and copying the ISO to the USB disk. So now I'm not sure about modifying the bcd store to add bootmenupolicy legacy.
     
  7. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    This won't cause a problem with some UEFI (with Secure Boot) systems that boot into FAT32?
     
  8. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    Just delete the instructions modifying the bcd store.
    If you prefer, you can set the fat32 partition active as in the original script :
    # Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOTFAT").DriveLetter + ":"
    # Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
     
  9. drew84

    drew84 MDL Expert

    Mar 13, 2014
    1,347
    2,302
    60
    .. guys freddie-o, rpo
    I have been following this thread for a while now, and am enjoying the banter/conversation between you two..
    looking forward to the continued conversation and each update of this project
     
  10. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    #113 freddie-o, Aug 8, 2019
    Last edited: Aug 8, 2019
    (OP)
    EDIT:

    The script so far with no errors...
    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
    #
    $global:SelectISO=$False
    $global:Cancel=$False
    #
    clear-host
    $Form=New-Object System.Windows.Forms.Form # Create the screen form (window)
    # Set the title and size of the window:
    $Form.Text='Windows Installation Disk v1.3'
    $Form.Width=450 ; $Form.Height=200
    $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds
    #    Select the USB disk
    # Create a drop-down list and fill it
    $Combobox=New-Object System.Windows.Forms.ComboBox
    $Combobox.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList;
    $Combobox.Location=New-Object System.Drawing.Point(30,35)
    $Combobox.Width=380;$Combobox.height=20
    $USB=$Null
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    While (!$Disks) {
        $Result=$wshell.Popup("Plug in your USB disk first, then click ""OK"" to continue. `r`n`r`nTo close this script, click ""Cancel"".",0,"Plug in USB disk",1+64)
        if ($result -eq 2) {exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    $USBDiskList=New-Object System.Windows.Forms.ComboBox
    # $USBDiskList|gm
    $USBDiskList.Width=450
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)  
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $Combobox.Items.Add((" {0,-30}|{1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }      
            }  
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form
    $SelectUSBDisk.Location=New-Object System.Drawing.Size(30,15)
    $SelectUSBDisk.Text="Select the USB disk";$SelectUSBDisk.Font='Consolas,10'
    $SelectUSBDisk.width=150;$SelectUSBDisk.height=15;
    $Form.Controls.Add($SelectUSBDisk)
    $form.Controls.Add($Combobox)
    $Combobox.SelectedIndex=0
    
    
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Size(300,110)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Consolas,10'
    $SelectISOButton.width=110;$SelectISOButton.height=30;
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()})
    $Form.Controls.Add($SelectISOButton)
    $SelectISOButton.Add_Click({$Form.close()})
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Size(180,110)
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.Text="Cancel";$CancelButton.Font='Consolas,10'
    $CancelButton.width=110;$CancelButton.height=30;
    $Form.Controls.Add($CancelButton)
    $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()})
    #
    [void]$Form.ShowDialog()
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    $ImagePath = $FileBrowser.FileName;
    $ISO=":"
    If($FileBrowser.FileNames -like "*\*") {
    #  Check if iso already mounted
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter
    #    Mount iso
        IF (!$ISO) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO |out-null
        $ISO = (Get-DiskImage -ImagePath $ImagePath | Get-Volume).DriveLetter}
        $ISO=$ISO+":"
    }
    if ($ISO -eq ":") {$wshell.Popup("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
    #
    $Result=$wshell.Popup("Warning! All partitions and data on the USB disk will be lost. `r`n`r`nTo create the Windows installation disk, click ""OK"". `r`n`r`nTo close this script, click ""Cancel"".",0,"Create Windows installation disk",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    #
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    # Eject the mounted iso image
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
     
  11. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    Your script is confusing : you have 2 combobox objects : $Combobox and $UsbDiskList. The script should be adapted to use only $UsbDiskList.
     
  12. freddie-o

    freddie-o MDL Expert

    Jul 29, 2009
    1,358
    2,267
    60
    #116 freddie-o, Aug 9, 2019
    Last edited: Aug 9, 2019
    (OP)
    Fixed
    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.3'
    $Form.Width=455 ; $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(20,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 USB disk",1+64)
            if ($result -eq 2) {$wshell.Popup("The script was cancelled.",0,"Cancel script",0+64) | Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(30," ").substring(0,30)
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
            Foreach ($Volume in $Volumes) {
                $USBDisks+=$USBDisk.DiskNumber
                $USBDiskList.Items.Add((" {0,-30}|{1,1}:| {2,-30}| {3:n2} GB" -f $FriendlyName, ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(30," ").substring(0,30), ($Partition.Size/1GB)))|out-null
                }     
            }
        } Else {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add((" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",($USBDisk.Size/1GB)))|out-null
        }
    }
    
    $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,15)
    $SelectUSB.Text="Select USB disk";$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(310,130)
    $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Consolas,10'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,20)
    $SelectISOButton.width=110;$SelectISOButton.height=30;
    $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,130)
    $CancelButton.Text="Cancel";$CancelButton.Font='Consolas,10'
    $CancelButton.Size=New-Object System.Drawing.Size(120,20)
    $CancelButton.width=110;$CancelButton.height=30;
    $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! All partitions and data on the USB disk will be lost. `r`n`r`nTo continue creating the installation disk, click ""OK"". `r`n`r`nTo close this script, click ""Cancel"".",0,"Create Windows installation disk",1+48)
    if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit}
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    Stop-Service ShellHWDetection
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size 700MB -AssignDriveLetter -IsActive | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection
    #
    robocopy $iso $usbntfs /e
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e
    robocopy $iso"\efi" $usbfat32"\efi" /e
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    
    # Eject the mounted iso image
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    #done - keep a comment on the last line so the previous useful crlf never gets eaten
    

    Edit:
    Updated the script (which had errors) in the OP.
     
  13. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    For me it's OK!
     
  14. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    @BAU
    Your original (modified) coding to get admin privilege :
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @echo off
    ::AveYo: self-elevate passing args and preventing loop
    set "args="%~f0" %*" & call set "args=%%args:"=\"%%"
    fsutil dirty query %systemdrive%>nul||(if "%?%" neq "y" powershell -c "start cmd -ArgumentList '/c set ?=y&call %args%' -verb runas" &exit)
    powershell -NoLogo -NoProfile -WindowStyle Normal -ExecutionPolicy Bypass -c "iex([io.file]::ReadAllText(\"%~f0\"))" &exit/b
    #>
    has the advantage to prevent loop, but this is not the case with :
    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
    }
    How is this to be modified to prevent loop? I suppose we have to deal with argument passing...
     
  15. AveYo

    AveYo MDL Expert

    Feb 10, 2009
    1,836
    5,685
    60
    there should be no loop since the check is in powershell - IsInRole(544) takes care of that ( if not admin - restart as admin, if already admin, do nothing )
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  16. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,440
    1,420
    60
    Thanks. Efficient, as usual.