Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell to automate formatting and copying data to USB drives.
Microsoft Scripting Guy, Ed Wilson, is here. Today we leave the mystery writers conference in Nashville, Tennessee and head to northern Kentucky. I will be teaching a Windows PowerShell workshop to a group of Microsoft premier customers, get to see my good friend Robert from California, speak to the first ever Cincinnati Windows PowerShell Users Group, and have dinner with some old friends. The Scripting Wife will be going with me to the Windows PowerShell Users Group meeting, enchanting local merchants, and be out visiting friends and family.
In preparation for the Windows PowerShell class, I agreed to copy a bunch of files to a bunch of USB drives. I really wanted USB 3.0 drives, but they were not available in the size and quantity that I needed. Oh well, there is always something that provides an excuse for a quick Windows PowerShell script! Yes, Windows PowerShell to the rescue!
Using PowerShell to format a drive
Like many of the things in Windows PowerShell 3.0 and Windows 8, the capabilities exist in previous versions of Windows, and they were doable even in Windows PowerShell 1.0. The difference is the ease of accomplishing the task. My Windows PowerShell story today begins with two commands. The first is the Format-Volume function (yes, I know the specific verb is a bit pushing the boundaries of use—I mean Format-List, Format-Table, Format-Wide do not necessary lead to Format-Volume, do they? Oh well. From a discoverability standpoint, the name makes sense unless you spend a lot of time searching the Help for Set-Volume, New-Volume, or even Initialize-Volume before you finally give up and use Get-Command –noun *volume*, which is how I found the command. By the way, it is not technically a cmdlet. Get-Command tells me it is a function, and it resides in the Storage module.
Anyway, I tried to use the Format-Volume function to format one of the portable USB drives, and the first thing that happened was that a prompt asked if I wished to continue. OK, so they implemented ShouldProcess. That is probably a good thing. It took a bit of playing around, but finally I discovered that to suppress the prompt (a definite requirement if I have any hopes of automating the process), I feed a value to the confirm parameter.
Note This is not included in the documentation, but it makes sense. The length of the NewFileSystemLabel property is limited to 11 characters. You can type more, and the command does not generate an error, but when you run the command, the following warning appears in the output.
PS C:\> Format-Volume -DriveLetter e -NewFileSystemLabel PowerShellROCKS -FileSystem
exfat -Confirm:$false
WARNING: The volume label is not valid.
DriveLetter FileSystemL FileSystem DriveType HealthStatu SizeRemaini Size
abel s ng
----------- ----------- ---------- --------- ----------- ----------- ----
E exFAT Removable Healthy 28.89 GB 28.89 GB
Even though the warning appears, the command still completes and formats the drive. The label reverts the default label for the type of drive. In this example, the label becomes Removable Disk.
The command line is shown here.
Format-Volume -DriveLetter E -NewFileSystemLabel PowerShell -FileSystem exfat -Confirm:$false
I decided that I want to use Robocopy to perform the actual copy operation. It is built-in to Windows 8, and it is very fast. The command line I use is simple: the source, the destination and an /S switch to copy subdirectories. I use the command line shown here.
robocopy $source $destination /S
Playing system sounds
The nice thing is that Robocopy informs me the progress of each copy operation. When the process completes, I play a system sound to let me know that I can get the next drive and run the script again. Here is the code that plays a system sound.
[media.SystemSounds]::("Hand").play()
I have no idea of what the system sounds sound like, so I wrote a quick bit of code to play the system sounds to provide me with an audition. Here is the code that I used to do that.
Foreach($sound in ([media.systemsounds] | gm -static -MemberType property))
{
$sound.Name
[media.SystemSounds]::($sound.name).play()
start-sleep -s 1
}
FormatDriveCopyFiles.ps1
#requires -version 3.0
ipmo storage
$source = "C:\data\PowerShellWOrkshop\"
$destination = "E:"
Format-Volume -DriveLetter E -NewFileSystemLabel PowerShell -FileSystem exfat -Confirm:$false
robocopy $source $destination /S
[media.SystemSounds]::("Hand").play()
When I run the script, the output from the following image displays in the Windows PowerShell ISE.
That is about it for today. I think there is an outlet mall the Scripting Wife wants to take me to before we check-in to the next hotel. Join me tomorrow for more Windows PowerShell cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy