Return volume name in Do loop - vbscript

I'm trying to create a script for HP UFT to automatically create/mount/unmount VHDs as needed. The problem is that diskpart takes quite a while to create, mount, format and label the VHD. I need a method to pause the script while the VHD is being created/mounted, after which it will continue on with the script.
The variable uftDrive is currently returning a drive letter, not a volume name, so the loop just runs indefinitely. Any thoughts as to how to pass the volume names as a variable? The VHD script is automatically assigning the first-available drive letter to the drive, as we have multiple machines that UFT will be run on, and they don't have identical network drive mappings, forcing us to dynamically detect the drive by volume name.
'===========================================================================
'This will check to see if the Virtual Hard Disk (VHD) exists, and if not,
'create it
'===========================================================================
Dim makevhdExists, vhdExists
Set makevhdExists = CreateObject("Scripting.FileSystemObject")
Set vhdExists = CreateObject("Scripting.FileSystemObject")
If Not makevhdExists.FileExists("c:\UFT\mountVHD.bat") Then
makevhdExists.CopyFile "\\companyADfolders\Users\UFT\VHD\*.*", "c:\UFT\"
End If
If Not makevhdExists.FileExists("c:\UFT\unmountVHD.bat") Then
wait 2
ElseIf Not vhdExists.FileExists("C:\UFT\UFT.vhd") Then
SystemUtil.Run "cmd","/c""C:\UFT\createVHD.bat"""
End If
Dim uftExists, uftDrive
uftExists = "False"
Do
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where VolumeName = 'UFT'")
For Each objItem in colItems
uftDrive = objItem.Name 'This is currently returning a drive letter,
'not a volume name
If uftDrive.Name = "UFT" Then
uftExists = "True"**
End If
Next
Loop Until uftExists = "True"

For the wait part
WScript.Sleep 5000
where the value indicated is milliseconds
For the second part, maybe i'm missing something, so, instead of an answer I have one silly question:
If you query wmi for win32_logicaldisk instances where their VolumeName is UFT, WHY your if command checks the Name property instead of the VolumeName property?
In any case, you don't need that if. If colItems.Count is greater than 0, there is at least one instance that matches the indicated condition
Something like this should work
Dim uftExists
uftExists = False
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Do
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where VolumeName = 'UFT'")
If colItems.Count > 0 Then
utfExists = True
Else
Sleep 500
End If
Loop Until uftExists

Changing ObjItem.Name to ObjItem.VolumeName worked!
For Each objItem in colItems
uftDrive = objItem.VolumeName 'This is currently returning a drive letter, not a volume name
If uftDrive = "UFT" Then
uftExists = "True"**
End If
Next

For the first question: To delay the script, you can use this function:
WScript.Sleep 1000
The number is in Milliseconds, so 1000 is 1 second.

Related

Is there a way to identify which USB port a mass storage drive uses?

