Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > VB Script

Vista - Static USB drive letters in XP (working script)

Reply
 
Old 08-15-2008   #1 (permalink)
Steve


 
 

Static USB drive letters in XP (working script)

This is posted to both the vbscript and wsh groups (hope that's OK).
Some people (like me) were looking for ways to assign predictable drive
letters to USB drives (for backups, etc).

I know there is at least one good utility out there for doing what this does
but I have not found a free one (not for business use), and some people I
know are REALLY CHEAP (those people frustrate me).
This script (example: save it as StaticUSBforXP.vbs) listens for device
changes (related to drives) and when a specific drive is discovered (based
on it's label) it assigns it a specific drive letter. This one checks for 2
different labels and assigns a different letter based on the label.
This is a brute force workaround to XP not having a Win32_Volume class, as a
result the floppy drive gets accessed a few times each time the drives are
added/removed. This is the first working version and should be optimized
and cleaned up (with some error checking coded perhaps). I left it as-is
with the debug echo's and commented lines.
You can run this via the scheduled tasks (use cscript) and set it to run at
startup to simulate running it like a service.
Normally when USB drives are attached they are assigned the next available
letter (Usually F or the last letter used). If you manually change the
assigned drive letter to say X and then assign the same letter to a second
drive the first one reverts to the next available letter (not X) the next
time it is attached so you cannot assign X to more than one drive (this is a
limitation of the registry and letter assignment logic). This overcomes
that limitation.
This is based on some code I found on the web plus my own efforts with the
WMI code creator.
This uses very little memory and CPU resources and can be terminated
cleanly.

Note: the sample script in the MS script repository for doing the same thing
uses a different event to listen for and causes the floppy drive to 'chug'
(activate) on a regular cycle even after the script is terminated, which I
found unacceptable (extra wear, annoying). This one will do it only when it
is running and an event triggers it.

Uses:
-if using ntbackup and USB drives you can now assign a pool of drives the
same drive letters (combined with BLAT you'd have a very workable USB backup
solution for free)
-ensure specific drives get assigned a specific letter

Hope others find this useful. I may not check back for a few months (very
busy) so if anything needs fixing, well, you know the drill.


[start of code]
' Description:
' (This is meant for XP, not 2003 and above, which have the win32_Volume
class, this
' is a brute force method.)
' Listens for a specific drive by drive label/name (ie: "MyThumbDrive" or
"SanDisk")
' Then assigns it a specified drive letter (X: for example)
' To run at boot time in background add to Scheduled Tasks accordingly (use
cscript).
' Issues:
' only works for a single drive at a time (for now)
' floppy drive activates for each device change event (up to 3 per cycle)
' does not check for drives already attached (just new arrivals; unplug and
reattach as a workaround)
' Warnings:
' DO NOT ATTACH MORE THAN ONE DRIVE WITH THE TARGET LABEL AT A TIME!
' example: do not attach "MyThumbDrive" and "SanDisk" at the same time, I
cannot predict what will happen
' (probably a loop, crash or stack overflow)
' Notes:
' This can/should be cleaned up for readability, efficiency and error
checks
' Suggestion: move drive name list and letters to a text config file and
read it in at run time

Option Explicit

dim strComputer, objWMIService, objEvents, objReceivedEvent, colItems,
objItem
dim objShell, objfs, objDriveCollection, strTemp, WshSysEnv, strSystemRoot
dim intDriveLetter, objDrive, strCMD, objFile, strVolume
dim targetLetter

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 1")

Wscript.Echo "Waiting for events ..."
Do While(True)
Set objReceivedEvent = objEvents.NextEvent

'report an event
Wscript.Echo "Win32_DeviceChangeEvent event has occurred."

Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_LogicalDisk WHERE VolumeName='Sandisk' OR
VolumeName='RSG_Backup1000'",,48)

' try not to run the letter change if it is already correct
For Each objItem in colItems
if ((objitem.volumename = "RSG_Backup1000" AND objitem.name <> "W:")
or _
(objitem.volumename = "SANDISK" AND objitem.name <> "V:")) then
Wscript.Echo objItem.Name & objItem.VolumeName & " will be changed."

