Sign in to follow this  
Followers 0
willpd13

Help with USB problem

4 posts in this topic

Hi All,

I have a little bit of a problem in that we have a few laptops that need to be backed up to USB hard disks but the USB disks do not always pick up the same drive letter which is common enough but our laptops also have quite a few mapped network drives (Yes the users can't handle UNCs) and when the USB drive picks the same letter as a mapped network drive you can still access the network share but not the USB drive. The users are incapable of using disk management as they are too likely to break something vital or format their hard disk by accident (and no I do not have much faith in the users) so I have been trying to write a script that will find a USB hard disk that has been attached but is not accessable and rename the drive letter.

I have been trying to do this in VB as I have more experience of this (about 2 hours :whistle: ) however while I can get this to sort of work on my PC running windows Vista the laptops have windows XP and the W32.Volume class driveletter object is not writable in XP also this only seems to work if the drive picks a valid letter that is not already in use by a network share.

My code is below

strComputer = "."

strDrivenewletter = "Z:"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colDiskDrives = objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive where interfacetype='USB'")

For Each objDrive In colDiskDrives

'Wscript.Echo "Physical Disk: " & objDrive.Caption & " -- " & objDrive.DeviceID

strDeviceID = Replace(objDrive.DeviceID, "\", "\\")

Set colPartitions = objWMIService.ExecQuery _

("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & _

strDeviceID & """} WHERE AssocClass = " & _

"Win32_DiskDriveToDiskPartition")

For Each objPartition In colPartitions

'Wscript.Echo "Disk Partition: " & objPartition.DeviceID

Set colLogicalDisks = objWMIService.ExecQuery _

("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & _

objPartition.DeviceID & """} WHERE AssocClass = " & _

"Win32_LogicalDiskToPartition")

For Each objLogicalDisk In colLogicalDisks

Wscript.Echo "Logical Disk: " & objLogicalDisk.DeviceID

strDriveletter = objLogicalDisk.DeviceID

Next

'Wscript.Echo

Next

Wscript.Echo strDriveletter

Next

Set colItems = objWMIService.ExecQuery("Select * from Win32_Volume")

For Each objItem in colItems

if objItem.DriveLetter = strdriveletter then

'WScript.Echo strLblName

objItem.DriveLetter = strDrivenewletter '& ":"

objItem.Put_

else

end if

next

From what I have been able to see of AutoIT it should be more than capable of doing this but I have never tried using it before so any suggestions or pointers in the right direction to examples etc are greatfully received as I think I am starting to go crazy trying to get my head around this it should be something that the OS does all by itself.

Thanks in advance.

Paul

Share this post


Link to post
Share on other sites



Thanks.

The problem I am having though is not telling when the device is plugged into the laptop it is changing the drive letter that is selected. It does not appear to be possible to access the drive information for the USB drive by drive letter if it has selected a drive letter that is in use by a network share as the OS only returns info on the mapped drive and the w32.volume class is not implemented in windows XP and the the only other WMI classes that I can find that might do the job the class is read only.

Share this post


Link to post
Share on other sites

here is a modified version of the detect usb script mentioned elsewhere in the site. This one uses diskpart.exe (on winxp, also works on w2k, but you need to copy the file from a winxp computer to @SystemDir of the w2k).

The drawback is that the user has to have admin rights to the computer... if your users don't have that, then uncomment the "RunAsSet" statements and plug-in the appropriate code there.

Hope this helps.

$drive_to_look = ''
$strComputer = "."
 $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")

 $colEvents = $objWMIService.ExecNotificationQuery _
    ("Select * From __InstanceOperationEvent Within 5 Where " _
        & "TargetInstance isa 'Win32_LogicalDisk'")



While 1
     $objEvent = $colEvents.NextEvent
    If $objEvent.TargetInstance.DriveType = 2 Then
        Select
            Case $objEvent.Path_.Class()="__InstanceCreationEvent"
                MsgBox(4096,"test","new drive is: " & $objEvent.TargetInstance.DeviceId & @CRLF & "New type is: "& DriveGetType($objEvent.TargetInstance.DeviceId))
                if ((DriveGetType($objEvent.TargetInstance.DeviceId )=="Network") or _
                    ((StringUpper($drive_to_look&":") <> StringUpper($objEvent.TargetInstance.DeviceId )) and (DriveGetType($objEvent.TargetInstance.DeviceId )<>"Network"))) Then
                    $drive_to_look = "A"
                    $keep_looking = True
                    while $keep_looking
                        if DriveGetType($drive_to_look & ":") Then
                            if ($drive_to_look == "z") Then
                                MsgBox(4096,"Error","no drive letter available")
                                Exit
                            Else
                                $drive_to_look = chr(asc($drive_to_look)+1)
                            EndIf
                        Else
                            $file = FileOpen(@TempDir & "\letter.txt",2)
                            FileWriteLine($file,"select volume "& $objEvent.TargetInstance.DeviceId )
                            FileWriteLine($file,"assign letter="&$drive_to_look&" noerr")
                            FileWriteLine($file,"exit")
                            FileClose($file)
                            $keep_looking = False
                        EndIf
                    WEnd
                    MsgBox(4096,"New Drive","Detected new drive "& $objEvent.TargetInstance.DeviceId & ","&@CRLF & "will be changed to drive "& $drive_to_look&":.",5)
    ;               RunAsSet("adminuser",@ComputerName,"adminpass")
                    RunWait(@SystemDir & "\diskpart.exe /s " & @TempDir & "\letter.txt","",@SW_HIDE)
                    FileDelete(@TempDir & "\letter.txt")
    ;               RunAsSet()
    ;                Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been added." & @CR)
                    MsgBox(4096,"New Drive","Detected new drive "& $objEvent.TargetInstance.DeviceId & ","&@CRLF& "changed it to drive "& $drive_to_look&":.",5)
                EndIf
            Case $objEvent.Path_.Class()="__InstanceDeletionEvent"
                Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been removed."& @CR)
        EndSelect
    EndIf
WEnd

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0