views:

838

answers:

2

The API for creating a new volume on our SAN is pretty straight forward. What I have not been able to figure out is how to programatically connect the iSCSI initiator to it, initialize the space (in the windows disk manager sense) and finally format it and mount it is a drive letter.

I currently use win2k3, however moving to win2k8 is an option if it would simplify implementing this.

+1  A: 

I had to implement disk initialization, partitioning, and formatting for one of my company's products. I can't share the code but I can point you in the right direction.

The API you want is called VDS - Virtual Disk Service. It's a COM API, but I've used it successfully from C++ (with ATL) and C# (COM interop).

Sadly the documentation is quite lacking; you just have to immerse yourself in the object model, write some code, and gradually you get a feel for it.

Windows Server 2008 ships with an undocumented but quite usable C# wrapper around VDS. Look for a DLL called Microsoft.Storage.Vds.dll. You can use Reflector to discover its various classes and methods. I found out about this when I read this blog post, in which the author is trying to initialize a disk from PowerShell using the aforementioned DLL.

VDS includes APIs that could be implemented by SAN vendors to provision a LUN and do other SAN things; suggest you avoid those and focus on the basic software provider, which will create basic (as opposed to dynamic) partitions on either an MBR or GPT disk. Note that the Microsoft wrapper I mentioned is a bit light on GPT support; I had to modify it a bit to get GPT disks working.

VDS is a complex and finicky API, but if you're just looking to initialize a disk, create a partition, format it, and mount it to a drive letter, most of what you need is there and fairly easy to do. Good luck.

anelson
A: 

I have done this from Powershell using diskpart with a script.

Something like:

$target    = ''    #Desired target IQN
$partition = 1     #Desired partition
$drvLetter = ''    #Desired drive letter

#get the disk device number from the iscsi session class (diskpart needs it)
$iscsiSsn = gwmi -namespace "root\wmi" -class MSiSCSIInitiator_SessionClass
$diskNum = ($($iscsiSsn | where { $_.targetname -eq $target}).devices).deviceNumber

#create the diskpart script on-the-fly then call the utility
$dskPrtScr = "$($env:temp)\diskpart.scr"
"sel disk $diskNum`nsel par 1`nassign letter=$drvLetter`nexit" | out-file $dskPrtScr -encoding ascii
diskpart /s $dskPrtScr
Tom