'todo: the code below should be wrapped up so it runs once (not if the
letters are correct)
'-----------
Set objShell = WScript.CreateObject("WScript.Shell")
Set objfs = CreateObject("Scripting.FileSystemObject")
Set objDriveCollection = objfs.Drives

Set WshSysEnv = objShell.Environment("PROCESS")
strTemp = WshSysEnv("Temp")
strSystemRoot = WshSysEnv("SystemRoot")

intDriveLetter=86 ' ascii for V
if objItem.VolumeName = "RSG_Backup1000" then intDriveLetter=87 ' ascii for
w

For Each objDrive in objDriveCollection

if objDrive = objItem.Name then
' discover volume ID
strCMD = strSystemroot & "\system32\cmd /c mountvol.exe " &
objDrive.DriveLetter & ": /L > " & strTemp & "\volume.txt"
'wscript.echo strCMD
objshell.run strCMD,0,true
Set objFile = objfs.OpenTextFile(strTemp & "\volume.txt", 1)
strVolume = ltrim(objFile.ReadLine)
objFile.close

' unmount drive
strCMD = "mountvol.exe " & objDrive.DriveLetter & ": /d"
'wscript.echo strCMD
objShell.Run strCMD,0,true

' Remount drive
strCMD = "mountvol.exe " & chr(intDriveLetter) & ": " & strVolume
'wscript.echo strCMD
objShell.Run strCMD,0,true
end if
next

'-----------
End if
Next

Loop


[end of code]



My System SpecsSystem Spec
Old 08-15-2008   #2 (permalink)
Pegasus \(MVP\)


 
 

Re: Static USB drive letters in XP (working script)


"Steve" <sdixon@xxxxxx> wrote in message
news:XsWdnXYctI3eQjjVnZ2dnUVZ_qfinZ2d@xxxxxx
Quote:

