![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| 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. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | 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 Specs![]() |
| | #2 (permalink) |
| | 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] It's free and I think it may well do what you're trying to achieve. |
My System Specs![]() |
![]() |
| 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 | |||