SCCM OSD with multiple disks

OSD with systems that have multiple disks can be troublesome. Out of the box, SCCM TS steps don’t offer much in regards to this. You can make Format Drive steps for each disk, but there is no immediate way to identify which disk is which!
Even going into BIOS to check which disk is on which channel won’t help. At each boot, Windows may interpret the disk channels differently: https://support.microsoft.com/en-us/help/937251/disk-drive-numbers-may-not-correspond-to-the-sata-channel-numbers-when

BUT, all hope is not lost. SCCM has a TS variable named OSDDiskIndex. The docs (https://technet.microsoft.com/en-us/library/hh273365.aspx) describe it as “Specifies the physical disk number to be partitioned.”. Hm, specify it how? Well, basically you find the number ID of the disk you want to specify for formatting, and you give that number to the OSDDiskIndex variable. How do we do this? You guessed it, with Powershell of course!

Since Server 2012/Windows 8, there exists the cmdlet Get-PhysicalDisk. You’d think it’d be a part of Powershell 3.0 for Windows 7/2008 R2, but for some reason the storage modules were not included in that (https://blogs.technet.microsoft.com/heyscriptingguy/2012/10/26/use-powershell-to-create-a-bootable-usb-drive/). I don’t know if it’s included in PS 4.0 and higher. But don’t fret, I will show how to accomplish the same thing with a WMI query.

Get-PhysicalDisk

Get-PhysicalDisk is a nice cmdlet. It gives all the relevant information you could wish for from a disk. For OSD, you probably want to differentiate disks on two criteria, SSD/HDD and size.
Getting disk type is easy. The MediaType property of a disk object from the cmdlet describes if the disk is an SSD or HDD. Size is decribed in the… size property! What else do we want? Oh, right the most important one, the ID! This is in DeviceID property.
Output example:

So, in a two disk scenario, where one disk is SSD and you want to select it, the command is as simple as

Get-PhysicalDisk | Where-Object MediaType -eq 'SSD' | Select-Object -ExpandProperty DeviceID

This will give us the ID of the disk that is an SSD.
Defining on size basis is easy as well (300GB):

Get-PhysicalDisk | Where-Object {$_.Size/1GB -gt 300} | Select-Object -ExpandProperty DeviceID

For combination of size and SSD:

Get-PhysicalDisk | Where-Object {$_.MediaType -eq 'SSD' -and  $_.Size/1GB -gt 300} | Select-Object -ExpandProperty DeviceID

WMI

This is all fine and dandy if you’re on at least Win8/2012/PE4.0 (or possibly Powershell 4.0 or higher on Win7/2008), but what if you’re not? Good old WMI it is then! Here’s the last example in WMI:

Get-WmiObject Win32_DiskDrive | Where {$_.Model -match "SSD" -and $_.Size/1GB -gt 300} | Select-Object -ExpandProperty Index

Basically, we use Win32_DiskDrive WMI class to get disk info. Sadly, there is no definite property in WMI that will tell if disk is SSD or not… But in my experience, all SSDs have “SSD” in the model name, so we’ll have to make do with that. Lastly, the ID of the disk is in the Index property.

So now we should know how to find the disk we want to partition. Next, let’s pass this information to the SCCM TS variable OSDDiskIndex, so the TS partition step will select the disk we want!

I find using Run Command Line TS step, with powershell.exe with the Command argument is the easiest way to run one-liners.

In the one-liner, we simply give the OSDDiskIndex variable the ID of the disk.

PowerShell -ExecutionPolicy Bypass -Command " (New-Object -COMObject Microsoft.SMS.TSEnvironment).Value('OSDDiskIndex') = Get-PhysicalDisk | Where-Object {$_.MediaType -eq 'SSD' -and  $_.Size/1GB -gt 300} | Select-Object -ExpandProperty DeviceID "

Of course, if you want to use WMI, replace the second portion of the command argument with the WMI equivalent.

When you run this, that disk will now be selected for later partitioning step.