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. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    #201 freddie-o, Sep 7, 2019
    Last edited: Sep 8, 2019
    (OP)
    Updated to v1.8.1
    Cleaned up the script and made some minor changes to the script and UI.

    Also added "Supported Windows versions" of the script to the OP.
     
  2. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    Suggestions introducing very lite changes.
    The title is moved to the cmd part of the script, it is easier to find for modification.
    The variable $ShortTitle contains the first part of the title. It is used for the gui display and for the popup messages.
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Windows Installation Disk v1.8.1 by: rpo/freddie-o/abbodi1406/BAU [forums.mydigitallife.net]&color 1E
    @set "__ARGS__=%*" &powershell -noprofile -c "$ScriptPath='%~f0';iex(Get-Content($ScriptPath) -raw)" &exit/b
    #>
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $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 " by: .*")[0]
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    Function Get-FileName
    {
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    IF ($FileBrowser.ShowDialog() -eq "Cancel"){Cancel}
    $FileBrowser.filename    # return the file name
    }
    $wshell=New-Object -ComObject Wscript.Shell
    #
    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"
    
    # 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($wshell.Popup("Please plug in your USB disk then click ""OK"" to continue.",0,$ShortTitle,1+64) -eq 2){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='Consolas,10'
    $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='Consolas,10'
    $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,22)
    $ISOFile.Backcolor = [System.Drawing.Color]::White
    $ISOFile.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
    $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(135,170)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Font='Consolas,10'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,25)
    $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(265,170)
    $CancelButton.Text="Cancel"
    $CancelButton.Font='Consolas,10'
    $CancelButton.Size=New-Object System.Drawing.Size(120,25)
    $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(135,170)
    $CreateDiskButton.Text="Create Disk"
    $CreateDiskButton.Font='Consolas,10'
    $CreateDiskButton.Size=New-Object System.Drawing.Size(120,25)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $Form.Controls.Add($ISOImage)
    $Form.Controls.Add($ISOFile)
    $Form.Controls.Remove($CreateDiskButton)
    $SelectISOButton.Add_Click(
        {$Global:ImagePath = Get-FileName # get the iso image path with file browser dialog
         $ImagePath= Split-Path -Path $Global:ImagePath -leaf # extract filename and extension (iso)
         $ISOFile.Text = $ImagePath
         if (($ISOFile.Text).length -gt 44) {$ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."}
         $Form.Controls.Remove($SelectISOButton)
         $Form.Controls.Add($CreateDiskButton)})
    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,-1}({1,1}:){2,-32}[{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"){$wshell.Popup("The script was cancelled.",1,$ShortTitle,0+64) | 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 ":") {Cancel}
    #
    if($wshell.Popup("Warning! Your USB disk will be converted to MBR scheme, repartitioned and reformatted. All the data will be lost. `r`n`r`nAre you sure you want to continue?",0,$ShortTitle,4+48) -eq 7){DisMount-DiskImage -ImagePath $ImagePath;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
    $wshell.Popup("The Windows Installation Disk completed successfully.",0,$ShortTitle,0+64) | Out-Null;exit
    
     
  3. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    Enabled visual styles but it only affects the "Form" not the "pop-ups"?

    Code:
    [System.Windows.Forms.Application]::EnableVisualStyles();
    
     
  4. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    I guess popup is not based upon .net framework.
     
  5. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    Figured it out
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Windows Installation Disk v1.8.2 by: rpo/freddie-o/abbodi1406/BAU [forums.mydigitallife.net]
    @set "__ARGS__=%*" &powershell -noprofile -c "$ScriptPath='%~f0';iex(Get-Content($ScriptPath) -raw)" &exit/b
    #>
    #
    #   This script must be executed with admin privilege
    #
    #   Test Administrator privileges
    If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        $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 " by: .*")[0]
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    Function Get-FileName
    {
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    IF ($FileBrowser.ShowDialog() -eq "Cancel"){Cancel}
    $FileBrowser.filename    # return the file name
    }
    $wshell=New-Object -ComObject Wscript.Shell
    #
    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"
    
    [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) {
        $Result=[System.Windows.Forms.MessageBox]::Show("Please plug in your USB disk first. `r`n`r`nClick OK to continue.","Plug in the USB disk","1","64")
            if ($result -eq 2) {Out-Null;exit}
        $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")}
    }
    $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='Consolas,10'
    $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='Consolas,10'
    $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,22)
    $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(135,170)
    $SelectISOButton.Text="Select ISO"
    $SelectISOButton.Font='Consolas,10'
    $SelectISOButton.Size=New-Object System.Drawing.Size(120,25)
    $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(265,170)
    $CancelButton.Text="Cancel"
    $CancelButton.Font='Consolas,10'
    $CancelButton.Size=New-Object System.Drawing.Size(120,25)
    $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(135,170)
    $CreateDiskButton.Text="Create Disk"
    $CreateDiskButton.Font='Consolas,10'
    $CreateDiskButton.Size=New-Object System.Drawing.Size(120,25)
    $Form.Controls.Add($CreateDiskButton)
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $Form.Controls.Add($ISOImage)
    $Form.Controls.Add($ISOFile)
    $Form.Controls.Remove($CreateDiskButton)
    $SelectISOButton.Add_Click(
        {$Global:ImagePath = Get-FileName # get the iso image path with file browser dialog
         $ImagePath= Split-Path -Path $Global:ImagePath -leaf # extract filename and extension (iso)
         $ISOFile.Text = $ImagePath
         if (($ISOFile.Text).length -gt 44) {$ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."}
         $Form.Controls.Remove($SelectISOButton)
         $Form.Controls.Add($CreateDiskButton)})
    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,-1}({1,1}:){2,-32}[{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"){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}
    #
    $Result=[System.Windows.Forms.MessageBox]::Show("WARNING! Your USB disk will be converted to MBR scheme, repartitioned and reformatted. `r`n`r`nAll partitions and data stored in the disk will be erased. `r`n`r`nAre you sure you want to continue?","Warning","4","48")
            if ($result -eq 7){DisMount-DiskImage -ImagePath $ImagePath;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
    [System.Windows.Forms.MessageBox]::Show("The Windows Installation Disk completed successfully.","Complete")
    
    
     
  6. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    This would be great if the Form had a progress bar.

    Code:
    # .Net methods for hiding/showing the console in the background
    Add-Type -Name Window -Namespace Console -MemberDefinition '
    [DllImport("Kernel32.dll")]
    public static extern IntPtr GetConsoleWindow();
    
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
    '
    function Hide-Console
    {
        $consolePtr = [Console.Window]::GetConsoleWindow()
        #0 hide
        [Console.Window]::ShowWindow($consolePtr, 0)
    }
    Hide-Console
     
  7. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    #208 freddie-o, Sep 9, 2019
    Last edited: Sep 9, 2019
    (OP)
    EDIT: Made a few corrections and changes to v1.8.2 and replaced the script in the OP (again)
     
  8. vigipirate

    vigipirate MDL Member

    Feb 24, 2011
    197
    49
    10
    Hello
    thank you all for your work really great j uses the script not too much problem
    simply when i want to mount the boot.wim image impossible if you could edit the script because in dism it does not want to mount my boot image .wim
    The specified image does not exist in Windows Image Manager.
    First look in the Windows Image Manager for existing images.
    The DISM log file is located ... the location C: \ Windows \ Logs \ DISM \ dism.log
    Thanks for your help
     
  9. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    My remarks concerning 1.8.2
    replace line 31 (because the Cancel function has been removed) by :
    IF ($FileBrowser.ShowDialog() -eq "Cancel"){[Environment]::Exit(0)}
    delete line 34
    replace lines 59-60 by :
    if([System.Windows.Forms.MessageBox]::Show("Please plug in your USB disk first.`n`nClick OK to continue.",$ShortTitle,"OKCancel","Information") -eq "Cancel") {exit}
    delete line 106
    delete lines 109-111
    lines 137-140 ???? what is that ???
    if($form.ShowDialog() -eq "Cancel") {[System.Windows.Forms.MessageBox]::Show("The script was cancelled.",$ShortTitle,"OK","Error")|out-Null;exit}
    replace lines 156-157 by :
    If([System.Windows.Forms.MessageBox]::Show("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?",$ShortTitle,"YESNO","Warning") -eq "NO"){DisMount-DiskImage -ImagePath $ImagePath|Out-Null;exit}
    Replace lines 189-190 by :
    [System.Windows.Forms.MessageBox]::Show("The Windows Installation Disk completed successfully.",$ShortTitle,"OK","Information")|Out-Null;exit
    I don't understand your problem. The boot.wim is taken from the iso image you supply and copied without any modification in the two sources directories. Does your usb disk boot?
     
  10. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    Updated to v1.9
    Changed the name of script to "Win10 Installation Disk"
    Made corrections and modifications to the script.
     
  11. Flipp3r

    Flipp3r MDL Expert

    Feb 11, 2009
    1,723
    756
    60
    Hi I just tried the v1.9 script.
    When I first ran it by clicking on the script through explorer, it prompted for admin, defaulted to the inserted usb key, let me choose the iso but quit without error when I continued.
    I then opened an admin cmd prompt & ran the script, no errors - all good.

    On the 1st page you have:
    I boot my usb key in uefi mode and got the progress bar so I guess your also setting "EFI\Microsoft\boot\bcd" to "bootmenupolicy Legacy" as well.
    Doesn't really matter though...
     
  12. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    Yes, you are right.
     
  13. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    Updated to v1.9.1
    Separated the "Select ISO" and "Create Disk" buttons so you still have opportunity to change your choice of ISO before creating the installation disk.
     
  14. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    This is exactly what i achieved in one of my previous scripts.
    In the meantime i worked on 1.9 :
    Code:
    <# : standard way of doing hybrid batch + powershell scripts
    @title Win10 Installation Disk 1.9 by: rpo/freddie-o/abbodi1406/BAU [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 " by: .*")[0]
    #
    Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms
    #
    Function Get-FileName
    {
    # Filebrowser dialog
    $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{
       Multiselect = $false # One file can be chosen
        Filter = 'ISO images (*.iso)|*.iso' # Select only iso files
    }
    IF ($FileBrowser.ShowDialog() -eq "Cancel"){[Environment]::Exit(0)}
    $FileBrowser.filename    # return the file name
    }
    #
    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.ControlBox = $false
    $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,20)
    $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(150,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(20,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(285,170)
    $CreateDiskButton.Text="Create Disk"
    $CreateDiskButton.Font='Default Font,9'
    $CreateDiskButton.Size=New-Object System.Drawing.Size(100,26)
    $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    
    $SelectISOButton.Add_Click({
        $Global:ImagePath = Get-FileName # get the iso image path with file browser dialog
        $ImagePath= Split-Path -Path $Global:ImagePath -leaf # extract filename and extension (iso)
        $ISOFile.Text = $ImagePath
        if (($ISOFile.Text).length -gt 44) {$ISOFile.Text = $ImagePath.PadRight(100," ").substring(0,43)+"..."}
        $CreateDiskButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
        $Form.Controls.Add($CreateDiskButton)
        $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,-32}[{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" "Error"|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

    The main modifications :
    Created a MsgBox function and changed the script accordlingly.
    Put the Cancel button to the left down corner
    Put focus on the create disk button
     
  15. freddie-o

    freddie-o MDL Addicted

    Jul 29, 2009
    682
    762
    30
    The Cancel button used to be in the left corner but I moved it to the right corner because generally all UIs have it in the right corner. I'll update the script in the OP.
     
  16. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    #218 rpo, Sep 10, 2019
    Last edited: Sep 10, 2019
    No problem to put it in the right corner :
    $CancelButton.Location=New-Object System.Drawing.Point(285,170)
    and :
    $CreateDiskButton.Location=New-Object System.Drawing.Point(20,170)
    And also :
    $SelectISOButton.Location=New-Object System.Drawing.Point(150,170)
     
  17. rpo

    rpo MDL Expert

    Jan 3, 2010
    1,144
    957
    60
    If you say so...