@@ -103,13 +103,24 @@ function Invoke-WinUtilISOWriteUSB {
103103 try {
104104 SetProgress " Formatting USB drive..." 10
105105
106- # Phase 1: Clean disk via diskpart
106+ # Phase 1: Clean disk via diskpart (retry once if the drive is not yet ready)
107107 $dpFile1 = Join-Path $env: TEMP " winutil_diskpart_$ ( Get-Random ) .txt"
108108 " select disk $diskNum `n clean`n exit" | Set-Content - Path $dpFile1 - Encoding ASCII
109109 Log " Running diskpart clean on Disk $diskNum ..."
110- diskpart / s $dpFile1 2>&1 | Where-Object { $_ -match ' \S' } | ForEach-Object { Log " diskpart: $_ " }
110+ $dpCleanOut = diskpart / s $dpFile1 2>&1
111+ $dpCleanOut | Where-Object { $_ -match ' \S' } | ForEach-Object { Log " diskpart: $_ " }
111112 Remove-Item $dpFile1 - Force - ErrorAction SilentlyContinue
112113
114+ if (($dpCleanOut -join ' ' ) -match ' device is not ready' ) {
115+ Log " Disk $diskNum was not ready; waiting 5 seconds and retrying clean..."
116+ Start-Sleep - Seconds 5
117+ Update-Disk - Number $diskNum - ErrorAction SilentlyContinue
118+ $dpFile1b = Join-Path $env: TEMP " winutil_diskpart_$ ( Get-Random ) .txt"
119+ " select disk $diskNum `n clean`n exit" | Set-Content - Path $dpFile1b - Encoding ASCII
120+ diskpart / s $dpFile1b 2>&1 | Where-Object { $_ -match ' \S' } | ForEach-Object { Log " diskpart: $_ " }
121+ Remove-Item $dpFile1b - Force - ErrorAction SilentlyContinue
122+ }
123+
113124 # Phase 2: Initialize as GPT
114125 Start-Sleep - Seconds 2
115126 Update-Disk - Number $diskNum - ErrorAction SilentlyContinue
@@ -122,7 +133,8 @@ function Invoke-WinUtilISOWriteUSB {
122133 Log " Disk $diskNum converted to GPT (was $ ( $diskObj.PartitionStyle ) )."
123134 }
124135
125- # Phase 3: Create FAT32 partition via diskpart
136+ # Phase 3: Create FAT32 partition via diskpart, then format with Format-Volume
137+ # (diskpart's 'format' command can fail with "no volume selected" on fresh/never-formatted drives)
126138 $volLabel = " W11-" + (Get-Date ).ToString(' yyMMdd' )
127139 $dpFile2 = Join-Path $env: TEMP " winutil_diskpart2_$ ( Get-Random ) .txt"
128140 $maxFat32PartitionMB = 32768
@@ -136,29 +148,38 @@ function Invoke-WinUtilISOWriteUSB {
136148 @ (
137149 " select disk $diskNum "
138150 $createPartitionCommand
139- " select partition 1"
140- " format quick fs=fat32 label=`" $volLabel `" "
141151 " exit"
142152 ) | Set-Content - Path $dpFile2 - Encoding ASCII
143153 Log " Creating partitions on Disk $diskNum ..."
144154 diskpart / s $dpFile2 2>&1 | Where-Object { $_ -match ' \S' } | ForEach-Object { Log " diskpart: $_ " }
145155 Remove-Item $dpFile2 - Force - ErrorAction SilentlyContinue
146156
147- SetProgress " Assigning drive letters ..." 30
157+ SetProgress " Formatting USB partition ..." 25
148158 Start-Sleep - Seconds 3
149159 Update-Disk - Number $diskNum - ErrorAction SilentlyContinue
150160
151161 $partitions = Get-Partition - DiskNumber $diskNum - ErrorAction Stop
152- Log " Partitions on Disk $diskNum after format : $ ( $partitions.Count ) "
162+ Log " Partitions on Disk $diskNum after creation : $ ( $partitions.Count ) "
153163 foreach ($p in $partitions ) {
154164 Log " Partition $ ( $p.PartitionNumber ) Type=$ ( $p.Type ) Letter=$ ( $p.DriveLetter ) Size=$ ( [math ]::Round($p.Size / 1 MB )) MB"
155165 }
156166
157167 $winpePart = $partitions | Where-Object { $_.Type -eq " Basic" } | Select-Object - Last 1
158168 if (-not $winpePart ) {
159- throw " Could not find the WINPE ( Basic) partition on Disk $diskNum after format ."
169+ throw " Could not find the Basic partition on Disk $diskNum after creation ."
160170 }
161171
172+ # Format using Format-Volume (reliable on fresh drives; diskpart format fails
173+ # with 'no volume selected' when the partition has never been formatted before)
174+ Log " Formatting Partition $ ( $winpePart.PartitionNumber ) as FAT32 (label: $volLabel )..."
175+ Get-Partition - DiskNumber $diskNum - PartitionNumber $winpePart.PartitionNumber |
176+ Format-Volume - FileSystem FAT32 - NewFileSystemLabel $volLabel - Force - Confirm:$false | Out-Null
177+ Log " Partition $ ( $winpePart.PartitionNumber ) formatted as FAT32."
178+
179+ SetProgress " Assigning drive letters..." 30
180+ Start-Sleep - Seconds 2
181+ Update-Disk - Number $diskNum - ErrorAction SilentlyContinue
182+
162183 try { Remove-PartitionAccessPath - DiskNumber $diskNum - PartitionNumber $winpePart.PartitionNumber - AccessPath " $ ( $winpePart.DriveLetter ) :" - ErrorAction SilentlyContinue } catch {}
163184 $usbLetter = Get-FreeDriveLetter
164185 if (-not $usbLetter ) { throw " No free drive letters (D-Z) available to assign to the USB data partition." }
@@ -167,6 +188,12 @@ function Invoke-WinUtilISOWriteUSB {
167188 Start-Sleep - Seconds 2
168189
169190 $usbDrive = " ${usbLetter} :"
191+ $retries = 0
192+ while (-not (Test-Path $usbDrive ) -and $retries -lt 6 ) {
193+ $retries ++
194+ Log " Waiting for $usbDrive to become accessible (attempt $retries /6)..."
195+ Start-Sleep - Seconds 2
196+ }
170197 if (-not (Test-Path $usbDrive )) { throw " Drive $usbDrive is not accessible after letter assignment." }
171198 Log " USB data partition: $usbDrive "
172199
0 commit comments