Summary: Use Windows PowerShell to build scripts to automate DiskPart.
Hey, Scripting Guy! Can we build a DISKPART script to automatically format USB drives as bootable?
—SH
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:
- Automating DiskPart with Windows PowerShell: Part 1
- Automating DiskPart with Windows PowerShell: Part 2
- Automating DiskPart with Windows PowerShell: Part 3
- Automating DiskPart with Windows PowerShell: Part 4
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