Tags


So I sat down the other day and decided I wanted to be able to do something really cool.

I wanted to be able to automatically create a bootable USB key, regardless of where it was in the computer.

Creating a Bootable USB key is actually not difficult in Windows.   It’s a well documented process that follows the lines of.

  • Insert USB Flash drive into a port
  • Launch DISKPART as Administrator
  • Execute some Commands in DISKPART
  • Use Robocopy to mirror your boot Media or Bootable content to the key.

Now in Truth I could write most all of this as a script I could launch in DISKPART with the /s parameter, then perhaps run this as a batch file.

But I wanted a far more dynamic solution.   I wanted to be able to plug in as many keys as I wanted on ANY computer and just have all the work done for me.

So this is very achievable by using DISKPART to pull up the data and have Windows PowerShell parse the output for the information we need.

Within DISKPART the first thing we are going to run is the Command LIST DISK to show us which disks are attached to the system.   The output will look somewhat similar to this.

image

Then within the application we can SELECT a particular Disk and access it’s DETAILS by doing something similar to this.

SELECT DISK 2

DETAIL DISK

This will give us the following output as an example

image

Now to automate any of these operations for DISKPART I would normally just create a TEXT file with the Commands I wish to run and execute something like

DISKPART /s thingstodo.txt

The process is easy to work with but the challenge is building a DISKPART script to pick the correct key every time.   You’re dealing with scenarios where it might NOT be DISK 2 for the USB, or perhaps there are removable hard disks.   There’s even a chance that you can’t USE some of the keys for a bootable deployment (the Operating system usually needs an 8gb key, bigger MDT deployments may cross into a 16gb key)

So Ideally what I would like to do (and will achieve by the end of this series) is have PowerShell Parse the output from DISKPART and BUILD the scripts I need for the application.   I will have Powershell identify the Disk number and produce an object return the details about the attached Disks (whether they are physical or removable)

So first I am going to have PowerShell build a DISKPART script to execute LIST DISK for me.   Why not have the file exist already?  Let’s go back to “Dynamic”.  I want the SCRIPT to be the environment and build whatever parts it needs.

new-item -Name listdisk.txt -Itemtype file -force | out-null
add-content -path listdisk.txt “list disk”

I will then execute DISKPART inside PowerShell and capture the output as an Object.

$listdisk=(diskpart /s listdisk.txt)

Now the output of this command is consistent in not only the format, but also in how much information it returns relevant to the physical disk count.  So one of the things I figured out was the number of lines in the output was EXACTLY 9 longer than the number of disks.   So with a little math I can have Powershell tell me how many disks DISKPART sees.

$totaldisk=$listdisk.count-9

Now for the fun part, we can build some simple DISKPART scripts to pull up the DETAIL on each individual DISK, including data on the partitions and Parse that out.

for ($d=0;$d -le $totaldisk;$d++)
{
new-item -Name detail.txt -ItemType file -force | out-null
add-content -Path detail.txt “select disk $d”
add-content -Path detail.txt “detail disk”

$Detail=(diskpart /s detail.txt)

Now from the output from the DETAIL DISK I want to pull out two key pieces of information, the Model of whatever disk we are examining and whether it is a USB key or not.  I COULD play with Regular Expressions but honestly this is simple enough to pull out with a Substring method and grabbing the output directly since the information is consistently in the same location.

$Model=$detail[8]
$type=$detail[10].substring(9)

Now the next challenge is to determine the SIZE of the removable key.   For that I can parse the data I already stored in $LISTDISK as I pulled it from LIST DISK which shows the size of each key on each row.

$size=$listdisk[8+$d].substring(25,9).replace(” “,””)

$length=$size.length
$multiplier=$size.substring($length-2,2)
$intsize=$size.substring(0,$length-2)

However let’s re-examine the output from LIST DISK

image

In some cases we will find the size of the disk is in Gigabytes, and sometimes reported in Megabytes.  Other times it’s even in Kilobytes!  So we’ll need a way to “Switch” those numbers with real values.   So the answer is simple.   Parse the numbers on the left, parse the MB/GB/KB on the right and figure out the multiplier it should be.   This sounds like a job …. for POWERSHELL!

We can use the Switch statement to easily swap out those letters for real values.   PowerShell has some built in shortcuts for things like Memory sizing, so we’ll leverage those.

switch($multiplier)
    {
        KB { $mult=1KB }
        MB { $mult=1MB }
        GB { $mult=1GB }
    }

Now we can do a little simple math to figure out the actual size of the Removable Key

$disktotal=([convert]::ToInt16($intsize,10))*$mult

Now we can just return this data as an Object with PowerShell’s new feature in Version 3 called “[pscustomobject]

[pscustomobject]@{DiskNum=$d;Model=$model;Type=$type;DiskSize=$disktotal}

}

We now run just run a script that (although this is slow) will produce the data from DISKPART as an Object like the following.

image

Now if you’ve EVER had to create a Bootable USB key, I’ll bet you can see where I am going with this next… Automatically creating the Scripts for Diskpart!

Next time.  We’ll look at that next time.

Remember, the Power of Shell is in You

Sean
The Energized Tech

Advertisements