Win10 Setup Disk [For UEFI or BIOS / UEFI with Secure Boot / Install.wim over 4 GB]

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

  1. Flipp3r

    Flipp3r MDL Expert

    Feb 11, 2009
    1,723
    756
    60
    It did but crashed (without any error shown).
    That's when I opened an admin cmd prompt and ran the script from there - and it worked...
     
  2. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    @freddie-o
    Please, could you suppress all references concerning myself on the OP and in the script? No need for cult of personality. Thank you.
     
  3. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    Changed the way to select iso image.
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Win10 Installation Disk 1.9.2 @ forums.mydigitallife.net
    @set "__ARGS__=%*" &powershell -noprofile -c "$ScriptPath='%~f0';iex((Get-Content($ScriptPath))  -join [char[]]10)" &exit/b
    #>
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $uac_error="Elevating UAC for Administrator Privileges failed"
        #   The following test is to avoid infinite looping if elevating UAC for Administrator Privileges failed
        if ($env:__ARGS__ -eq $uac_error) {
        "$uac_error`r`nRight click on the script and select ""Run as administrator""`r`nPress Enter to exit..."|write-host;pause >$null;exit/b}
    #   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
    $pswindow.windowtitle = ([string]($pswindow.windowtitle -split "^.*  ")).trim() ; $ShortTitle=($pswindow.windowtitle -split " @ .*")[0]
    #
    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],$ShortTitle,$Args[1],$Args[2])}
    #
    clear-host
    $USB=$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.Width=420 ; $Form.Height=250
    $Form.StartPosition = "CenterScreen"
    $Form.SizeGripStyle = "Hide"
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
    # 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,45)
    $USBDiskList.Size=New-Object System.Drawing.Size(365,20)
    $USBDiskList.Font='Consolas,10'
    $Form.Controls.Add($SelectUSBDiskList)
    $USBDisks=@() # array with USB disk number
    $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    
    While (!$Disks) {
    if((MsgBox "Please plug in your USB disk first then click OK to continue." "OKCancel" "Information") -eq "Cancel") {exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    $USBDisk=New-Object System.Windows.Forms.Label # Put the USB Disk label on the form
    $USBDisk.Location=New-Object System.Drawing.Point(20,25)
    $USBDisk.Text="USB Disk"
    $USBDisk.Font='Default Font,9'
    $USBDisk.Size=New-Object System.Drawing.Size(400,20)
    $Form.Controls.Add($USBDisk)
    
    $ISOImage=New-Object System.Windows.Forms.Label # Put the ISO Image label on the form
    $ISOImage.Location=New-Object System.Drawing.Point(20,90)
    $ISOImage.Font='Default Font,9'
    $ISOImage.Size=New-Object System.Drawing.Size(350,20)
    $ISOImage.text="ISO Image"
    $Form.Controls.Add($ISOImage)
    
    $ISOFile=New-Object System.Windows.Forms.Label # Put the ISO file name on the form
    $ISOFile.Location=New-Object System.Drawing.Point(20,110)
    $ISOFile.Text=" "
    $ISOFile.Font='Consolas,10'
    $ISOFile.Size=New-Object System.Drawing.Size(365,23)
    $ISOFile.Backcolor = [System.Drawing.Color]::White
    $ISOFile.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle
    $Form.Controls.Add($ISOFile)
    
    $SelectISOButton=New-Object System.Windows.Forms.Button # Put the Select ISO button on the form
    $SelectISOButton.Location=New-Object System.Drawing.Point(180,170)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Font='Default Font,9'
    $SelectISOButton.Size=New-Object System.Drawing.Size(100,26)
    $Form.Controls.Add($SelectISOButton)
    
    $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form
    $CancelButton.Location=New-Object System.Drawing.Point(285,170)
    $CancelButton.Text="Cancel"
    $CancelButton.Font='Default Font,9'
    $CancelButton.Size=New-Object System.Drawing.Size(100,26)
    $Form.Controls.Add($CancelButton)
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    
    $CreateDiskButton=New-Object System.Windows.Forms.Button # Put the Create Disk button on the form
    $CreateDiskButton.Location=New-Object System.Drawing.Point(75,170)
    $CreateDiskButton.Text="Create Disk"
    $CreateDiskButton.Font='Default Font,9'
    $CreateDiskButton.Size=New-Object System.Drawing.Size(100,26)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.Enabled = $false
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $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()}})
    
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(40," ").substring(0,39)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-39}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
                Foreach ($Volume in $Volumes) {
                    $USBDisks+=$USBDisk.DiskNumber
                    $USBDiskList.Items.Add(("{0,-2}({1,1}:){2,-31}[{3:n2} GB]" -f " ", ($Partition.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Partition.Size/1GB)))|out-null
                }
            }
        }
    }
    $form.Controls.Add($USBDiskList)
    $USBDiskList.SelectedIndex=0
    #
    if($form.ShowDialog() -eq "Cancel") {MsgBox "The script was cancelled." "OK" "Information"|out-Null;exit}
    #
    # At this point the mounted USB disk and the iso image file path are defined
    #
    $USB=$USBDisks[$USBDiskList.SelectedIndex]
    #
    # Mount the image file if not already mounted and get the drive letter
    #
    #  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 ":") {exit}
    #
    If((MsgBox "WARNING! Your USB disk will be converted to MBR scheme, repartitioned and reformatted.`n`nAll partitions and data stored in the disk will be erased.`r`n`r`nAre you sure you want to continue?" "YESNO" "Warning") -eq "NO"){DisMount-DiskImage -ImagePath $ImagePath|Out-Null;exit}
    Clear-Host
    #    Clear the USB stick
    Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false
    set-disk $usb -partitionstyle mbr
    Stop-Service ShellHWDetection -erroraction silentlycontinue|out-null
    #    Create the fat32 boot partition
    $usbfat32=(New-Partition -DiskNumber $usb -Size  1GB -AssignDriveLetter | Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT").DriveLetter + ":"
    #    Create the ntfs intall partition
    $usbntfs=(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter -IsActive | Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL").DriveLetter + ":"
    Start-Service ShellHWDetection -erroraction silentlycontinue|out-null
    #
    robocopy $iso $usbntfs /e /xf $iso\boot\bcd $iso\efi\microsoft\boot\bcd
    robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi
    robocopy $iso"\boot" $usbfat32"\boot" /e /xf $iso\boot\bcd
    robocopy $iso"\efi" $usbfat32"\efi" /e /xf $iso\efi\microsoft\boot\bcd
    robocopy $iso"\sources" $usbfat32"\sources" boot.wim
    
    Copy-Item $ISO"\boot\bcd" $env:temp -Force
    & bcdedit /store ($env:temp + "\bcd") /set '{default}' bootmenupolicy Legacy
    Set-ItemProperty -Path ($env:temp + "\bcd") -Name IsReadOnly -Value $true
    Copy-Item ($env:temp + "\bcd") $usbfat32"\boot\bcd" -Force
    Copy-Item ($env:temp + "\bcd") $usbntfs"\boot\bcd" -Force
    Copy-Item $ISO"\EFI\Microsoft\boot\bcd" $env:temp -Force
    & bcdedit /store ($env:temp + "\bcd") /set '{default}' bootmenupolicy Legacy
    Set-ItemProperty -Path ($env:temp + "\bcd") -Name IsReadOnly -Value $true
    Copy-Item ($env:temp + "\bcd") $usbfat32"\EFI\Microsoft\boot\bcd" -Force
    Copy-Item ($env:temp + "\bcd") $usbntfs"\EFI\Microsoft\boot\bcd" -Force
    remove-item ($env:temp + "\bcd") -force
    remove-item ($env:temp + "\bcd.*") -force
    # Eject the mounted iso image
    DisMount-DiskImage -ImagePath $ImagePath |out-null
    MsgBox "The installation disk completed successfully." "OK" "Information" |Out-Null;exit
     
  4. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    Updated the script in the OP:
    Made some changes to the script on how the ISO is selected.
    The consoles text and background colors are now consistent with one another.
     
  5. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    Replacement for line 14 :
    Code:
        read-host "$uac_error`r`nRight click on the script and select ""Run as administrator""`r`nPress Enter to exit...";exit}
    exit/b is not a valid powershell instruction; just use exit.
     
  6. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    #230 rpo, Oct 1, 2019
    Last edited: Oct 1, 2019
    Some simplification. Replace :
    Code:
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(40," ").substring(0,39)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-39}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $Partitions = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}
        If ($Partitions) {
            Foreach ($Partition in $Partitions) {
            $Volumes=get-volume | Where-Object {$Partition.AccessPaths -contains  $_.path }
                Foreach ($Volume in $Volumes) {
                    $USBDisks+=$USBDisk.DiskNumber
                    $USBDiskList.Items.Add(("{0,-2}({1,1}:){2,-31}[{3:n2} GB]" -f " ", ($Volume.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Volume.Size/1GB)))|out-null
                }
            }
        }
    }

    by :
    Code:
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(40," ").substring(0,39)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-39}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $Volumes = Get-Partition | Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber}|Get-Volume
        Foreach ($Volume in $Volumes) {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add(("{0,-2}({1,1}:){2,-31}[{3:n2} GB]" -f " ", ($Volume.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Volume.Size/1GB)))|out-null         
        }
    }
     
  7. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    #232 rpo, Oct 1, 2019
    Last edited: Oct 1, 2019
    My bad :
    Code:
    Foreach ($USBDisk in $Disks) {
        $FriendlyName=($USBDisk.FriendlyName).PadRight(40," ").substring(0,39)
        $USBDisks+=$USBDisk.DiskNumber
        $USBDiskList.Items.Add(("{0,-39}{1:n2} GB" -f $FriendlyName,($USBDisk.Size/1GB)))|out-null
        $Volumes = $USBDisk|Get-Partition |Get-Volume
        Foreach ($Volume in $Volumes) {
            $USBDisks+=$USBDisk.DiskNumber
            $USBDiskList.Items.Add(("{0,-2}({1,1}:){2,-31}[{3:n2} GB]" -f " ", ($Volume.DriveLetter), $Volume.FileSystemLabel.PadRight(25," ").substring(0,25), ($Volume.Size/1GB)))|out-null       
        }
    }
     
  8. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    And what is the problem with that?
     
  9. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
  10. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    Nope. But the drive letters and volume names are only displayed for information. What matters is the disk number which is not displayed (it's the number you get with diskpart -> list disks) because it is a poor help for the user; instead the "friendly" disk name is displayed.
     
  11. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    I think it's still better for the user (more user-friendly) when the drive letters are displayed in alphabetical order
     
  12. vigipirate

    vigipirate MDL Member

    Feb 24, 2011
    197
    49
    10
    hello need your help
    I copy iso windows 7 x64 on cle usb launches your script
    Win10 Installation Disk [UEFI or BIOS / UEFI with Secure Boot / Install.wim over 4GB
    no problem at the bot of the usb key in Mbr I have the launch of windows but at the moment to install windows it mes me a window and asks
    A Media Driver Your Computer Needs "or" Error Message "A Required CD / DVD Drive Device Driver Is Missing" When You Install Windows

    with rufus I'm not that problem
    thanks for your or modify your script
     
  13. coleoptere2007

    coleoptere2007 MDL Guru

    Apr 8, 2008
    3,136
    1,735
    120
    As indicated in the title "Windows 10 installation......." :rolleyes:
     
  14. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30

    This may help
    How to install Windows 7 from a USB 3.0 Thumb Drive (FAST installation!)