> This is posted to both the vbscript and wsh groups (hope that's OK).
> Some people (like me) were looking for ways to assign predictable drive
> letters to USB drives (for backups, etc).
>
> I know there is at least one good utility out there for doing what this
> does but I have not found a free one (not for business use), and some
> people I know are REALLY CHEAP (those people frustrate me).
> This script (example: save it as StaticUSBforXP.vbs) listens for device
> changes (related to drives) and when a specific drive is discovered (based
> on it's label) it assigns it a specific drive letter. This one checks for
> 2 different labels and assigns a different letter based on the label.
> This is a brute force workaround to XP not having a Win32_Volume class, as
> a result the floppy drive gets accessed a few times each time the drives
> are added/removed. This is the first working version and should be
> optimized and cleaned up (with some error checking coded perhaps). I left
> it as-is with the debug echo's and commented lines.
> You can run this via the scheduled tasks (use cscript) and set it to run
> at startup to simulate running it like a service.
> Normally when USB drives are attached they are assigned the next available
> letter (Usually F or the last letter used). If you manually change the
> assigned drive letter to say X and then assign the same letter to a second
> drive the first one reverts to the next available letter (not X) the next
> time it is attached so you cannot assign X to more than one drive (this is
> a limitation of the registry and letter assignment logic). This overcomes
> that limitation.
> This is based on some code I found on the web plus my own efforts with the
> WMI code creator.
> This uses very little memory and CPU resources and can be terminated
> cleanly.
>
> Note: the sample script in the MS script repository for doing the same
> thing uses a different event to listen for and causes the floppy drive to
> 'chug' (activate) on a regular cycle even after the script is terminated,
> which I found unacceptable (extra wear, annoying). This one will do it
> only when it is running and an event triggers it.
>
> Uses:
> -if using ntbackup and USB drives you can now assign a pool of drives the
> same drive letters (combined with BLAT you'd have a very workable USB
> backup solution for free)
> -ensure specific drives get assigned a specific letter
>
> Hope others find this useful. I may not check back for a few months (very
> busy) so if anything needs fixing, well, you know the drill.
>
>
> [start of code]
> ' Description:
> ' (This is meant for XP, not 2003 and above, which have the win32_Volume
> class, this
> ' is a brute force method.)
> ' Listens for a specific drive by drive label/name (ie: "MyThumbDrive" or
> "SanDisk")
> ' Then assigns it a specified drive letter (X: for example)
> ' To run at boot time in background add to Scheduled Tasks accordingly
> (use cscript).
> ' Issues:
> ' only works for a single drive at a time (for now)
> ' floppy drive activates for each device change event (up to 3 per cycle)
> ' does not check for drives already attached (just new arrivals; unplug
> and reattach as a workaround)
> ' Warnings:
> ' DO NOT ATTACH MORE THAN ONE DRIVE WITH THE TARGET LABEL AT A TIME!
> ' example: do not attach "MyThumbDrive" and "SanDisk" at the same time,
> I cannot predict what will happen
> ' (probably a loop, crash or stack overflow)
> ' Notes:
> ' This can/should be cleaned up for readability, efficiency and error
> checks
> ' Suggestion: move drive name list and letters to a text config file and
> read it in at run time
>
> Option Explicit
>
> dim strComputer, objWMIService, objEvents, objReceivedEvent, colItems,
> objItem
> dim objShell, objfs, objDriveCollection, strTemp, WshSysEnv, strSystemRoot
> dim intDriveLetter, objDrive, strCMD, objFile, strVolume
> dim targetLetter
>
> strComputer = "."
>
> Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
> Set objEvents = objWMIService.ExecNotificationQuery _
> ("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 1")
>
> Wscript.Echo "Waiting for events ..."
> Do While(True)
> Set objReceivedEvent = objEvents.NextEvent
>
> 'report an event
> Wscript.Echo "Win32_DeviceChangeEvent event has occurred."
>
> Set colItems = objWMIService.ExecQuery( _
> "SELECT * FROM Win32_LogicalDisk WHERE VolumeName='Sandisk' OR
> VolumeName='RSG_Backup1000'",,48)
>
> ' try not to run the letter change if it is already correct
> For Each objItem in colItems
> if ((objitem.volumename = "RSG_Backup1000" AND objitem.name <> "W:")
> or _
> (objitem.volumename = "SANDISK" AND objitem.name <> "V:")) then
> Wscript.Echo objItem.Name & objItem.VolumeName & " will be
> changed."
>
> 'todo: the code below should be wrapped up so it runs once (not if the
> letters are correct)
> '-----------
> Set objShell = WScript.CreateObject("WScript.Shell")
> Set objfs = CreateObject("Scripting.FileSystemObject")
> Set objDriveCollection = objfs.Drives
>
> Set WshSysEnv = objShell.Environment("PROCESS")
> strTemp = WshSysEnv("Temp")
> strSystemRoot = WshSysEnv("SystemRoot")
>
> intDriveLetter=86 ' ascii for V
> if objItem.VolumeName = "RSG_Backup1000" then intDriveLetter=87 ' ascii
> for w
>
> For Each objDrive in objDriveCollection
>
> if objDrive = objItem.Name then
> ' discover volume ID
> strCMD = strSystemroot & "\system32\cmd /c mountvol.exe " &
> objDrive.DriveLetter & ": /L > " & strTemp & "\volume.txt"
> 'wscript.echo strCMD
> objshell.run strCMD,0,true
> Set objFile = objfs.OpenTextFile(strTemp & "\volume.txt", 1)
> strVolume = ltrim(objFile.ReadLine)
> objFile.close
>
> ' unmount drive
> strCMD = "mountvol.exe " & objDrive.DriveLetter & ": /d"
> 'wscript.echo strCMD
> objShell.Run strCMD,0,true
>
> ' Remount drive
> strCMD = "mountvol.exe " & chr(intDriveLetter) & ": " & strVolume
> 'wscript.echo strCMD
> objShell.Run strCMD,0,true
> end if
> next
>
> '-----------
> End if
> Next
>
> Loop
>
>
> [end of code]
Have you had a look at USBDLM (http://www.uwe-sieber.de/usbdlm_e.html)?
It's free and I think it may well do what you're trying to achieve.


My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Drive Letters Vista General
Drive letters Vista General
USB drive letters and mapped drive letter issues Vista hardware & devices
USB drive letters and mapped drive letter issues Vista hardware & devices
Mapped drive letters get re used when plugging in USB Thumb Drive Vista networking & sharing


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46