EDIT: The problem with that script are the "Select ISO" and "Create USB Disk" buttons. I cannot figure out how to make them do what they're supposed to. After selecting the ISO, the window should just close, but it starts the script. The "Create USB Disk" button should start the script. Also the "Select USB Disk" drop down list starts out blank.
I had a look at your modified script to have only one gui and modified it as follows : Code: @echo off ( echo # echo # This script must be executed with admin privilege echo # echo # Test Administrator privileges echo If ^(-NOT ^([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent^(^)^).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"^)^) echo { echo # Restart the script to get Administrator privileges and exit echo Start-Process 'powershell.exe' -Verb runAs -ArgumentList ^("-NoLogo -WindowStyle Normal -noprofile -file " + """" + $PSCommandPath + """"^) echo exit echo } echo # We have Administrator privileges echo # echo [console]::ForegroundColor = "Yellow" echo [console]::BackgroundColor = "blue" echo # echo Add-Type -AssemblyName System.Windows.Forms # Load the class System.Windows.Forms echo # Filebrowser dialog echo $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog -Property @{ echo Multiselect = $false # One file can be chosen echo Filter = 'ISO images ^(*.iso^)^|*.iso' # Select iso files echo } echo # echo $wshell=New-Object -ComObject Wscript.Shell echo clear-host echo # Select the USB disk echo $global:SelectISO=$False echo $global:Cancel=$False echo $Form=New-Object System.Windows.Forms.Form # Create the screen form ^(window^) echo # $Form ^|gm;pause echo # Set the title and size of the window: echo $Form.Text='Windows installation disk^' echo $Form.Width=490 ; $Form.Height=210 echo $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds echo # Create a drop-down list and fill it echo $USB=$Null echo $USBDisks=@^(^) # array with USB disk number echo $Disks=Get-Disk ^| Where-Object {^($_.BusType -eq "USB"^) -and ^($_.OperationalStatus -eq "Online"^)} echo $USBDiskList=New-Object System.Windows.Forms.ComboBox echo # $USBDiskList^|gm echo $USBDiskList.Width=450 echo Foreach ^($USBDisk in $Disks^) { echo $FriendlyName=^($USBDisk.FriendlyName^).PadRight^(30," "^).substring^(0,30^) echo $Partitions = Get-Partition ^| Where-Object { $_.DiskNumber -eq $USBDisk.DiskNumber} echo If ^($Partitions^) { echo Foreach ^($Partition in $Partitions^) { echo $Volumes=get-volume ^| Where-Object {$Partition.AccessPaths -contains $_.path } echo Foreach ^($Volume in $Volumes^) { echo $USBDisks+=$USBDisk.DiskNumber echo $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 echo } echo } echo } Else { echo $USBDisks+=$USBDisk.DiskNumber echo $USBDiskList.Items.Add^(^(" {0,-30}| {1,1}| {2,-30}| {3:n2} GB" -f $FriendlyName, " ", " ",^($USBDisk.Size/1GB^)^)^)^|out-null echo } echo } echo $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form echo $SelectUSBDisk.Location=New-Object System.Drawing.Size^(10,20^) echo $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10' echo $SelectUSBDisk.width=200;$SelectUSBDisk.height=20; echo $Form.Controls.Add^($SelectUSBDisk^) echo $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList; echo $USBDiskList.Location=New-Object System.Drawing.Point^(10,40^) echo $USBDiskList.width=450;$USBDiskList.height=20 echo $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White" echo $USBDiskList.Font='Segoe UI,10' echo $Form.Controls.Add^($USBDiskList^) echo $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form echo $SelectISOButton.Location=New-Object System.Drawing.Size^(10,100^) echo $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10' echo $SelectISOButton.width=80;$SelectISOButton.height=60; echo $Form.Controls.Add^($SelectISOButton^) echo $SelectISOButton.Add_Click^({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog^(^)}^) echo $Form.Controls.Add^($SelectISOButton^) echo $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form echo $CreateUSBDiskButton.Location=New-Object System.Drawing.Size^(350,130^) echo $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10' echo $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30; echo $Form.Controls.Add^($CreateUSBDiskButton^) echo $CreateUSBDiskButton.Add_Click^({$Form.close^(^)}^) echo $Form.Controls.Add^($CreateUSBDiskButton^) echo $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form echo $CancelButton.Location=New-Object System.Drawing.Size^(260,130^) echo $CancelButton.Size=New-Object System.Drawing.Size^(120,20^) echo $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10' echo $CancelButton.width=60;$CancelButton.height=30; echo $Form.Controls.Add^($CancelButton^) echo $CancelButton.Add_Click^({$global:Cancel=$True;$Form.close^(^)}^) echo $result = $Form.ShowDialog^(^) echo $USB=$USBDisks[$USBDiskList.SelectedIndex] echo if ^($Cancel^){$wshell.Popup^("User Cancelled the script",0,"Cancel"^) ^| Out-Null;exit} echo if ^(!$USB^){$wshell.Popup^("No USB disk selected",0,"Error"^) ^| Out-Null;exit} echo if ^(!$global:SelectISO^){$wshell.Popup^("Operation cancelled. You must select a ISO image",0,"Error"^) ^| Out-Null;exit} echo # echo # [void]$FileBrowser.ShowDialog^(^) echo # echo $ImagePath = $FileBrowser.FileName; echo $ISO=":" echo If^($FileBrowser.FileNames -like "*\*"^) { echo # Check if iso already mounted echo $ISO = ^(Get-DiskImage -ImagePath $ImagePath ^| Get-Volume^).DriveLetter echo # Mount iso echo IF ^(!$ISO^) {Mount-DiskImage -ImagePath $ImagePath -StorageType ISO ^|out-null echo $ISO = ^(Get-DiskImage -ImagePath $ImagePath ^| Get-Volume^).DriveLetter} echo $ISO=$ISO+":" echo } echo if ^($ISO -eq ":"^) {$wshell.Popup^("No ISO image mounted or operation cancelled",0,"Error"^) ^| Out-Null;exit} echo # Clear the USB stick echo Clear-Disk $usb -RemoveData -RemoveOEM -Confirm:$false echo Stop-Service ShellHWDetection echo # Create the fat32 boot partition echo $usbfat32=^(New-Partition -DiskNumber $usb -Size 1GB -AssignDriveLetter -IsActive ^| Format-Volume -FileSystem FAT32 -NewFileSystemLabel "BOOT"^).DriveLetter + ":" echo # Create the ntfs intall partition echo $usbntfs=^(New-Partition -DiskNumber $usb -UseMaximumSize -AssignDriveLetter ^| Format-Volume -FileSystem NTFS -NewFileSystemLabel "INSTALL"^).DriveLetter + ":" echo Start-Service ShellHWDetection echo # Read-Host "Eject the iso if it is mounted. When ready press Enter" echo # $Volumes = ^(Get-Volume^).Where^({$_.DriveLetter}^).DriveLetter echo # Read-Host "Mount the iso. When ready press Enter" echo # $ISO = ^(Compare-Object -ReferenceObject $Volumes -DifferenceObject ^(Get-Volume^).Where^({$_.DriveLetter}^).DriveLetter^).InputObject echo # $ISO = ^(get-volume^| Where-Object {^($_.DriveType -eq "CD-ROM"^) -and ^($_.filesystemlabel -ne ""^) -and ^($_.OperationalStatus -eq "OK"^)} ^|Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single^).DriveLetter + ":" echo # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose echo # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose echo # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose echo # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse -Verbose echo # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse -Verbose echo # new-item $usbfat32"\sources" -itemType Directory echo # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim" -Verbose echo robocopy $iso $usbntfs /e echo robocopy $iso"\" $usbfat32"\" bootmgr bootmgr.efi echo robocopy $iso"\boot" $usbfat32"\boot" /e echo robocopy $iso"\efi" $usbfat32"\efi" /e echo robocopy $iso"\sources" $usbfat32"\sources" boot.wim echo # Eject the mounted iso image echo # ^(New-Object -ComObject Shell.Application^).Namespace^(17^).ParseName^($ISO^).InvokeVerb^("Eject"^) echo DisMount-DiskImage -ImagePath $ImagePath ^|out-null echo Remove-item ^($env:TEMP + "\script.ps1"^) )>"%temp%\script.ps1" powershell -noprofile -executionpolicy bypass -WindowStyle Normal -file "%temp%\script.ps1" I don't see a real advantage using only one gui.
I modified the script using abbodi1406's suggestion... Code: @echo off ::AveYo: self-elevate passing args and preventing loop set "args="%~f0" %*" & call set "args=%%args:"=\""%%" reg query HKU\S-1-5-19>nul 2>nul||(if "%?%" neq "y" powershell -c "start cmd -ArgumentList '/c set ?=y&call %args%' -verb runas" &exit) title Windows installation disk ::Script by @rpo / @abbodi1406 / @freddie-o [forums.mydigitallife.net] powershell -NoLogo -NoProfile -WindowStyle Normal -ExecutionPolicy Bypass -C "$f=[io.file]::ReadAllText('%~f0') -split ':ps_usb\:.*';iex ($f[1]);" & exit/b :ps_usb: [ [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 # Select the USB disk $global:SelectISO=$False $global:Cancel=$False $Form=New-Object System.Windows.Forms.Form # Create the screen form (window) # $Form |gm;pause # Set the title and size of the window: $Form.Text='Windows installation disk' $Form.Width=495 ; $Form.Height=210 $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds # Create a drop-down list and fill it $USB=$Null $USBDisks=@() # array with USB disk number $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 $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 } } $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form $SelectUSBDisk.Location=New-Object System.Drawing.Size(15,20) $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10' $SelectUSBDisk.width=200;$SelectUSBDisk.height=20; $Form.Controls.Add($SelectUSBDisk) $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList; $USBDiskList.Location=New-Object System.Drawing.Point(15,40) $USBDiskList.width=450;$USBDiskList.height=20 $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White" $USBDiskList.Font='Segoe UI,10' $Form.Controls.Add($USBDiskList) $WARNING=New-Object System.Windows.Forms.Label # Put the WARNING label on the form $WARNING.Location=New-Object System.Drawing.Size(15,70) $WARNING.Text="WARNING: All partitions and data on the USB disk will be lost.";$WARNING.Font='Segoe UI,10' $WARNING.width=400;$WARNING.height=20; $Form.Controls.Add($WARNING) $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form $SelectISOButton.Location=New-Object System.Drawing.Size(15,110) $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10' $SelectISOButton.width=80;$SelectISOButton.height=50; $Form.Controls.Add($SelectISOButton) $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()}) $Form.Controls.Add($SelectISOButton) $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(355,130) $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10' $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30; $Form.Controls.Add($CreateUSBDiskButton) $CreateUSBDiskButton.Add_Click({$Form.close()}) $Form.Controls.Add($CreateUSBDiskButton) $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form $CancelButton.Location=New-Object System.Drawing.Size(280,130) $CancelButton.Size=New-Object System.Drawing.Size(120,20) $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10' $CancelButton.width=60;$CancelButton.height=30; $Form.Controls.Add($CancelButton) $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()}) $result = $Form.ShowDialog() $USB=$USBDisks[$USBDiskList.SelectedIndex] if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit} if (!$USB){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit} if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit} # # [void]$FileBrowser.ShowDialog() # $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("No ISO image mounted or operation cancelled",0,"Error") | 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 # Read-Host "Eject the iso if it is mounted. When ready press Enter" # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter # Read-Host "Mount the iso. When ready press Enter" # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":" # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse -Verbose # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse -Verbose # new-item $usbfat32"\sources" -itemType Directory # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim" -Verbose 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 # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject") DisMount-DiskImage -ImagePath $ImagePath |out-null :ps_usb: ] I wanted to add a "WARNING" pop up message after clicking "Create USB Disk" button but couldn't make the "Cancel" button in the pop up to work. So I just added it to the GUI.
But do you see a real advantage in using a proper hybrid batch-powershell format so that users and you yourself can quickly revision the script without all that messy echo and carret escaping? Just noticed @freddie-o already did it above, but here's my changes that do the elevation inside powershell part as the original (using 544 instead of "Administrator" - think about the poor portuguese users and many others that have this string localized) 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 # [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 # Select the USB disk $global:SelectISO=$False $global:Cancel=$False $Form=New-Object System.Windows.Forms.Form # Create the screen form (window) # $Form |gm;pause # Set the title and size of the window: $Form.Text='Windows installation disk' $Form.Width=490; $Form.Height=210 $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds # Create a drop-down list and fill it $USB=$Null $USBDisks=@() # array with USB disk number $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 $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 } } $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form $SelectUSBDisk.Location=New-Object System.Drawing.Size(10,20) $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10' $SelectUSBDisk.width=200;$SelectUSBDisk.height=20; $Form.Controls.Add($SelectUSBDisk) $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList; $USBDiskList.Location=New-Object System.Drawing.Point(10,40) $USBDiskList.width=450;$USBDiskList.height=20 $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White" $USBDiskList.Font='Segoe UI,10' $Form.Controls.Add($USBDiskList) $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form $SelectISOButton.Location=New-Object System.Drawing.Size(10,100) $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10' $SelectISOButton.width=80;$SelectISOButton.height=60; $Form.Controls.Add($SelectISOButton) $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()}) $Form.Controls.Add($SelectISOButton) $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(350,130) $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10' $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30; $Form.Controls.Add($CreateUSBDiskButton) $CreateUSBDiskButton.Add_Click({$Form.close()}) $Form.Controls.Add($CreateUSBDiskButton) $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form $CancelButton.Location=New-Object System.Drawing.Size(260,130) $CancelButton.Size=New-Object System.Drawing.Size(120,20) $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10' $CancelButton.width=60;$CancelButton.height=30; $Form.Controls.Add($CancelButton) $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()}) $result = $Form.ShowDialog() $USB=$USBDisks[$USBDiskList.SelectedIndex] if ($Cancel){$wshell.Popup("User Cancelled the script",0,"Cancel") | Out-Null;exit} if (!$USB){$wshell.Popup("No USB disk selected",0,"Error") | Out-Null;exit} if (!$global:SelectISO){$wshell.Popup("Operation cancelled. You must select a ISO image",0,"Error") | Out-Null;exit} # # [void]$FileBrowser.ShowDialog() # $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("No ISO image mounted or operation cancelled",0,"Error") | 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 1GB -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 # Read-Host "Eject the iso if it is mounted. When ready press Enter" # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter # Read-Host "Mount the iso. When ready press Enter" # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":" # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse -Verbose # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse -Verbose # new-item $usbfat32"\sources" -itemType Directory # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim" -Verbose 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 # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject") DisMount-DiskImage -ImagePath $ImagePath |out-null Remove-item ($env:TEMP + "\script.ps1") #done - keep a comment on the last line so the previous useful crlf never gets eaten small edit for forensic friendliness: - the powershell process shows the file that got iex instead of just $env:__CMD__
After line 123 of the script in the Op, just add : Code: $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",0,"Warning",1+48) if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-null;exit} BTW you can now suppress lines 72-77.
Upon clicking the cancel button, I got this... Code: Dismount-DiskImage : Cannot bind argument to parameter 'ImagePath' because it is null. At line:99 char:51 + if ($result -eq 2) {DisMount-DiskImage -ImagePath $ImagePath |out-nul ... + ~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Dismount-DiskImage], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Dismount-DiskImage
This is the script working on my system : Spoiler 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 # [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 # Select the USB disk $global:SelectISO=$False $global:Cancel=$False $Form=New-Object System.Windows.Forms.Form # Create the screen form (window) # $Form |gm;pause # Set the title and size of the window: $Form.Text='Windows Installation Disk v3' $Form.Width=495 ; $Form.Height=210 $Form.AutoSize=$true # AutoSize property to make the form automatically stretch, if the elements on the form are out of bounds # Create a drop-down list and fill it $USB=$Null $USBDisks=@() # array with USB disk number $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 $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 } } $SelectUSBDisk=New-Object System.Windows.Forms.Label # Put the SelectUSBDisk label on the form $SelectUSBDisk.Location=New-Object System.Drawing.Size(15,20) $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10' $SelectUSBDisk.width=200;$SelectUSBDisk.height=20; $Form.Controls.Add($SelectUSBDisk) $USBDiskList.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList; $USBDiskList.Location=New-Object System.Drawing.Point(15,40) $USBDiskList.width=450;$USBDiskList.height=20 $USBDiskList.backColor="blue" ; $USBDiskList.ForeColor="White" $USBDiskList.Font='Segoe UI,10' $Form.Controls.Add($USBDiskList) $SelectISOButton=New-Object System.Windows.Forms.Button # Put the SelectISO button on the form $SelectISOButton.Location=New-Object System.Drawing.Size(15,110) $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10' $SelectISOButton.width=80;$SelectISOButton.height=50; $Form.Controls.Add($SelectISOButton) $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()}) $Form.Controls.Add($SelectISOButton) $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(355,130) $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10' $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30; $Form.Controls.Add($CreateUSBDiskButton) $CreateUSBDiskButton.Add_Click({$Form.close()}) $Form.Controls.Add($CreateUSBDiskButton) $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form $CancelButton.Location=New-Object System.Drawing.Size(280,130) $CancelButton.Size=New-Object System.Drawing.Size(120,20) $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,10' $CancelButton.width=60;$CancelButton.height=30; $Form.Controls.Add($CancelButton) $CancelButton.Add_Click({$global:Cancel=$True;$Form.close()}) $result = $Form.ShowDialog() $USB=$USBDisks[$USBDiskList.SelectedIndex] if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit} if (!$USB){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit} if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit} # $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("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit} $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",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 -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 # Read-Host "Eject the iso if it is mounted. When ready press Enter" # $Volumes = (Get-Volume).Where({$_.DriveLetter}).DriveLetter # Read-Host "Mount the iso. When ready press Enter" # $ISO = (Compare-Object -ReferenceObject $Volumes -DifferenceObject (Get-Volume).Where({$_.DriveLetter}).DriveLetter).InputObject # $ISO = (get-volume| Where-Object {($_.DriveType -eq "CD-ROM") -and ($_.filesystemlabel -ne "") -and ($_.OperationalStatus -eq "OK")} |Out-GridView -Title 'Select Cd-Rom image' -OutputMode Single).DriveLetter + ":" # Copy-Item -Path $ISO\* -Destination "$($usbntfs)" -Recurse -Verbose # Copy-Item -Path $ISO"\bootmgr" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\bootmgr.efi" -Destination $usbfat32"\" -Verbose # Copy-Item -Path $ISO"\boot" -Destination $usbfat32"\boot" -Recurse -Verbose # Copy-Item -Path $ISO"\efi" -Destination $usbfat32"\efi" -Recurse -Verbose # new-item $usbfat32"\sources" -itemType Directory # Copy-Item -Path $ISO"\sources\boot.wim" -Destination $usbfat32"\sources\boot.wim" -Verbose 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 # (New-Object -ComObject Shell.Application).Namespace(17).ParseName($ISO).InvokeVerb("Eject") DisMount-DiskImage -ImagePath $ImagePath |out-null #done - keep a comment on the last line so the previous useful crlf never gets eaten
@BAU "what's with the SeT[/USER] "__CMD__=..?" : a copy/paste problem, but script is corrected. btw my Windows is a French one but i can use "Administrator" instead of 544. Windows behaviour is sometimes strange; i have a powershell script where i had to use the localized name "Administrateur" ($admin=(get-wmiobject win32_group| Where-Object {$_.sid -eq "s-1-5-32-544"}).name).
Updated the [Windows installation disk] script in the OP with v3. A new GUI and script elevates and runs using a hybrid batch-powershell format.
The script with some housekeeping Spoiler 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 # [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 v3' $Form.Width=495 ; $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 $Combobox=New-Object System.Windows.Forms.ComboBox $Combobox.DropDownStyle=[System.Windows.Forms.ComboBoxStyle]::DropDownList; $Combobox.Location=New-Object System.Drawing.Point(15,40) $Combobox.Width=450;$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("Please mount USB stick. Click ""OK"" when ready`r`nor ""Cancel"" to exit.",0,"Warning",1+48) 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(15,20) $SelectUSBDisk.Text="Select USB disk";$SelectUSBDisk.Font='Segoe UI,10' $SelectUSBDisk.width=200;$SelectUSBDisk.height=20; $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(355,130) $SelectISOButton.Text="Select ISO";$SelectISOButton.Font='Segoe UI,10' $SelectISOButton.width=110;$SelectISOButton.height=30; $Form.Controls.Add($SelectISOButton) $SelectISOButton.Add_Click({$global:SelectISO=$true;[void]$FileBrowser.ShowDialog()}) $Form.Controls.Add($SelectISOButton) $CreateUSBDiskButton=New-Object System.Windows.Forms.Button # Put the CreateUSBDisk button on the form $CreateUSBDiskButton.Location=New-Object System.Drawing.Size(15,130) $CreateUSBDiskButton.Text="Create USB Disk";$CreateUSBDiskButton.Font='Segoe UI,10' $CreateUSBDiskButton.width=110;$CreateUSBDiskButton.height=30; $Form.Controls.Add($CreateUSBDiskButton) $CreateUSBDiskButton.Add_Click({$Form.close()}) $Form.Controls.Add($CreateUSBDiskButton) $CancelButton=New-Object System.Windows.Forms.Button # Put the Cancel button on the form $CancelButton.Location=New-Object System.Drawing.Size(230,130) $CancelButton.Size=New-Object System.Drawing.Size(120,20) $CancelButton.Text="Cancel";$CancelButton.Font='Segoe UI,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] # if ($Cancel){$wshell.Popup("The script was cancelled.",0,"Cancel") | Out-Null;exit} if ($USB -eq $Null){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit} if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit} # $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("No ISO image mounted or operation cancelled",0,"Error") | Out-Null;exit} # $Result=$wshell.Popup("All partitions and data on the USB disk will be lost.",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 -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
So we don't need this anymore? Code: if ($USB -eq $Null){$wshell.Popup("No USB disk detected.",0,"Error") | Out-Null;exit} Can this scenario Code: $Result=$wshell.Popup("Please mount USB stick. Click ""OK"" when ready`r`nor ""Cancel"" to exit.",0,"Warning",1+48) if ($result -eq 2) {exit} $Disks=Get-Disk | Where-Object {($_.BusType -eq "USB") -and ($_.OperationalStatus -eq "Online")} be applied here too? Code: if (!$global:SelectISO){$wshell.Popup("No ISO image selected.",0,"Error") | Out-Null;exit} so instead of exiting the script, you can go back to the GUI to select the ISO?