How to automate a command line utility like DiskPart (vbscript)

Hi all,

The other day I created a VBScript to automate DiskPart.exe tool and be able to perform tasks on a disk after selecting it by LUN ID. Note that Diskpart only allow us to select disks by their index number or their location path.

Bellow you can see a sample Diskpart.exe script, and how I managed to do the same stuff with VBScript after finding the right disk by its LUN ID. In general, this sample will show you how automate any other command line tool by sending commands to it and reading and parsing its output:

 

 ' ===================================================================

' Sample diskpart script:

'

'   rescan

'   sel disk 37

'   sel vol 0

'   assign letter f

'   exit

'



' ===================================================================

' PARAMETERS

' ===================================================================

' Get LUN ID and letter to assign from user. 

If Wscript.Arguments.Count <> 2 Then 

    ' If we didn't pass them as params to the script, ask the user 

    ' for them

    iLunId = CInt(InputBox("Enter LUN ID"))

    cLetter = InputBox("Enter letter")

Else

    iLunId = CInt(Wscript.Arguments(0))

    cLetter = Wscript.Arguments(1)

End If



' ===================================================================

' MAIN

' ===================================================================



' Run diskpart

set objShell = WScript.CreateObject("WScript.Shell")

set objExec = objShell.Exec("diskpart.exe")



' Let's find the disk which LUN ID we need



' Rescan the disks

strOutput = ExecuteDiskPartCommand("rescan")

WScript.echo strOutput



' Select the first disk

strOutput = ExecuteDiskPartCommand("sel disk 0")

WScript.echo strOutput



' Iterate through the disks until we find the one we need

bFoundDisk = false

Do While InStr(strOutput, "There is no disk selected") = 0

    

    ' See current disk details

    strOutput = ExecuteDiskPartCommand("detail disk")

    WScript.echo strOutput



    ' Is this the disk which LUN ID is the one we are looking for?

    If (GetLunId(strOutput) = iLunId) Then

        ' Yes. Launch the rest of the commands on the original diskpart script

        strOutput = ExecuteDiskPartCommand("sel vol 0")

        WScript.echo strOutput



        strOutput = ExecuteDiskPartCommand("assign letter " & cLetter)

        WScript.echo strOutput

        

        ' We are done. We can leave now

        bFoundDisk = true

        Exit Do

    End If

    

    ' We didn't find the disk. Move to the next one

    strOutput = ExecuteDiskPartCommand("sel disk next")

    WScript.echo strOutput    

Loop



' We can close diskpart already

ExitDiskPart



WScript.echo "***********************************************************************"

WScript.echo "Script has finished. DiskPart has been closed"

If bFoundDisk Then

     WScript.echo "RESULT: We successfully run desired commands on disk with LUN ID = " & iLunId

Else

    WScript.echo "RESULT: We COULD NOT find the disk with LUN ID = " & iLunId

End If

WScript.echo "***********************************************************************"





' ===================================================================

' HELPER FUNCTIONS

' ===================================================================



Function ExecuteDiskPartCommand (strCommand)



    ' Run the command we want

    objExec.StdIn.Write strCommand & VbCrLf

         

    ' If we read the output now, we will get the one from previous command (?). As we will always

    ' run a dummy command after every valid command, we can safely ignore this

    Do While True

        IgnoreThis = objExec.StdOut.ReadLine & vbcrlf              



        ' Command finishes when diskpart prompt is shown again

        If InStr(IgnoreThis, "DISKPART>") <> 0 Then Exit Do

    Loop

    

    ' Run a dummy command, so the next time we call this function and try to read output,

    ' we can safely ignore the result

    objExec.StdIn.Write VbCrLf

         

    ' Read command's output

    ExecuteDiskPartCommand = ""    

    Do While True

        ExecuteDiskPartCommand = ExecuteDiskPartCommand & objExec.StdOut.ReadLine & vbcrlf              



        ' Command finishes when diskpart prompt is shown again

        If InStr(ExecuteDiskPartCommand, "DISKPART>") <> 0 Then Exit Do

    Loop



End Function



Function GetLunId(strDetails)

    ' Parse the details of the disk

    arrayLines = Split(strDetails, vbcrlf)

    for i = LBound(arrayLines) to UBound(arrayLines)

        If (InStr(arrayLines(i), "LUN ID : ") <> 0) Then

        

            ' We found the LUN ID. Return it

            GetLunId = CInt(Mid(arrayLines(i), Len("LUN ID : ")))

            Exit For

        End If

    next

End Function



Sub ExitDiskPart

    ' Run exit command to exit the tool

    objExec.StdIn.Write "exit" & VbCrLf

End Sub




I hope this helps.

Regards,

 

Alex (Alejandro Campos Magencio)