Automating DiskPart with Windows PowerShell: Part 5

Automating DiskPart with Windows PowerShell: Part 5

  • Comments 7
  • Likes

Summary: Use Windows PowerShell to build scripts to automate DiskPart.

Hey, Scripting Guy! Question Hey, Scripting Guy! Can we build a DISKPART script to automatically format USB drives as bootable?

—SH

Hey, Scripting Guy! Answer Hello SH,

Honorary Scripting Guy, Sean Kearney, here. I’m filling in for our good friend, Ed Wilson. It’s Friday and Ed has had a long week (and a lot of feedback, I suspect, from my bad puns). So I suspect he’ll be all “tied up” with email.

We have pulled together a really cool function called Get-DiskPartInfo, which automates the use of DiskPart to a point that’s it’s information is now an object that we can consume with Windows PowerShell.

Note This is the final part in a series. If you are behind, please read:

Let’s look at a basic DiskPart script to make a USB key bootable again:

SELECT DISK 2
CLEAN
CREATE PARTITION PRIMARY
FORMAT FS=NTFS QUICK
ASSIGN
ACTIVE

With our current advanced function, we can already identify USB flash drives and hard drives. Because we can isolate them down to size, we can make a fairly educated guess about devices that are removable USB keys.

Educated guess? Well, the one problem that I haven’t been able to figure out an answer for is how to separate a hard drive USB device from a USB flash drive. That information is not presented in DiskPart.

But I can suggest that I think most of the USB flash drives I have are going to be under a certain size…let’s say 32 GB. And for my purposes (I would like to extend this to Microsoft Deployment Toolkit (MDT) 2012), I can probably suggest that they won’t be smaller than a certain size either—say 8 GB.

Now let’s start building a new advanced function called Initialize-USBBoot. What we are going to do is build the script that is needed to make the keys bootable in DiskPart:

Function INITIALIZE-USBBOOT()
{

[cmdletbinding()]
Param()

First, we’re going to identify the parameters for our bootable devices: USB drives between 7.5 GB and 65 GB:

$TYPE=’USB’
$MIN=7GB
$MAX=65GB

And now that we have a cool new way to parse DiskPart, this all gets so much easier:

$DRIVELIST=(GET-DISKPARTINFO | WHERE { $_.Type –eq $TYPE –and $_.DiskSize -lt $MAX and $_.DiskSize –gt $MIN })

This will return all drives that are seen by DiskPart, including their identified DiskID numbers, which we can use to build a single script for DiskPart.

Again, I’m going with a “simple is best” approach when I build the content. First, I’ll create the file for the DiskPart script:

NEW-ITEM -Path bootemup.txt -ItemType file -force | OUT-NULL

Then I step through every drive in the list and obtain its DiskID from DiskPart:

$DRIVELIST | FOREACH {
$DISKNUM=$_.DISKNUM

Now I’ll build the script. Because it’s simply a serial set of commands, we can build one script to do all the work:

ADD-CONTENT -Path bootemup.txt -Value "SELECT DISK $DiskNum"
ADD-CONTENT -Path bootemup.txt -Value "CLEAN"
ADD-CONTENT -Path bootemup.txt -Value "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path bootemup.txt -Value "FORMAT FS=FAT32 QUICK"
ADD-CONTENT -Path bootemup.txt -Value "ASSIGN"
ADD-CONTENT -Path bootemup.txt -value "ACTIVE"

}

}

Now with this in place, I can run the following script:

INITIALIZE-USBBOOT
DISKPART /S .\BOOTEMUP.TXT

Now we can plug-in a series of USB keys that fit those parameters and wipe them clean for booting!

How does MDT 2012 fit into all of this?

Let’s assume that you have a folder called C:\DeploymentContent, and you need to be able to have a simple solution for technicians to build their keys—a solution that means consistency in the process.

In Windows PowerShell, we can launch Robocopy.exe like any other application, but also pass parameters to it. Because our new Get-DiskPartInfo cmdlet will also return the drive letter for those USB keys, we can identify our USB flash keys with those same parameters, and pass the results to Robocopy.exe. Here’s a sample script that could meet this need:

$TYPE=’USB’
$MIN=7GB
$MAX=65GB

$DRIVELIST=(GET-DISKPARTINFO | WHERE { $_.Type –eq $TYPE –and $_.DiskSize -lt $MAX -and $_.DiskSize –gt $MIN })

$DRIVELIST | FOREACH {

$Source=”C:\DeploymentContent\”
$Destination=$_.DriveLetter

ROBOCOPY $Source $Destination /E

}

There you have it! A bit of work to play with, but now we have an almost single-click solution to build those deployment keys. You could even leverage this to easily erase media keys and deploy documentation or client media.

By the way, if you don’t feel like typing, this entire solution is uploaded as a module on the Script Center Repository: Automate Creation of Bootable USB Keys with PowerShell.

And remember the choice is yours, as is the power…with Windows PowerShell!

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
  • @Sean - excellent example.

    WMI cannot easily do this.  It leverage capabilities of older utilities that have not yet been converted to PowerShell.

  • Based on previous entries in this series, you might be expecting some WMI code from me right about now.  Nope!

    This entry shows how I like to leverage command-line programs in PowerShell:  Call them and forget them (after checking $LASTEXITCODE).  If you need to parse the program's text output, that's where I immediately start looking for a cmdlet or .NET approach instead.  When parsing the output is not required, though, keep using the old programs wherever it makes sense.  For example, "net use" is still the easiest way to map a drive, even in PowerShell.

  • I agree with David on this one mostly.

    PowerShell V3 is easier to map drives now.

    new-psdrive X FileSystem \\sbs01\c$ -persist -Credential dom/user01

    Can't be any easier.

  • @david and @jrv

    The reason I opt away from .NET solutions sometimes (Or more drove this solution towards parsing) is it enables regular ITPros who are not heavily versed in .NET to build solutions.  

    Where I love PowerShell (and always will) is how it offers multiple options for the same answer.  

    For me?  It's whatever answer worked for me in the short term.  You can ALWAYS find a better tool down the road :)

    Sean

  • Very useful.  Nicely done, as usual.

  • Automating DiskPart with command prompt
    http://answers-free.blogspot.in/2014/02/how-to-automate-windows-diskpart.html

  • DiskPart.exe - Powershell Parser for Windows Server 2008 R2
    https://gallery.technet.microsoft.com/DiskPartexe-Powershell-0f7a1bab