The other day, as I was working with a customer on implementing a Windows 10, version 1803 based MDT task sequence, one of IT technicians mentioned that they had issues installing newly received HP ProDesk 600 MT G3 computers. These computers (at least the top tier configuration with Intel Core i7 and 16 GB RAM) have a somewhat unique hard drives configuration: on the inside, there are actually two disks: an HDD and an SSD. The problem: the SSD is being identified as Disk 1, which leads to two issues:
- MDT picks the HDD as the first boot device and uses it during the "Format and Partition" step.
- After applying the OS image, an attempt to create BCD entries will fail at the Verify BCDBootEx step with the following exit code: 15250.
I verified the issue, checked the log files, but could not find anything that would explain the problem right away. However, when looking at the attached disks I noticed that there were two Windows installations: one on the HDD (performed by the Microsoft Deployment Toolkit) and one on the SSD (HP's Windows 10 factory image). My assumption, therefore, was that the existing Windows 10 installation broke MDT function that creates a new boot entry for the new OS using BCDBoot.exe.
Running diskpart clean on the SSD in order to remove the factory image would only solve part of the problem: MDT (and Configuration Manager for that matter) would still pick the slower HDD for the OS installation. This is the expected behavior as by default each task sequence assumes that the first enumerated fixed disk should be used during the Format and Partition Disk step.
My goal now was to identify a workaround which would allow the customer to dynamically determine if the internal SSD was enumerated as the first or second boot device and adjust disk number for the Format and Partition (UEFI) task sequence step accordingly. There are actually multiple ways to achieve this:
- Assuming that all HP ProDesk 600 MT G3 models come with the same fixed disk configuration, one could simply duplicate the "Format and Partition (UEFI)" disk step, change the disk index to 1 and test for "HP ProDesk 600 MT G3" in order to use the modified step just for this particular model. Personally, I would not go down this path as it makes a few assumptions and things typically change down the road.
- You could modify the ZTIDiskPart script - which creates the disk partitions on the target computer by calling the Diskpart utility - as demonstrated by Keith Garner on multiple occasions by dynamically altering the OSDDiskIndex variable.
- Finally - and this is the solution I opted for - you could use a PowerShell script to query hard drive configuration. While this approach involves modifying your task sequences, it is MDT version agnostic and does not require reapplying your code modifications with each Microsoft Deployment Toolkit update. So I went ahead and wrote a small PowerShell script that uses Get-Disk and Get-PhysicalDisk cmdlets to query fixed disks attached to a system and pulls FriendlyName, MediaType and Number properties, merges the results together using Warren F's Join-Object function, and finally sets a variable which can be used to preselect one of "Format and Partition" steps in the task sequence.
I added the script to the MDT task sequence in the Pre-Install phase, performed the necessary modifications and - positive I'd solved my issue - ran the task sequence. To my immense satisfaction, the installation ran through. Case closed! As for why the creation of the new boot entry did not work in the first place, with everything else on my plate I haven’t had the time to investigate further.
Code Snippet:
Switch ($Model){ "HP ProDesk 600 G3 MT"{ #Note: we need to make sure that SSD is not the first boot device, so we need to evaluate the disk number as well $disksorder = Get-Disk | Select-Object Number,FriendlyName $physicaldisks = Get-PhysicalDisk | Select-Object FriendlyName,MediaType $disks = Join-Object -Left $disksorder -Right $physicaldisks -LeftJoinProperty FriendlyName -RightJoinProperty FriendlyName Write-Host "$($myInvocation.MyCommand) - Processing retrieved physical disks." Write-Host "$($myInvocation.MyCommand) - " $disks foreach($disk in $disks) { if($disk.MediaType -like "SSD" -and $disk.Number -gt "0") { Write-Host "$($myInvocation.MyCommand) - SSD drive detected and it is not the first boot device." $TSenv.Value("IsNVMe") = "TRUE" Exit 0 } if($disk.MediaType -like "SSD" -and $disk.Number -eq "0") { Write-Host "$($myInvocation.MyCommand) - SSD drive detected and it is the first boot device. No change required." Exit 0 } } }
Note: The script has only been tested on HP ProDesk 600 MT G3 but should work for other models as well provided you adjust the script to match your model(s).
How does it work:
Should you end up in the same boat, follow these steps to work around the problem:
- Add the SSDVerifier script to your MDT deployment share and insert it into your Windows 10 task sequence before Format and Partition steps.
- Add IsNVME property to your CustomSettings.ini.
- Duplicate your "Format and Partition (UEFI)" step and adjust execution conditions as illustrated below:
- Make sure that disk index on the alternative "Format and Partition (UEFI)" step is set to 1.
That's it!
Tweet me if you fancy or have any questions.