ISOtoUSB Powershell script

I have created the script below using powershell to demonstrate the new storage features available in powershell on Windows 8 and Server 2012. This is also a pretty good example of how to build a GUI with powershell and window.forms. Unfortunately it will only work on Windows 8 or Server 2012 or higher even if you install powershell 4.0 the storage module is part of the OS so not available in Windows 7. The script will clean then format and make active the selected USB key then copy the selected ISO onto it. Feel free to use or modify
LINK TO THE SCRIPT IN A ZIP FILE
-----------------------------------------------------------Cut below line----------------------------------------------------------------------------------#######################################################################################################
# ISOtoUSB.ps1
# By: JAW
# This script will create a bootable USB key and copy an ISO image onto it.
# Window 8 or server 2012 and higher only
###########################################################################
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
# We are running "as Administrator" - so change the title and background color to indicate this
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "DarkBlue"
clear-host
}
else
{
# We are not running "as Administrator" - so relaunch as administrator
# Create a new process object that starts PowerShell
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
# Specify the current script path and name as a parameter
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
# Indicate that the process should be elevated
$newProcess.Verb = "runas";
# Start the new process
[System.Diagnostics.Process]::Start($newProcess);
# Exit from the current, unelevated, process
exit
}
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#FUNCTIONS
function Validate-Input{
$valid = $true
if($objTextBox.Text -eq ""){
$valid =$false
[System.Windows.Forms.MessageBox]::Show("You must select an ISO file.")
}
if($comboBox1.SelectedIndex -eq -1 )
{$valid =$false
[System.Windows.Forms.MessageBox]::Show("You must select a USB Drive letter")
}
return $valid
}
function Combine-Object {
param(
$object1,
$object2
)
trap {
$a = 1
continue
}
$propertylistObj1 = @($object1 | Get-Member -ea Stop -memberType *Property | Select-Object -ExpandProperty Name)
$propertylistObj2 = @($object2 | Get-Member -memberType *Property | Select-Object -ExpandProperty Name | Where-Object { $_ -notlike '__*'})
$propertylistObj2 | ForEach-Object {
if ($propertyListObj1 -contains $_) {
$name = '_{0}' -f $_
} else {
$name = $_
}
$object1 = $object1 | Add-Member NoteProperty $name ($object2.$_) -PassThru
}
$object1
}
function Get-Drives {
Get-WmiObject Win32_DiskPartition |
ForEach-Object {
$partition = $_
$logicaldisk = $partition.psbase.GetRelated('Win32_LogicalDisk')
if ($logicaldisk -ne $null) {
Combine-Object $logicaldisk $partition
}
} | select-Object Name, VolumeName, DiskIndex, Index
}
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "ISO files (*.iso)| *.iso"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
} #end function Get-FileName
#end functions
#THE FORM
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "ISOtoUSB for Windows 8 / Server 2012"
$objForm.Size = New-Object System.Drawing.Size(470,200)
$objForm.StartPosition = "CenterScreen"
#first label
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(85,20)
$objLabel.Text = "Select ISO file:"
$objForm.Controls.Add($objLabel)
#Textbox for iso filename
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(110,20)
$objTextBox.Size = New-Object System.Drawing.Size(55,80)
$objTextBox.width = 235
$objForm.Controls.Add($objTextBox)
#Browse button for ISO
$BrowseButton = New-Object System.Windows.Forms.Button
$BrowseButton.Location = New-Object System.Drawing.Size(360,18)
$BrowseButton.Size = New-Object System.Drawing.Size(75,23)
$BrowseButton.Text = "Browse"
$BrowseButton.Add_Click({$objTextBox.Text = Get-FileName("C:\"); })
$objForm.Controls.Add($BrowseButton)
#Select USB label
$objLabe2 = New-Object System.Windows.Forms.Label
$objLabe2.Location = New-Object System.Drawing.Size(10,50)
$objLabe2.Size = New-Object System.Drawing.Size(100,20)
$objLabe2.Text = "Select USB Drive:"
$objForm.Controls.Add($objLabe2)
#Get removable devices and populate drives combobox
$Devices = @(Get-WmiObject -Query "Select * From Win32_LogicalDisk" | ? { $_.driveType -eq 2 })
$comboBox1 = New-Object System.Windows.Forms.ComboBox
$comboBox1.Location = New-Object System.Drawing.Point(110, 50)
$comboBox1.Size = New-Object System.Drawing.Size(55, 310)
ForEach ($Device in $Devices){
$drive = gwmi win32_volume | Where-Object {$_.DriveLetter -eq ($Device.DeviceID)} | Select-Object DriveLetter
if( $drive.driveletter -ne 0){$comboBox1.Items.add( $drive.driveletter )}
}
$objForm.Controls.Add($comboBox1)
#Refresh button for USB Drives
$RefreshButton = New-Object System.Windows.Forms.Button
$RefreshButton.Location = New-Object System.Drawing.Size(170,50)
$RefreshButton.Size = New-Object System.Drawing.Size(75,23)
$RefreshButton.Text = "Refresh"
$RefreshButton.Add_Click({
$Devices = @(Get-WmiObject -Query "Select * From Win32_LogicalDisk" | ? { $_.driveType -eq 2 })
$comboBox1.items.clear()
$comboBox1.SelectedIndex = -1
ForEach ($Device in $Devices){
$drive = gwmi win32_volume | Where-Object {$_.DriveLetter -eq ($Device.DeviceID)} | Select-Object DriveLetter
if( $drive.driveletter -ne 0){$comboBox1.Items.add( $drive.driveletter )}
}
})
$objForm.Controls.Add($RefreshButton)
#FAT32 for UEFI BIOS checkbox
$objTypeCheckbox = New-Object System.Windows.Forms.Checkbox
$objTypeCheckbox.Location = New-Object System.Drawing.Size(10,80)
$objTypeCheckbox.Size = New-Object System.Drawing.Size(200,20)
$objTypeCheckbox.Text = "FAT32 for UEFI only BIOS"
$objForm.Controls.Add($objTypeCheckbox)
#Main GO button to format key and copy ISO
$GoButton = New-Object System.Windows.Forms.Button
$GoButton.Location = New-Object System.Drawing.Size(10,110)
$GoButton.Size = New-Object System.Drawing.Size(140,33)
$GoButton.Text = "Format USB Key and copy ISO Image"
$GoButton.Add_Click({
$test = Validate-Input
if( $test -eq $true){
#File system type
$fs = "NTFS"
if($objTypeCheckbox.Checked -eq $true){$fs ="FAT32";}
Write-Progress -Activity 'Preparing drive to copy files.' -Status " 10 percent" -PercentComplete 10
#Get disk # for selected drive letter
$a = Get-Drives | Where-Object {$_.name -eq ($comboBox1.SelectedItem)} | Select-Object DiskIndex
#clean disk
Clear-Disk -Number $a.diskIndex -RemoveData -Confirm:$false
Write-Progress -Activity 'Preparing drive' -Status " 30 percent" -PercentComplete 30
#partition and format
$letter = $comboBox1.SelectedItem
$letter = $letter.substring(0,1)
New-Partition -DiskNumber $a.diskIndex -DriveLetter $letter -UseMaximumSize -IsActive:$true | Format-Volume -FileSystem $fs -NewFileSystemLabel "ISOtoUSB" -Confirm:$false
Write-Progress -Activity 'Preparing drive' -Status " 100 percent" -PercentComplete 100
Write-Progress "Done" "Done" -completed
#mount ISO file
$mountVolume = MOUNT-DISKIMAGE $objTextBox.Text
#get mounted drive letter
$driveLetter = (Get-DiskImage $objTextBox.Text | Get-Volume).DriveLetter
$driveLetter = $driveLetter + ":\*"
#create progress bar and copy files
$FOF_CREATEPROGRESSDLG = "&H0&"
$objShell = New-Object -ComObject "Shell.Application"
$dest = $letter + ":\"
$objFolder = $objShell.NameSpace( "$dest")
$objFolder.CopyHere( $driveLetter, $FOF_CREATEPROGRESSDLG)
#Dismount ISO image
Dismount-DiskImage $objTextBox.Text
[System.Windows.Forms.MessageBox]::Show("USB Key ready to use.")
}}) #end click function
$objForm.Controls.Add($GoButton )
#Cancel button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(170,112)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objForm.Topmost = $false
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
------------------------------------end cut above line ----------------------------------------------------------------