Summary: Honorary Scripting Guy, Sean Kearney, continues his series about using Windows Powershell to build scripts to automate DiskPart.
Hey, Scripting Guy! I saw yesterday that you can use Windows PowerShell to build a small script for DiskPart, but how can I make the information useful?
—SH
Hello SH,
Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson. He appears to have overdone his tie house, and it’s bending under the weight. You could say it’s “bow”ing.
Enough of the bad puns. Yesterday we used Windows PowerShell to build a tiny DiskPart script and launch DiskPart to capture the output to count disks. Today we’re going to dive in a little deeper and get some useful information out of it. If we look at a sample screen output from DiskPart, we can identify some key features we’ll want.
Note This is Part 2 in a series. If you are behind, read:
We’ll need the disk number. This is normally in sequence, but if a drive is removed, you’ll find that the values have gaps.
We’ll need the size. The reason for this is that I want to know if we have an 8 GB flash device or 500 GB flash device. If it’s larger than 64 GB (for my purposes), I’m going to presume that’s a removable hard drive.
But looking here, I don’t see anything showing me the device type. For that, there is a Detail command in DiskPart that we can leverage to show us that information. See the following output as an example:
You can see the Type for this particular device is USB. So we CAN get this information from the output from DISKPART. We just need to establish the pattern for the information.
Really we have a fairly easy pattern to work with on the LIST DISK output. We already know from the previous day that we can pull the number of disks from the output. So we only need to pull out the bottom number of lines. In Windows PowerShell if you access an array with element [-1] you will always access the bottom line of information.
So if you wanted to see the bottom line from DISKPART we can access that within the $LISTDISK object we created before
$LISTDISK[-1]
And then to access these individual members, we can produce deeper negative numbers:
What we need now is a way to access the data on each line. We could use some funky regular expressions, but we can also leverage some basic Substring() methods to pull out what we need. For each line, we can access the disk by selecting what appears to be the seventh character in the line (maybe some extra space?). To grab the information from the last line, we type:
$DiskID=$LISTDISK[-1].substring(7,5)
We of course should trim off any remaining white spaces after the output:
$DiskID=$LISTDISK[-1].substring(7,5).trim()
By using this same technique, we can grab the size of the actual media. It starts a little later down the same line. We’ll grab the number and GB (because in some cases, the output will be in KB or MB).
$SIZE=$LISTDISK[-1].substring(25,9)
In this case, I want to concatenate the numbers and spaces. A simple replace will meet this need:
$SIZE=$LISTDISK[-1].substring(25,9).replace(“ “,””)
What we need to do next is grab the disk type and the drive letter of the primary partition. Why the default letter? We’re going to design this so that all the information (including the drive letter that is assigned later) is available to use to send the output for XCOPY or Robocopy.
So we can take the information that we’ve obtained as an example and build a small DiskPart script to query details of that particular individual disk. The process will be similar to how we obtained the size and drive letters:
- Build a text file with the commands for DiskPart.
- Run DiskPart with the provided script, and capture the output.
- Parse the output and get the goodies we need.
First…to build the script for DiskPart to select a particular disk and obtain its details:
NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "DETAIL DISK"
$DETAIL=(DISKPART /S DETAIL.TXT)
Now we can use a similar process to parse out the data of the disk details:
First identify which line contains the Type: information. Yes. I sat there counting the lines on my screen to figure this out. (Does anybody have something to wipe off my fingerprints?)
$TYPE=$DETAIL[10].substring(9).trim()
Drilling down further, I find the drive letter for the first partition:
$DRIVELETTER=$DETAIL[-1].substring(15,1)
Now for fun, we’re going to grab some more specific details. The model of the drive also happens to be available and could be nice for output purposes:
$MODEL=$DETAIL[8]
Cool! With a little parsing we can grab the data we need and even build a simple DiskPart script with it.
But wait! How do we actually know the size? How do we go through and organize this into something more? Will Sean break into a song?
These answers and more in tomorrow’s episode of “Hey, Scripting Guy!” as we visit DiskPart and Windows PowerShell again in Part 3.
I invite you to follow us on Twitter and Facebook. If you have any questions, send email to Ed at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Sean Kearney (filling in for our good friend Ed Wilson),
Honorary Scripting Guy, Windows PowerShell MVP
…and good personal friend of the BATCHman