I write the following VB script in order to run the CLI command - vpnclient.exe
my target is to automate the vpnclcient process and answer “y” when question appears,
I have WIN XP PC
During running the vpnclient.exe in CMD window we get then following question
Do you wish to continue? (y/n):
In my VB I write the “echo y” in order to answer on this question automatically
but question is still stuck in CMD window ,and I cant continue
please advice what chuld be wrong in my code and how to fix it?
MY VB script (vpnclient.exe – exist under VPN directory)
Dim oShell
Set oShell = WScript.CreateObject ("WScript.Shell")
oShell.run "cmd /K CD C:\Program Files\Cisco\VPN & ( echo y | vpnclient.exe connect ""site moon"" )"
Set oShell = Nothing
You can try by creating a file with the commands to be executed on the command line instead of echoing the password.
Here's an example where a text file is created first with the required command and then those commands are invoked from the file.
Public Function FTPDownload(serverName, ftpuser, ftppassword, dirPath, localpath, fileName)
Dim fso, myfile
Set fso = CreateObject("Scripting.FileSystemObject")
'Create FTP.EXE commands file
Set fso = CreateObject("Scripting.FileSystemObject")
Set myfile= fso.OpenTextFile("C:\Regression\Results\ftp_cmd.ini", 2, True)
myfile.WriteLine("open " &serverName )
myfile.WriteLine(ftpuser)
myfile.WriteLine(ftppassword)
myfile.WriteLine("lcd " & localpath )
myfile.WriteLine("cd " & dirPath)
myfile.WriteLine("prompt")
myfile.WriteLine("cr")
myfile.WriteLine("mget *" &fileName &"*" )
myfile.WriteLine("mdelete *" &fileName &"*" )
myfile.WriteLine("close")
myfile.WriteLine("quit")
myfile.Close
'====================The following code executes the FTP script. It creates a Shell object and run FTP program on top of it.===================
Set objShell = CreateObject( "WScript.Shell" )
objShell.Run ("ftp -i -s:" & chr(34) & "C:\Regression\Results\ftp_cmd.ini" & chr(34))
Set objShell = Nothing
End Function
Related
When I started on this I wasn't aware that I had to be able to select each daily task manually and pick each task whenever I want, I'm trying to figure out how to convert it into a manual entry so I don't have to rework the whole thing, bear in mind I'm very new to vbscript so if there's an obvious solution I apologize. I'm still working on the later days of the week to finish this.
dtmToday = Date()
dtmDayOfWeek = DatePart("w", dtmToday)
'Select case to pickup the value of day of the week and call procedure
Select Case dtmDayOfWeek
Case 1
Call Sunday()
Case 2
Call Monday()
Case 3
Call Tuesday()
Case 4
Call Wednesday()
Case 5
Call Thursday()
Case 6
Call Friday()
Case 7
Call Saturday()
End Select
'Sunday procedure will execute from select case
sub Sunday()
'defining variables
dim wshShell
dim path
dim fso
'setting up the environment to run vbscript
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
' Execute the command and append to the text file
WShShell.run "cmd /c ping -n 10 youtube.com >> ping.txt", hidden
wscript.quit
End sub
'Monday procedure will execute from select case
sub Monday()
'defining variables
dim wshShell
dim path
dim fso
'setting up the environment to run vbscript
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
' to execute the command and append to the text file using >> if you want to text to be overriden use >
WShShell.run "cmd /c netstat >> netstat.txt", hidden
wscript.quit
End sub
'Tuesday procedure will execute from select case
sub Tuesday()
'defining variables
dim wshShell
dim path
dim fso
'setting up the environment to run vbscript
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
' to execute the command and append to the text file using >> if you want to text to be overriden use >
WShShell.run "cmd /c arp -a >> arp.txt", hidden
wscript.quit
End sub
sub Wednesday()
'defining variables
dim wshShell
dim path
dim fso
'setting up the environment to run vbscript
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
WShShell.run "cmd /c nbstat -n >> nbstat.txt", hidden
wscript.quit
End Sub
sub Thursday()
'defining variables
dim wshShell
dim path
dim fso
'setting up the environment to run vbscript
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
WShShell.run "cmd /c tracert -n 10 youtube.com >> nbstat.txt", hidden
wscript.quit
End Sub
You need first optimize your code to avoid heavy duplication as #Lankymart was mentioned it in his comment, by writing one function and call it when you need it, and to store all your commands into an array for easy access by their index.
So your code can be written like that :
Option Explicit
' We define our Global variables
Dim Title,ArrCommands,strcmd,dtmDayOfWeek,IndexCommand,UserInput
Title = "Run command line based on the Day Of Week"
'----------------------------------------------------------------------------------
' We define and store our commands lines into an array
ArrCommands = Array(_
"ping -n 10 youtube.com >> ping.txt",_
"netstat >> netstat.txt",_
"arp -a >> arp.txt",_
"Color 0A & Title Running nbtstat command & nbtstat -n",_
"Color 0A & Title Running Tracert command & tracert youtube.com",_
"Color 0A & Title Running Ipconfig command & Ipconfig /all",_
"Color 0A & Title Running netstat command & netstat -ano"_
)
'-------------------------------Main Program---------------------------------------
Do While Not IsDate(UserInput)
UserInput = InputBox("Type a date here example 24/06/2020",Title,"24/06/2020")
dtmDayOfWeek = MyWeekday(UserInput)
IndexCommand = dtmDayOfWeek - 1
Loop
MsgBox "Day of the Week = "& dtmDayOfWeek & vbCrlf &_
"The command will be executed is : "& ArrCommands(IndexCommand),vbInformation,Title
'Select case to pickup the value of day of the week
Select Case dtmDayOfWeek
Case 1
Call Execute(ArrCommands(IndexCommand),0)
Case 2
Call Execute(ArrCommands(IndexCommand),0)
Case 3
Call Execute(ArrCommands(IndexCommand),0)
Case 4
Call Execute(ArrCommands(IndexCommand),1)
Case 5
Call Execute(ArrCommands(IndexCommand),1)
Case 6
Call Execute(ArrCommands(IndexCommand),1)
Case 7
Call Execute(ArrCommands(IndexCommand),1)
End Select
'MsgBox "Command line is done",vbInformation,Title
'----------------------------------------------------------------------------------
Function MyWeekday(MyDate)
If MyDate = "" Then MyDate = Date()
If IsDate(MyDate) Then
MyWeekDay = Weekday(MyDate)
Exit Function
End If
End Function
'----------------------------------------------------------------------------------
Sub Execute(StrCmd,Console)
Dim ws,MyCmd
Set ws = CreateObject("wscript.Shell")
'The console = 0 means will be running in hidden mode
If Console = 0 Then
MyCmd = "CMD /C " & StrCmd & " "
ws.run MyCmd,Console,True
End If
'The console = 1 means will be running in not hidden mode
If Console = 1 Then
MyCmd = "CMD /K " & StrCmd & " "
ws.run MyCmd,Console,True
End If
End Sub
'----------------------------------------------------------------------------------
I have a batch file that gets some parameters from the command line and returns some values into STDOUT.
I want the batch file to be "silent" (such that the console is not shown), and found out probably the only possibility of using vbs script.
I used this thread for implementing the argument forwarding to the batch file in VBS.
Then, I used the following command for calling the batch file I wrapped:
CreateObject("WScript.Shell").Run batchFilePath & " " & Trim(arglist), 0, False
It turns out that my batch file does run, but its STDOUT is discarded somewhere, and does not make its way back to whom called the VBS script. I.e. the batch file's STDOUT is not redirected into the VBS script's STDOUT.
How can I make the batch file's STDOUT being redirected to the VBS script STDOUT, such that if I start the VBS script from some shell, the batch file's output will be printed to the shell too?
Use Exec instead of Run, like this:
set objShell = CreateObject( "WScript.Shell" )
cmd = "echo Hello World!"
' Run the process
set objRes = objShell.Exec( "cmd /c """ & cmd & """" )
' Wait for the child process to finish
Do While objRes.Status = 0
WScript.Sleep 100
Loop
' Show whatever it printed to its standard output
Wscript.Echo "The output was:" & vbNewLine & objRes.StdOut.ReadAll()
Try this...
Intreturn = WshShell.Run("cmd /c " & path& " " & args & ">c:\batchoutput.txt", 0, true)
Set fso = CreateObject("Scripting.FileSystemObject")
Set objfile = fso.OpenTextFile("c:\batchoutput.txt", 1)
text = objfile.ReadAll
Objfile.Close
Or try this...
Set WshShell = WScript.CreateObject("WScript.Shell")
Set objexc = WshShell.Exec("cmd /c " & command and args) 'replace command and args with proper variables
strOutputText = ""
While Not objexc.StdOut.AtEndOfStream
strOutputText = strOutputText & objexc.StdOut.ReadLine()
Loop
Msgbox strOutputText
You may need some debugging on this.
I am new to Windows Scripting. I have a simple script for archiving using WinRAR CLI utility. I have to schedule this script using batch file. During archiving there are some errors and I want them to write in a simple text file or at least I can write entire output of archiving in a file. How can I change my code to do this?
Dim MyDate
Dim OutputFile
const WaitUntilFinished = true, DontWaitUntilFinished = false, ShowWindow = 1, DontShowWindow = 0
MyDate = Replace(Date, "/", "-")
OutputFile = "backup-" & mydate & ".rar"
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.CurrentDirectory = "C:\Users\ABC\Desktop\"
objShell.Run "C:\windows\Rar.exe a .\VBScripts\backups\" & OutputFile & " software", ShowWindow, WaitUntilFinished
objShell.Popup "Archiving Completed Successfully!",5, "Scheduled Backup"
Set objShell = Nothing
Batch file is like this;
#echo off
start /wait C:\Users\ABC\Desktop\VBScripts\scheduled_backup.vbs
Change your command line to include redirection to a log file:
logfile = "C:\path\to\your.log"
objShell.Run "%COMSPEC% /c C:\windows\Rar.exe a .\VBScripts\backups\" & _
OutputFile & " software >""" & logfile & """", ShowWindow, WaitUntilFinished
Use this function instead of WScript.Shell.Run:
' Runs an external program and pipes it's output to
' the StdOut and StdErr streams of the current script.
' Returns the exit code of the external program.
Function Run (ByVal cmd)
Dim sh: Set sh = CreateObject("WScript.Shell")
Dim wsx: Set wsx = Sh.Exec(cmd)
If wsx.ProcessID = 0 And wsx.Status = 1 Then
' (The Win98 version of VBScript does not detect WshShell.Exec errors)
Err.Raise vbObjectError,,"WshShell.Exec failed."
End If
Do
Dim Status: Status = wsx.Status
WScript.StdOut.Write wsx.StdOut.ReadAll()
WScript.StdErr.Write wsx.StdErr.ReadAll()
If Status <> 0 Then Exit Do
WScript.Sleep 10
Loop
Run = wsx.ExitCode
End Function
Call script instead of start in your batch and use redirection:
script //nologo C:\Users\ABC\Desktop\VBScripts\scheduled_backup.vbs 2> errors.txt
I have jumbled up a vbs script to compress files older than 7 days using 7za's command line utility. While most of the logic works fine, I am able to compress single file into single zip file.
The problem arises when I try to add all matching files to one zip file. Below is the code snippet:
strCommand = "7za.exe -mx=9 a " & ObjectFolder & sysDate & ".zip " & strFileName
strRun = objShell.Run(strCommand, 0, True)
Now as per the 2nd line, setting True would make sure the script will wait till command is finished executing. But the problem is 7za is exiting immediately and going to the next loop, processing the next file and since it tries to create same zip file, I get access denied error.
Can someone please help me to fix this?
I have also tested the scenario in command prompt. What I did was, execute below 2 commands simultaneously in separate prompts:
Prompt 1:
C:\7za.exe -mx=9 a test.zip c:\sample1.pdf
Prompt 2:
C:\7za.exe -mx=9 a test.zip c:\sample2.pdf
Prompt 2 resulted in following error:
Error: test.zip is not supported archive
System error:
The process cannot access the file because it is being used by another process.
This is the same error I am getting in my script and I need help in resolving this. Any pointers will be helpful!
UPDATE:
With the great pointers provided by both John and Ansgar, I was able to resolve this! It turned out to be a bug in my script! In my script, I included a check to see if the file is in use by any other process before processing it for archive. So I was checking this by opening the file for appending using:
Set f = objFSO.OpenTextFile(strFile, ForAppending, True)
But before proceeding to process the same file, I was not CLOSING it in the script, hence the error: The process cannot access the file because it is being used by another process
After I closed the file, all went well!
Thanks Again for all the great support I got here!
As a token of gratitude, I am sharing the whole script for anyone's use. Please note that I am not the original author of this, I gathered it from various sources and tweaked it a little bit to suit my needs.
Archive.vbs
Const ForAppending = 8 ' Constant for file lock check
Dim objFSO, objFolder, objFiles, objShell
Dim file, fileExt, fileName, strCommand, strRun, strFile
Dim SFolder, OFolder, Extension, DaysOld, sDate
'''' SET THESE VARIABLES! ''''
SFolder = "C:\SourceFolder\" 'Folder to look in
OFolder = "C:\OutputFolder\" 'Folder to put archives in
Extension = "pdf" 'Extension of files you want to zip
DaysOld = 1 'Zip files older than this many days
''''''''''''''''''''''''''''''
sDate = DatePart("yyyy",Date) & "-" & Right("0" & DatePart("m",Date), 2) & "-" & Right("0" & DatePart("d",Date), 2)
'Create object for playing with files
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Create shell object for running commands
Set objShell = wscript.createObject("wscript.shell")
'Set folder to look in
Set objFolder = objFSO.GetFolder(SFolder)
'Get files in folder
Set objFiles = objFolder.Files
'Loop through the files
For Each file in objFiles
fileName = Split(file.Name, ".")
fileExt = fileName(UBound(fileName))
'See if it is the type of file we are looking for
If fileExt = Extension Then
'See if the file is older than the days chosen above
If DateDiff("d", file.DateLastModified, Now()) >= DaysOld Then
strFile = file.Path
'See if the file is available or in use
Set f = objFSO.OpenTextFile(strFile, ForAppending, True)
If Err.Number = 70 Then ' i.e. if file is locked
Else
f.close
strFName = objFSO.GetBaseName(file.name)
strCommand = "C:\7za.exe -mx=9 a " & OFolder & sDate & ".zip " & strFile
strRun = objShell.Run(strCommand, 0, True)
'wscript.echo strCommand ' un-comment this to check the file(s) being processed
'file.Delete ' un-comment this to delete the files after compressing.
End If
End If
End If
Next
'Cleanup
Set objFiles = Nothing
Set objFolder = Nothing
Set objFSO = Nothing
Set objShell = Nothing
wscript.Quit
===========================
Thanks
-Noman A.
Not quite what you asked for, but here's a batch script I use for a similar task in case that helps get you past of your immediate issue:
ArchiveScriptLog.Bat
::ensure we're in the right directory, then run the script & log the output
cls
pushd "c:\backup scripts"
ArchiveScript.bat > ArchiveScript.log
popd
ArchiveScript.bat
::Paths (must include the \ on the end). There must be no space between the equals and the value
::UNC paths are acceptable
Set FolderToBackup=F:\EnterpriseArchitect\Energy\
Set BackupPath=F:\EnterpriseArchitect\!ARCHIVE\
Set RemoteBackupPath=\\ukccojdep01wok\h$\Energy\cciobis01edc\
Set SevenZip=C:\Program Files (x86)\7-Zip\
::Get DATE in yyyymmdd format; done in two lines to make it easy to change the date format
FOR /F "TOKENS=2,3,4 DELIMS=/ " %%A IN ('echo %Date%') DO (SET mm=%%A&SET dd=%%B&SET yyyy=%%C)
SET strDate=%yyyy%%mm%%dd%
::Set the Backup File to be the backup path with the current date & .zip on the end
Set BackupFile=%BackupPath%%strDate%.zip
::create a zip containing the contents of folderToBackup
pushd %SevenZip%
7z a "%BackupFile%" "%FolderToBackup%"
popd
::go to the archive directory & copy all files in there to the remote location (this accounts for previous errors if the network were unavailable)
pushd "%BackupPath%"
move *.zip "%RemoteBackupPath%"
popd
::delete off backups in the remote location which are older than 90 days
pushd "%RemoteBackupPath%"
forfiles /D -90 /M *.zip /C "cmd /c del #file"
popd
Your command shouldn't return before 7za has finished its task (and it doesn't in my tests). Try changing your code to the following, so you can see what's going on:
strCommand = "7za.exe -mx=9 a " & ObjectFolder & sysDate & ".zip " & strFileName
strCommand = "%COMSPEC% /k " & strCommand
strRun = objShell.Run(strCommand, 1, True)
It may also be a good idea to quote the filenames:
Function qq(str)
qq = Chr(34) & str & Chr(34)
End Function
strCommand = "7za.exe -mx=9 a " & qq(ObjectFolder & sysDate & ".zip") & " " _
& qq(strFileName)
I am writing a script that executes and write everything to the file
here is example,
I stored the complete command in the variable 'Command' ,
Command = "ftp ftp.xyz.com 21 " & vbCRLF
and then executing it in command prompt,
shell.Run "%comspec% /c FTP " & Command & " > " & E:/abc.txt, 0, TRUE
but when this program execute it won't write anything to the text file because this is an incomplete command, this command on execution prompt user to input username and password of FTP,
how can i do this , that my programm automatically input username and password when prompt and then write everything to file ?
You need to run FTP using an unattended script. (Try ftp /? and look at the -s switch.)
It looks like this:
Const HOSTNAME = "ftp.myserver.com"
Const USERNAME = "Login"
Const PASSWORD = "password"
Set WshShell = CreateObject("WScript.Shell")
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFile = objFso.CreateTextFile("session.txt")
With objFile
.WriteLine "USER username"
.WriteLine "password"
.WriteLine "cd /public_html/" ' continue adding commands like this
.Close
End With
strOutput = "C:\somefilepath\output.txt"
strCommand = "%systemroot%\System32\ftp.exe -s:session.txt > " & strOutput
strCommand = WshShell.ExpandEnvironmentStrings(strCommand)
WshShell.Run strCommand, 0, vbTrue
objFso.DeleteFile "session.txt", vbTrue
You can read more in my article Using FTP in WSH on ASP Free. I also answered a related question here.