Skip to content

Instantly share code, notes, and snippets.

@bashenk
Last active December 22, 2020 23:38
Show Gist options
  • Save bashenk/7b0fcfcc9672f2ccb9201c862f5fd369 to your computer and use it in GitHub Desktop.
Save bashenk/7b0fcfcc9672f2ccb9201c862f5fd369 to your computer and use it in GitHub Desktop.
function Format-NewBootableUSB() {
[CmdletBinding(DefaultParameterSetName='Default')]
Param(
[Parameter(Position=0,Mandatory=$True,ParameterSetName='Default')]
[Parameter(Position=0,Mandatory=$True,ParameterSetName='CopyOnly')]
[String]$FirstPartitionSourceFolder,
[Parameter(Position=1,ParameterSetName='Default')]
[Parameter(Position=1,ParameterSetName='CopyOnly')]
[String]$SecondPartitionSourceFolder,
[Parameter(Position=2,ParameterSetName='Default')]
[String]$FirstPartitionName,
[Parameter(Position=3,ParameterSetName='Default')]
[String]$SecondPartitionName,
[Parameter(ParameterSetName='CopyOnly')]
[Switch]$CopyOnly,
[Parameter(Position=2,ParameterSetName='CopyOnly')]
[String]$FirstPartitionDriveLetter,
[Parameter(Position=3,ParameterSetName='CopyOnly')]
[String]$SecondPartitionDriveLetter
)
$ErrorActionPreference='Stop'
if (-not $PSBoundParameters.ContainsKey('CopyOnly')) {
If (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw 'Format-NewBootableUSB must be run as Administrator'
}
$disks = Get-Disk | Where-Object {$_.Path.StartsWith('\\?\usbstor#disk')}
if ($null -eq $disks -or $disks.Count -eq 0) {throw "Please insert a USB device first."}
$disk = $disks | Sort-Object -Property "Number" | Out-GridView -Title 'Which disk do you want to format?' -PassThru
if ($null -eq $disk) {
$disk = Get-Disk -Number $(disks | Sort-Object -Property "Number" | ForEach-Object { Get-Partition -DiskNumber $_.Number 2>$null } | Out-GridView -Title 'Which drive do you want to format?' -PassThru).DiskNumber
if ($null -eq $disk) {
Return
}
}
if ($PSVersionTable.PSVersion.Major -le 5) {
# PowerShell Core appears to not require this to be loaded.
try {[Void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')} catch {throw}
}
if ([String]::IsNullOrWhiteSpace($FirstPartitionName)) {
$FirstPartitionName = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a name for the first partition (Windows boot media)','Partition 1','WinPE')
}
if ([String]::IsNullOrWhiteSpace($FirstPartitionName)) {Return}
if ([String]::IsNullOrWhiteSpace($SecondPartitionName)) {
$SecondPartitionName = [Microsoft.VisualBasic.Interaction]::InputBox('Enter a name for the second partition (images/scripts/etc)','Partition 2','Images')
}
if ([String]::IsNullOrWhiteSpace($SecondPartitionName)) {Return}
$diskNum = $disk.Number
$response=(New-Object -ComObject "WScript.Shell").PopUp("Proceeding to completely clean and format Disk $diskNum.`nDisk $diskNum contains the following partitions:`n$(Get-Partition -DiskNumber $diskNum|Out-String)`n`nAre you sure you wish to proceed?",$null,"Formatting Disk #$diskNum",49)
if ($response -ne 1) {
# User did not click OK
Return
}
Clear-Disk -Number $diskNum -RemoveData -RemoveOEM -Confirm
Reset-PhysicalDisk -UniqueID $Disk.UniqueID
# $disk = Initialize-Disk -Number $DiskNum -PartitionStyle MBR -PassThru
$FirstPartitionDriveLetter = Get-FirstAvailableDriveLetter
$FirstPartition = New-Partition -DiskNumber $diskNum -Size 2GB -IsActive:$True
$FirstPartition | Format-Volume -FileSystem FAT32 -NewFileSystemLabel $FirstPartitionName
$FirstPartition | Set-Partition -NewDriveLetter $FirstPartitionDriveLetter
Bootsect /Nt60 "$($FirstPartitionDriveLetter):"
$FirstPartition | Set-Partition -IsHidden $True -ErrorAction Continue # This was failing for some reason.
$SecondPartitionDriveLetter = Get-FirstAvailableDriveLetter
$SecondPartition = New-Partition -DiskNumber $diskNum -UseMaximumSize
$SecondPartition | Format-Volume -FileSystem NTFS -NewFileSystemLabel $SecondPartitionName
$SecondPartition | Set-Partition -NewDriveLetter $SecondPartitionDriveLetter
}
if ($null -ne $FirstPartitionDriveLetter -and $PSBoundParameters.ContainsKey('FirstPartitionSourceFolder') -and ([System.IO.DirectoryInfo]$FirstPartitionSourceFolder).Exists) {
cmd /c "robocopy `"$($FirstPartitionSourceFolder)`" $($FirstPartitionDriveLetter):\ /E /ZB /J /FFT /DCOPY:DAT /NJH /R:1 /W:1 /XD `"$($FirstPartitionDriveLetter):\System Volume Information`" `"$($FirstPartitionSourceFolder)\System Volume Information`""
}
if ($null -ne $SecondPartitionDriveLetter -and $PSBoundParameters.ContainsKey('SecondPartitionSourceFolder') -and ([System.IO.DirectoryInfo]$SecondPartitionSourceFolder).Exists) {
cmd /c "robocopy `"$($SecondPartitionSourceFolder)`" $($SecondPartitionDriveLetter):\ /E /ZB /J /DCOPY:DAT /NJH /R:1 /W:1 /XD `"$($SecondPartitionDriveLetter):\System Volume Information`" `"$($SecondPartitionSourceFolder)\System Volume Information`""
if ($? -eq $False) {Return}
}
}
function Get-FirstAvailableDriveLetter() {
for($j=67; Get-PSDrive([char]$j) -ErrorAction Ignore){
$j++
}
[char]$j
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment