Automating DiskPart with Windows PowerShell: Part 1

Automating DiskPart with Windows PowerShell: Part 1

  • Comments 11
  • Likes

Summary: Honorary Scripting Guy, Sean Kearney, talks about using Windows Powershell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! I know I can create a bootable USB key by using DiskPart, but is there any way to have it automated so the computer does the work for me?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson, who’s building some giant contraption in his backyard to hold his giant collection of bow ties. So he’s a bit “tied up.”

So the answer is absolutely, “Yes! Yes! Yes!” You can automate the creation of bootable memory keys. Having this ability is great if you’re using utilities like MDT 2012, and you need bootable media on the fly.

So I sat down and poked through my shiny new Surface Pro to dig for cmdlets to automate creating bootable partitions on USB.  There are so many new modules and cmdlets to choose from.

Then my jaw dropped. There were none (at least none that I could spy), and I wanted to fix that.

Creating a bootable USB key is pretty easy. Most of us could run this process with our hands behind our backs while singing a happy tune. The standard procedure for a bootable USB key is:

  1. Launch DiskPart as an Administrator.
  2. Use List Disk to find your USB key (or keys if you’re being efficient).
  3. Use Select Disk to choose your USB key.
  4. Clean (to wipe out the MBR and delete the partition entries).
  5. Run Create Partition Primary to create a new primary partition on the USB flash drive.
  6. Format FS=FAT32 Quick to lay down the file system as Fat32.
  7. Assign (to give our friend a drive letter).
  8. Active to make it bootable.

So if your USB key always came up as DISK 2, you might have a little text file called “bootme.txt” with the following commands:

  1. Select DISK 2.
  2. Clean.
  3. Create Partition Primary.
  4. Format FS=FAT32 Quick.
  5. Assign.
  6. Active.

You could happily run:

DISKPART /s .\bootme.txt

….and whoosh! All done.

But wouldn’t it be far nicer to have something a bit more dynamic with the ability to figure out most of the work for you? Then you actually could do this with a touch of your fingers!

The ironic thing about DiskPart is that it works great, but it doesn’t have a native way to export the information it has.

But I know of something that can help. Wait for it…

Starts with a “P”…

Has a cool theme song…

Yes! Of course! PowerShell can aid here! We can actually have Windows PowerShell create scripts for DiskPart and leverage the output of DiskPart to create newer scripts for it!

Sounds like magic doesn’t it? Nope. Just a feature of Windows PowerShell that has been used before to automate applications like HANDLE.exe from Sysinternals.

So our first challenge is to create a text file for DiskPart to literally “List the disks.”

We could cheat and simply type something in Notepad, but if we use a script (or better yet, build a function), the solution will be self-contained.

So first—oh mighty PowerShell—make me a text file. We could do something really fancy and elegant, but sometimes simplicity is best. Simple means easy to modify and easy to understand. Here we go:

NEW-ITEM –name listdisk.txt –itemtype file –force | OUT-NULL
ADD-CONTENT –path listdisk.txt “LIST DISK”

Now we can automate DiskPart with this new mini script. But we’ll want to capture the output:

$LISTDISK=(DISKPART /S LISTDISK.TXT)   

So what we’ve done here is capture all the output DiskPart was sending to the screen as a Windows PowerShell object. Now we can do all sorts of really neat stuff—like parse the data for what we want.

So the first thing we need to know from “LIST DISK” is, well, how many disks we’re looking at. Believe it or not, this is easier than you imagine. First off, the number of lines in the output is a built-in property:

$TOTALDISK=$LISTDISK.count

Now there are a lot of funky ways to figure this out. But honestly, all we have to know is how many of the lines in the output do not contain the information we want—the lines with the disk information. That number happens to be 9. (Yes, I smudged up my screen and counted 1….2…..3….ketchup stain.)

So we can use Windows PowerShell to calculate this:

$TOTALDISK=($LISTDISK.count)-9

But we have a ways to go. We need to find out the assigned number for the drive if it’s a USB flash drive…whether it’s pink or green.

But we’ll come back tomorrow and show more about how we can parse the information from DiskPart!

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

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • @Ed

    Try  this:

    $commands=@(

        'list disk',

        'select disk 0',

        'list partition'

    )

    $commands | diskpart

    $results = $commands | diskpart

  • @jrv

    Very cool! An excellent example of improving upon the original solution!

    Sean

  • I apologize if this winds up being a duplicate post.  I typed it out and submitted once before, and it's not showing up.

    It might not be very reliable to parse diskpart's text output as a way of reading the list of disks.  Different versions of diskpart (or different localizations) might format the output differently, causing headaches (essentially the whole reason PowerShell works with Objects instead of text).

    It looks like the WMI class Win32_DiskDrive might provide a cleaner alternative.  I've run the "list disk" command on a few different computers (just Windows 7 and 2008 R2 so far, so it probably needs more thorough testing), and the "Index" property of Win32_DiskDrive appears to match the disk number in diskpart's output.  If this is always the case, you also get the benefit of being able to filter based on the other properties of Win32_DiskDrive (InterfaceType and MediaType) to distinguished the removable USB drive from other types of disks.

  • @sean

    Driving DISKPART in a pipeline has been around for a decade or more.  It has been used in batch files and still works in PowerShell.

    The primary use of DISKPART is not to list disk information although it can be used this way.  It is useful for structuring or re-structuring existing and new disks.  With tools like MDT diskpart has become less used but I see that many still like to use it.  Ed's example with PowerShell shows how we can continue to use it with PowerShell.

    If you only want disk partition information WMI is probable easier and more PosHy but does not work well inpre-Vista systems.  

    One more tool and two ways to use it with PowerShell.

  • @Dave

    The reason for utilizing DiskPart and PowerShell was to mimick the solution for making a bootable USB with Diskpart.  But I absolutely love that this generating other ideas :)

    The intended use of this particular solution is more for a single O/S but can be adapted.  But you are correct in that there is always a chance the output might night be as consistent in some cases.   Here is where Regular expressions might come into play.

    @jrv

    Some techniques are not always obvious which is why I love doing these posts.  People like yourself pop in with some great ideas to share.

    Alone we cannot know all.  Sharing our knowledge and working together we can solve anything

    Sean

  • @Sean

    Yes - exploring many techniques is a good exercise which is why I am waiting t see your implementation of RegEx.  Everyone does it differently and I always learn.  This one does not have an obvious best solution.

  • @jrv

    No Regex this time but perhaps that in itself could be a cool blog post.  If you're interested in PowerShell and Regular Expressions search for posts by PowerShell MVP Tome Tanasovski who makes Regex as easy as a one liner

    Sean

  • @Sean - I can RegEx that but wanted to see how you would do it.  I had an idea you might have an easier way.  RegEx is the best and easiest way t 'objectify' the disk data from diskpart.  The reason I know about using th4 pipe into diskpart is because I did this back in PosH v1.  It was a good exercise for using PowerShell and RegEx

  • You need to clean your screen again.

    $LISTDISK=(DISKPART /S LISTDISK.TXT)

    $TOTALDISK=($LISTDISK.count)-9

    This will not give you the correct number of disks listed, the output is different when you run diskpart with a diskpart script. The command "List disk" and the blank line after it is not shown and thus the number of lines to discard is 2 less, and should be 7.

    $LISTDISK=(DISKPART /S LISTDISK.TXT)

    $TOTALDISK=($LISTDISK.count)-7

  • http://answers-free.blogspot.in/2014/02/how-to-automate-windows-diskpart.html

  • Step by step guide for disk automation
    http://answers-free.blogspot.in/2014/02/how-to-automate-windows-diskpart.html