I am trying to identify which port a USB mass storage is connected to.
Here is my scenario. I have a vbscript program that monitors the USB mass storage drive plug-ins and do some routines on them and its process flow needs to know which port the drive was connected to.
So far I am not able to find a link between the USB events, the identified usb mass storage drive and the port on the computer (for eg., Location - Port_#0001.Hub_#0006 as shown in Windows device manager->usb controllers->USB mass storage). My search was mainly using 'VbsEdit' tool by connecting a storage device and stepping through the available snippets.
Sub Monitor_usb_storage_events()
Dim WsShell,strComputer,wmi, wmiEvent,usb,objDisk,fileSys,colDisks,Drive
Set WsShell = CreateObject("WScript.Shell")
strComputer = "."
Set wmi = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set wmiEvent = wmi.ExecNotificationQuery("select * from __InstanceOperationEvent within 1 where TargetInstance ISA 'Win32_PnPEntity' and TargetInstance.Description='USB Mass Storage Device'")
While True
Set usb = wmiEvent.NextEvent()
Select Case usb.Path_.Class
Case "__InstanceCreationEvent"
'WScript.Echo("USB device found")
Set colDisks = wmi.ExecQuery _
("SELECT * FROM Win32_LogicalDisk")
For Each objDisk in colDisks
If objDisk.DriveType = 2 Then
Set fileSys = CreateObject("Scripting.FileSystemObject")
For Each Drive In fileSys.Drives
If Drive.IsReady Then
'*Need port number where this drive is connected*
End If
Next
End If
Next
Case "__InstanceDeletionEvent"
'WScript.Echo("USB device removed")
Case "__InstanceModificationEvent"
'WScript.Echo("USB device modified")
End Select
Wend
End Sub
Here is a script I've had a for while that queries the Win32_USBControllerDevice and then returns the dependent devices.
Option Explicit
Dim strComputer: strComputer = "."
Dim objWMIService: Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dim colDevices: Set colDevices = objWMIService.ExecQuery _
("Select * From Win32_USBControllerDevice")
Dim objDevice
For Each objDevice in colDevices
Dim strDeviceName: strDeviceName = objDevice.Dependent
strDeviceName = Replace(strDeviceName, """", "")
Dim arrDeviceNames: arrDeviceNames = Split(strDeviceName, "=")
strDeviceName = arrDeviceNames(1)
Dim colUSBDevices: Set colUSBDevices = objWMIService.ExecQuery _
("Select * From Win32_PnPEntity Where DeviceID = '" & strDeviceName & "'")
Dim objUSBDevice
For Each objUSBDevice in colUSBDevices
Wscript.Echo objUSBDevice.Description
WScript.Echo objUSBDevice.PnPDeviceID
Next
Next
If you combined this with your __InstanceOperationEvent WMI query you should be able to modify the above script to query the DeviceID returned in the matched Win32_PnPEntity instance.
You can get the DeviceID in your above script using:
strDeviceName = usb.TargetInstance.DeviceID

VBScript, Delete Exact String Only

Hi I have the following VBscript to remove printers, however when I run it, it is also deleting just Canon IR70.
Dim aPrinterModels(2)
aPrinterModels(0)="Canon IR70 (Cpoy 1)"
aPrinterModels(1)="Canon IR70 (Cpoy 2)"
aPrinterModels(2)="Canon IR70 (Cpoy 3)"
for each printer in aPrinterModels
RemovePrinterAndPort(printer)
next
Sub RemovePrinterAndPort(strModelMask)
on error resume next
msiMessageTypeError = &H01000000
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
'objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer where name like'" & strModelMask & "%'")
if colInstalledPrinters.count<>0 then
For each objPrinter in colInstalledPrinters
Set colInstalledPorts = objWMIService.ExecQuery("Select * from Win32_TCPIPPrinterPort where name like '" & objPrinter.PortName & "'")
objPrinter.Delete_
For Each objPort in colInstalledPorts
objPort.Delete_
Next
Next
end if
Set colInstalledPrinters = Nothing
Set colInstalledPorts = nothing
Set objWMIService = Nothing
End Sub
How can I get it to only delete the exact string in aPrinterModels??
Many thanks in advance.
I cannot try wmi query with your scenario and like comparison but I'd use = comparison as follows:
Set colInstalledPrinters = objWMIService.ExecQuery( _
"Select * from Win32_Printer where name = '" & strModelMask & "'")
The code snippet with objPort.Delete execute only on the assumption that ports for copied printer instances differ from original printer port.
In more presumable case of the same port for all printer instances (original and copies): modify code snippet with objPort.Delete to be performed conditionally or suppress it at all and remove unused ports as an independent task:
for each printer in aPrinterModels
RemovePrinter(printer)
next
RemoveUnusedPorts
Sub RemovePrinter(strModelMask)
'on error resume next
msiMessageTypeError = &H01000000
Set objWMIService = GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery( _
"Select * from Win32_Printer where name = '" & strModelMask & "'")
if colInstalledPrinters.count<>0 then
For each objPrinter in colInstalledPrinters
' wscript.Echo "Printer to Delete " & objPrinter.Name
objPrinter.Delete_
Next
end if
Set colInstalledPrinters = Nothing
Set objWMIService = Nothing
End Sub
Sub RemoveUnusedPorts
' code snippet to remove unused ports here
End Sub

Find a service with Partial name VBS

We have a service that runs with different names on different machines like
Bomgar-scadsadccd, Bomgarsdscchfn, Bomgarscnkfkdk
So, here we need to write a VB script that will find this service with partial name "Bomgar"
and check it's status like
1) Not present, then should install from a shared folder like "start \10.216.16.245\Bomgar.exe"
2) Installed but not running, then start the service.
3) Installed and running then quit.
How can we achieve this?
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service where Name='bomgar*'")
nItems = colRunningServices.Count
If nItems > 0 Then
For Each objItem in colRunningServices
If objItem.State = "Stopped" Then
objItem.startservice
ElseIf objItem.State = "Running" Then
exit
End If
Next
Else
start \\10.18.23.245\Shared\Bomgar.exe
End If
You can use the like keyword and % wildcards in your WQL statement to find any services containing certain text. For example:
Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service where Name like '%bomgar%'")
And instead of start, you'll need to use something like the Run command of the WshShell object to launch your EXE:
With CreateObject("WScript.Shell")
.Run "\\10.18.23.245\Shared\Bomgar.exe"
End With

VBS - Get Default Printer

Using the Wscript.Network object shown below, is there an easy way to retrieve the default printer on a machine? I know how to set the default printer, but I'm looking to get the current default printer name. I have a mixture of Windows 2000, XP, and 7 clients and don't want to use WMI for that reason.
Set objNetwork = CreateObject("WScript.Network")
Set objLocalPrinters = objNetwork.EnumPrinterConnections
The WshNetwork.EnumPrinterConnections collection doesn't provide any information about the default printer. You can try retrieving the default printer name from the registry instead, though I'm not sure if it's reliable:
Set oShell = CreateObject("WScript.Shell")
strValue = "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Device"
strPrinter = oShell.RegRead(strValue)
strPrinter = Split(strPrinter, ",")(0)
WScript.Echo strPrinter
As for WMI, it's true that some WMI classes and class members aren't available on older Windows versions. For example, the Win32_Printer.Default property that indicates whether the printer is the default one, doesn't exist on Windows 2000/NT. Nevertheless, there's a simple workaround for finding the default printer on those Windows versions, which consists in checking for the PRINTER_ATTRIBUTE_DEFAULT attribute in each printer's Attribute bitmask:
Const ATTR_DEFAULT = 4
strComputer = "."
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = oWMI.ExecQuery("SELECT * FROM Win32_Printer")
For Each oPrinter in colPrinters
If oPrinter.Attributes And ATTR_DEFAULT Then
Wscript.Echo oPrinter.ShareName
End If
Next
This code works on later Windows versions as well.
For details, check out this Hey, Scripting Guy! article: Is There Any Way to Determine the Default Printer On a Computer?
From (MSDN):
The EnumPrinterConnections method returns a collection. This collection is an array that associates pairs of items — network printer local names and their associated UNC names. Even-numbered items in the collection represent printer ports. Odd-numbered items represent the networked printer UNC names. The first item in the collection is at index zero (0).
So there is little chance to get the default printer from this collection. Sorry
Greetz,
GHad
for MS ACCESS oPrinter.ShareName is null but oPrinter.Caption works well!
Dim strComputer As String
Dim oWMI As Object
Dim colPrinters
Dim oPrinter
Const ATTR_DEFAULT = 4
strComputer = "."
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = oWMI.ExecQuery("SELECT * FROM Win32_Printer")
For Each oPrinter In colPrinters
If oPrinter.Attributes And ATTR_DEFAULT Then
Debug.Print oPrinter.Caption
End If
Next

Mount/Unmount USB drives with VBSCript

I am looking for a way to mount\unmount a USB flash drive using VBScript. This is the closest I was able to get.
Sub EjectDrive(strDrive)
On Error Resume Next
CONST SSF_DRIVES = 17
Set objShell = CreateObject("Shell.Application")
Set objDrive = objShell.Namespace(SSF_DRIVES).ParseName(strDrive)
objDrive.InvokeVerb "E&ject"
End Sub
This will work on Windows Server 2003, but not NT/2000/XP/Vista unfortunately.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_Volume Where Name = 'E:\\'")
For Each objItem in colItems
objItem.Dismount(True, True)
Next
From Dismount a Volume.
Take a look at this thread, its talks about using the mountvol.exe command line tool to mount/unmount a drive, and it should work for USB flash drives, or there is also a program called deveject. Se this thread for more info: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/d2e5d16e-e7c9-48ef-88b8-3abf6e638384
You can popup the eject dialog by using something like this. I am not sure if it possible to unmount a specific device.
Set WshShell = WScript.CreateObject("WScript.Shell")
intReturn = WshShell.Run("RunDll32.exe shell32.dll,Control_RunDLL hotplug.dll", 1, TRUE)

Resources