I am writing a piece of VBScript in which I want to Save a file (say, notepad) into my USB Stick.
To do so, I am using AppActive and SendKeys "^s" which will pop up a window asking for the path.
The problem is I don't know what letter will my USB have on certain computers. On mine, it's E, but on my friend's PC it is G (anyway, irrelevant). Is there a way to say the path without including the letter?
I named my usb "USB" and simply tried to write the path without the letter. It works for my computer, but it doesn't work on any other PCs. Any suggestions?
PS: I'm working on Windows (if the OS is needed)
As for my research, I got this link, which is closest to my need, but not what I want.
Getting USB Device path from USB port
UPDATE: Noodles' code was really good if you want to find the drive letter when you don't know it
UPDATE 2: I also found this
http://www.howtogeek.com/96298/assign-a-static-drive-letter-to-a-usb-drive-in-windows-7/
So I can basically assign a random letter for my USB (say, Z) and simply use this as drive letter (hope it also works on windows 10)
This code monitors volume changes and if it's a USB then copies the files to c:\test. Your interest is the Win32_Volume code.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set evtDevice = objWMIService.ExecNotificationQuery ("SELECT * FROM Win32_VolumeChangeEvent")
Wscript.Echo "Waiting for events ..."
Do
Set objReceivedEvent = evtDevice.NextEvent
'report an event
Wscript.Echo " Win32_Device Changed event occurred" & VBNewLine
If objReceivedEvent.EventType = 1 Then
Wscript.Echo "Type = Config Changed"
ElseIf objReceivedEvent.EventType = 2 Then
Wscript.Echo "Type = Device Arrived"
Set colItems = objWMIService.ExecQuery("Select * From Win32_Volume")
For Each objItem in colItems
Wscript.Echo objitem.DriveType
If objitem.DriveType = 2 then
Wscript.Echo objItem.DriveType & " " & objItem.Name & " " & objItem.driveletter
Wscript.Echo "Starting Copying"
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set SrcFldr=objShell.NameSpace(objitem.driveletter)
Set DestFldr=objShell.NameSpace("c:\test\")
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Wscript.Echo "Finished Copying"
End If
Next
ElseIf objReceivedEvent.EventType = 3 Then
Wscript.Echo "Type = Device Left"
ElseIf objReceivedEvent.EventType = 4 Then
Wscript.Echo "Type = Computer Docked"
End If
Loop
You can't write to any storage device without knowing its assigned drive letter. You likely would want to instead open a file dialog allowing the user to choose the appropriate USB driver or other storage drive and then use the path selected.
See "How to open a file dialog in VBS".
Related
A previous team where I work created a vbs script that can automatically start a restore of a Macrium Image File located on inserted optical media. The problem is that the Macrium Image File is now too big for one disc, and now we have it split onto 2 separate discs, so now the vbs script doesn't function the way it should.
When Automatic Restore is launched, it should detect disc 1, which ends in 00.00.mrimg and know that it is part of a multi-disc install, at which point it asks for the next disc, ending in 00-01.mrimg.
I know this probably makes no sense, especially if anyone reading is not familiar with Macrium. But I will do my best to answer any questions.
I would normally plug away and try to figure it out myself, but i'm not very familiar with VBS and the problem is pretty time sensitive. Any help I can get will be much appreciated.
Opened AutoRestore.vbs script to see if I could fix the issue, but I don't know enough about vbs to fix it.
'AutoRestore.vbs
Dim fso, d, dc, s, n , Root, u, racine, folder, folderName, restoreString, foundFile, cdDrive
Dim wipe
Dim objShell
Set objShell = WScript.CreateObject("WScript.shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set dc = fso.Drives
foundFile = false
restoreString = "00-00.mrimg"
For Each d in dc
Root = d.Driveletter & ":"
racine = d.Driveletter & ":\"
u= Detect(Root)
if (( u="CD-ROM") ) then
cdDrive = cdDrive & racine & " "
if (d.isReady) then
folderName = racine & "IAS\"
Set folder = fso.GetFolder(folderName)
end if
end if
Next
If IsNull(folder) or IsEmpty(folder) Then
MsgBox "Could not locate IAS folder containing restore image." & vbCrLf & "The following optical disk drives were searched: " & cdDrive & vbCrLf & "Please verify the media is the drive or use manual restore.", 48, "Folder Not Found"
Else
For each file in folder.Files
If instr(1,file.Name, restoreString, vbTextCompare) > 0 Then
return = objShell.run("""%ProgramFiles%\macrium\diskrestore.exe""" & folderName & file.Name & " -r -g -u --targetnum 0 --reboot --eject",1,false)
foundFile = true
Exit For
End If
Next
if (foundFile = false) Then
MsgBox "Cannot locate .mrimg file in " & folderName & "." & vbCrLf & "Please use manual restore.", 48, "File Not Found"
End If
End If
Function Detect(DrivePath)
Dim fso, d, s, t
Set fso = CreateObject("Scripting.FileSystemObject")
Set d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(DrivePath)))
Select Case d.DriveType
Case 0: t = "Unknown"
Case 1: t = "Removable"
Case 2: t = "Fixed"
Case 3: t = "Network"
Case 4: t = "CD-ROM"
Case 5: t = "RAM Disk"
End Select
Detect = t
End Function
Expected Results: Run AutoRestore.vbs, the script sees the 00-00.mrimg file in IAS folder of the optical media, then prompts to insert the optical media containing the 00-01.mrimg file.
Actual Results: Run AutoRestore.vbs, then Macrium states "Backup set is not complete. At least one file may be missing."
You could first copy all the mrimg files to a temporary folder on the machine's hard drive. Once you have them all, you can then run Disk Restore with that folder instead of the CD-ROM drive.
Most of your existing code would work. After the For Each d in dc loop, you know the drive where the discs are being inserted. You could add another loop:
Dim tempFolder
Set tempFolder = fso.GetFolder("C:\AutoRestore\")
Do While MsgBox("Please insert disc and click OK. When all discs have been inserted, click Cancel", vbOKCancel, "Auto Restore") = vbOK
For Each file In folder.Files
If InStr(1, file.Name, ".mrimg") > 0 Then
' Copy file to Temp folder
fso.CopyFile file.Path, tempFolder.Path & "\", True
End If
Next
Loop
After this, you should have all the mrimg files in the tempFolder location. I am not familiar with the parameters the Marcium command expects but this is where you would specify the new folder:
objShell.run("""%ProgramFiles%\macrium\diskrestore.exe""" & tempFolder.Path & "\" & file.Name & " -r -g -u --targetnum 0 --reboot --eject",1,false)
Im looking for some help with creating a script that can scan the Disk Drives on a Server or PC and search out a Zepto Virus infection and alert us in our Monitoring Dashboard.
We have used scripts to detect Cryptowall and Locky but these rely on searching for a very specific file name. The difference with Zepto is that its "Help" files are composed with a random number in each file:
_3_HELP_instructions.html, _21_HELP_instructions.html, _12_HELP_instructions.html etc.
Essentially im looking for a script that can maybe search for *_HELP_instructions.html or even just search for any filename with HELP_instructions.html contained in it.
The code we have used for Locky is as follows:
strComputer = "."
set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colShares = objWMIService.ExecQuery("Select * from Win32_Share")
For each objShare in colShares
strInfected = False
If objFSO.fileexists(objShare.path & "\_Locky_recover_instructions.txt") then
strInfected = True
wscript.echo "Network Share " & objShare.Path & " is INFECTED!"
wscript.quit(2015)
End If
Next
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
Is there anyone out there that can help me with this one? due to the way our Monitoring Dashboard works i need the script to be based on the above, with the:
If strInfected = False Then
wscript.echo "System Clear!"
wscript.quit(0)
End If
at the end of the script.
Many thanks in advance
So I've been thrown in the deep end of the shark tank without even my arm floaters and I don't know how to swim (Translation - I don't know VBS).
So I find myself here because I keep hitting my scripts with the two sticks I have it still doesn't work. When I fix one issue another appears and when I fix that one the other returns (feel like I'm chasing my tail).
So below is the latest iteration of my code (I keep moving crap around thinking it might magically work).
'---- Set Constant for Reading
Const ForReading = 1
'----- Define at the Variables for the scripts
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
'------ Path for File below is Explicit (meaning you need to enter the complete path)
Set objTextFile = objFSO.OpenTextFile("c:\users\me\documents\Small- ComputerList.txt", ForReading)
'---- Begin Loop for reading the Array
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
arrServiceList = Split(strNextLine , ",")
' ------- strComputer = "usms-w-ksd68598" Commented out from original script
' ------- Reading from the Array
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & arrServiceList(0) & "\root\cimv2")
' ------- Running the Command to find all the printers
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colPrinters
objDictionary.RemoveAll
objDictionary.Add objPrinter.PortName, objPrinter.PortName
Next
' ------ Running the Command to find all the TCP/IP Printer Ports
Set colPorts = objWMIService.ExecQuery _
("Select * from Win32_TCPIPPrinterPort")
For Each objPort in colPorts
If objDictionary.Exists(objPort.Name) Then
strUsedPorts = strUsedPorts & _
objDictionary.Item(objPort.Name) & VbCrLf
Else
strFreePorts = strFreePorts & objPort.Name & vbCrLf
End If
Next
'----- Printing out the Results to the screen
For i = 1 to Ubound(arrServiceList)
& arrServiceList(i)
Next
Loop
Wscript.Echo "System Name: " & arrServiceList(0)
Wscript.Echo "The following ports are in use for: " & VbCrLf & strUsedPorts
Wscript.Echo "The following ports are not used for: " & VbCrLf & strFreePorts
If my crazy ducted taped scripts make no sense please don't be shocked. I've been stuck in a cave hitting the keyboard with two sticks and this is the result I've come up with. Not too bad for a caveman but it still doesn't work.
Any help, assistance, advice, comment, jokes, sarcasm, ranting appreciated. Any trolling will be swiftly dealt with a big mallet over the head.
Thank you,
Ed Medina
Lo and behold the gods of code have shine their light upon my path and provided me with an answer.
Anyway, Thanks to Big Chris and Mr. Roryap for their questions. I want to also thank the Academy, all of my fellow coders, my mom, coffee, the mailman, my wife, my cat and all the little people.
Here is a code that will work which will read from a file in your Temp Folder (file is named Computers.txt) and then against that file it will run and test to find all the printers ports in that computer in your Domain (Network).
The output is a simple Echo out giving it to you in the window. I just kept hitting the keyboard with my two sticks in my dark, smelly cave and out came out the code.
The only caveat is that if you have a wrong computer name or a computer turned off the script will fail at that point and won't continue (yeah, yeah, working on it).
'---- Set Constant for Reading
Const ForReading = 1
'----- Define at the Variables for the scripts
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
'------ Path for File below is Explicit (meaning you need to enter the complete path)
Set objFile = objFSO.OpenTextFile("c:\Temp\Computers.txt", ForReading)
'---- Begin Loop for reading the Array
Do Until objFile.AtEndOfStream
strComputer = objFile.ReadLine
' ------- Reading from the Array
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
' ------- Running the Command to find all the printers
Set colPrinters = objWMIService.ExecQuery _
("Select * from Win32_Printer")
For Each objPrinter in colPrinters
objDictionary.RemoveAll
objDictionary.Add objPrinter.PortName, objPrinter.PortName
Next
' ------ Running the Command to find all the TCP/IP Printer Ports
Set colPorts = objWMIService.ExecQuery _
("Select * from Win32_TCPIPPrinterPort")
For Each objPort in colPorts
If objDictionary.Exists(objPort.Name) Then
strUsedPorts = strUsedPorts & _
objDictionary.Item(objPort.Name) & VbCrLf
Else
strFreePorts = strFreePorts & objPort.Name & vbCrLf
End If
Next
'---- Output to Screen
Wscript.Echo "System Name: " & strComputer
Wscript.Echo "The following ports are in use for: " & VbCrLf & strUsedPorts
Wscript.Echo "The following ports are not used for: " & VbCrLf & strFreePorts
Loop
Thank you.
BTW if anyone know how to throw an error and keep working give feel free to post. Thanks again everyone.
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.
Looking to have a vbscript that can copy a folder and its contents to a active usb drive. So the script need to found the active usb drive put in it. Next copy the folder and its contests to the usb drive. Then after the copy job it done need to tell it's finish. There is what I get so far for it.
Const OverWriteFiles = True
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.CopyFolder "C:\Test" , "?:\Test" , OverWriteFiles 'the "?:\Test" is the part set the usb drive at.
Wscript.Echo "I am Done."
So, what part I really need help with is found out what the active usb drive letter. Next tell is to copy to that usb drive letter.
I know it's not alot of code. But, any info wold be a great help.
This example shows the type of each drive:
Set oFSO = CreateObject("Scripting.FileSystemObject")
sRes = ""
For Each oDrive In oFSO.Drives
sRes = sRes & "DriveLetter: " & oDrive.DriveLetter & ", DriveType: "
Select Case oDrive.DriveType
Case 0
sRes = sRes & "Unknown"
Case 1
sRes = sRes & "Removable"
Case 2
sRes = sRes & "HDD"
Case 3
sRes = sRes & "Network Drive"
Case 4
sRes = sRes & "CD-ROM"
Case 5
sRes = sRes & "RAM-Drive"
End Select
sRes = sRes & vbNewLine
Next
MsgBox sRes
Your script should be like this one:
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each objDrive In objFSO.Drives
If objDrive.DriveType = 1 Then
objFSO.CopyFolder "C:\Test" , objDrive.DriveLetter & ":\Test" , True
MsgBox "Copy to " & objDrive.DriveLetter & " Completed"
End If
Next
UPD: Last drive can be found this way:
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each objDrive In objFSO.Drives
Set objLastDrive = objDrive
Next
MsgBox objLastDrive.DriveLetter
Well, there may be more than one "active" USB drive. There's nothing stopping me from plugging flash drives into every available USB port on my computer. But here's how you can identify a USB drive (aka, "Removable Drive") on your computer and copy a folder to it with the CopyFolder() function.
Const TYPE_REMOVABLE = 1
With CreateObject("Scripting.FileSystemObject")
For Each Drive In .Drives
If Drive.DriveType = TYPE_REMOVABLE Then
.CopyFolder "C:\Test", Drive.DriveLetter & ":\Test", True
End If
Next
End With