Automate Bootable USB creation with Powershell–Part 4

So we now have a pile of bootable USB keys.  Woohoo!

Now what we need to do is get ROBOCOPY to transfer data to them.   Automating THAT should be quite easy.   For that we have some very simple requirements.

  • All Data is in a folder called “C:\MDTImage\Content”
  • We are going to dump the data to all blank USB drives that fall into the same parameters as before (larger than 8GB, smaller than 64GB)

For this we COULD play with DISKPART some more, pull up the DETAIL on each drive and match the VOLUMES somehow, or I could cheat.

You see the keys we are going to use fit two key criteria.  They are USB and have been VERY recently formatted (like about 4 minutes) ago.  So they should have a very high free space count.   For this task we can leverage WMI and simply ask the computer the following question.

“Oh Great and Mighty Deep Thought!  Please show us all USB Drives with only One partition! We need to see the ones where the free space is over 99%, the drive is larger than 8gb and smaller than 64gb! And Please…. No.  Don’t tell us it will take a Billion Years in a computer called the Earth!”

Well had this been any OTHER giant computer, it might have.  But we can leverage a script similar to the first by accessing the “DETAIL” of each removable USB disk to find it’s correct Volume Letter.

But if I go into DISKPART and pull up the DETAIL DISK on a recently formatted drive I can see what I need is there already

image

Since we are already pulling information from DETAIL DISK, we can modify the original script and have it access the drive Letter in the final line and incorporate it into the original script.

In our original script (in part 1) we parsed DETAIL DISK with the following lines.

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

Since we are still accessing the output from $detail, we can add in one more PowerShell variable.  Specifically we want the Last line (which contains the volume information we are looking for) and a VERY specific element, the Driver letter.

$DriveLetter=$detail[-1].substring(15,1)

And we can just modify our [pscustomobject] to send that property back as an additional piece of info.

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

Now armed with a more improved script we can ask Windows PowerShell to talk to his friend DISKPART to get the Drive Letter for the Single Volume on all Removable USB Drives larger than 8GB and smaller than 64GB.

$TYPE=’USB’
$MIN=8GB
$MAX=64GB
$letters=(./QUERYDISKPARTV2.PS1 | Where { $_.Type –eq $Type –and $_.Disksize –gt $Min –and $_.Disksize –lt $Max } | SELECT-Object DriveLetter)

Now armed with this information we can have Robocopy do the rest of the work for us.

$Source=”C:\MDTImage\Content”

$letters { FOREACH { $Destination=$_.DriveLetter+”`:”; START-PROCESS ROBOCOPY.EXE –ArgumentList “$Source $Destination /E /S”} }

So now if we tie all these pieces together we could build some kinda of cool crazy automatic USB key creator for MDT that does NOT involve showing somebody the inner workings of DISKPART and ROBOCOPY.

We can turn it into a “Click Here” solution.

Kinda cool eh?

Remember, the Power of Shell is in YOU

Sean
The Energized Tech

2 Comments

  1. I keep getting error:
    PS H:\> C:\USB_Boot\QueryDiskpartv2.ps1
    Unexpected token 'and' in expression or statement.
    At C:\USB_Boot\QueryDiskpartv2.ps1:39 char:76
    + .\QueryDiskpartv2.ps1 | where { $_.Type –eq $Type –and $_.Size –gt $Min and <<<< $Size –lt $Max } + CategoryInfo : ParserError: (and:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken _________________________________________________ Here is the script I copied from this site: new-item -Name listdisk.txt -Itemtype file -force | out-null add-content -path listdisk.txt “list disk” $listdisk=(diskpart /s listdisk.txt) $totaldisk=$listdisk.count-9 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) $Model=$detail[8] $type=$detail[10].substring(9) $size=$listdisk[8+$d].substring(25,9).replace(” “,”") $length=$size.length $multiplier=$size.substring($length-2,2) $intsize=$size.substring(0,$length-2) switch($multiplier) { KB { $mult=1KB } MB { $mult=1MB } GB { $mult=1GB } } $disktotal=([convert]::ToInt16($intsize,10))*$mult [pscustomobject]@{DiskNum=$d;Model=$model;Type=$type;DiskSize=$disktotal} } .\QueryDiskpartv2.ps1 | where { $_.Type –eq ‘USB’ } get-wmiobject -query “SELECT * from win32_diskdrive where Interfacetype = ‘USB’” | Select-object Model,InterfaceType,Size $TYPE=’USB’ $MIN=8GB $MAX=64GB .\QueryDiskpartv2.ps1 | where { $_.Type –eq $Type –and $_.Size –gt $Min and $Size –lt $Max } SELECT DISK 1 CLEAN CREATE PARTITION PRIMARY FORMAT FS=FAT32 QUICK ASSIGN ACTIVE $TYPE=’USB’ $MIN=8GB $MAX=64GB $DRIVELIST=(.\QueryDiskpartv2.ps1 | where { $_.Type –eq $Type –and $_.Size –gt $Min and $Size –lt $Max }) NEW-ITEM -Path bootemup.txt -ItemType file -force | OUT-NULL $DRIVELIST | FOREACH { $DISKNUM=$_.DiskNum 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” } $DriveLetter=$detail[-1].substring(15,1) $TYPE=’USB’ $MIN=8GB $MAX=64GB $letters=(./QUERYDISKPARTV2.PS1 | Where { $_.Type –eq $Type –and $_.Disksize –gt $Min –and $_.Disksize –lt $Max } | SELECT-Object DriveLetter) $Source=”Z:\PE_Boot_Only_x64” $letters { FOREACH { $Destination=$_.DriveLetter+”`:”; START-PROCESS ROBOCOPY.EXE –ArgumentList “$Source $Destination /E /S”} } $Source=”Z:\PE_Boot_Only_x64” $letters { FOREACH { $Destination=$_.DriveLetter+”`:”; START-PROCESS ROBOCOPY.EXE –ArgumentList “$Source $Destination /E /S”} } ______________________________________________________________________ If I can get help to also map the drive to the location with a selection letting me choose between the folders \\houmgmt49\bootmedia$\PE_Boot_Only_x86 or \\houmgmt49\bootmedia$\PE_Boot_Only_x64 to be mapped. I am a noob and want to automate the USB boot media process.

    • Comments aren't the best place for Q&A. Consider posting in our forums, linking to this post if it's relevant, and attaching your script as a TXT file. From the error message, it looks like you may have someplace used "and" instead of "-and."