I'm a newbie to programming but very much willing to work hard and
try. We have about 100 servers and on each servers we have the g drive
and e drive. early this year there were some temp files dumped all
over the 100 servers under variuos folders and subfolders so i have
been assigned a task to clean this up. Any chance someone can guide me
in getting an automated script where all i need to do is enter the
list of servers and the file extension to search and then script would
scan for the file extension on all 100 servers and each of the drives
associated with it.
so far i have the following script
Rem Script created: 01.10.2009 22:24
Rem Author: captedgar
strDir = "c:\"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set objDir = FSO.GetFolder(strDir)
getInfo(objDir)
Sub getInfo(pCurrentDir)
For Each aItem In pCurrentDir.Files
If LCase(Right(CStr(aItem.Name), 3)) = "tmp" Then
'wscript.Echo aItem.Name 'all c:\*.tmp
listed
End If
Next
For Each aItem In pCurrentDir.SubFolders
getInfo(aItem) 'passing recursively
Next
End Sub
Your code will work very nicely, stepping recursively through all folders on
the specified drive. To make it go through all existing drives you could use
the following code:
Const Fixed = 2
Set oFSO = CreateObject("Scripting.FileSystemObject")
For Each oDrive In oFSO.Drives
If oDrive.DriveType = Fixed _
Then getInfo oFSO.GetFolder(oDrive.DriveLetter & ":\")
Next
Sub getInfo(pCurrentDir)
For Each aItem In pCurrentDir.Files
If LCase(Right(CStr(aItem.Name), 3)) = "tmp" _
Then WScript.Echo aItem.Name 'all c:\*.tmp listed
Next
For Each aItem In pCurrentDir.SubFolders
getInfo(aItem) 'passing recursively
Next
End Sub
If you wish to deal with several file extensions then you have to repeat the
process for each extension.
While it would be fairly straightforward to process a list of x servers with
a script running on your own machine, execution would be very slow and you
would choke your network for many hours. This is because the script must
read hundreds of thousands of file names from each server. It would be much
fast to execute the script locally on each server, e.g. like so:
@echo off
for /F %%a in (c:\Servers.txt) do (
psexec.exe -u edgar -p password \\%%a \\YourPC\c$\script.vbs
)
This batch file will do the following:
- It will enumerate your server names from c:\Servers.txt
- It will start a console session at each server, using the
specified user name and password.
- It will invoke the script that you keep on your own machine.
Note that the script represents a security risk because your
account/password is hard coded and visible to anyone working on your
machine.
You can download psexec.exe from www.sysinternals.com.
Hi pegasus
Thanks for the reply.
This may be a daft question so please bare with me.
I have copied the exact script from yours.
see below
Const Fixed = 2
Set oFSO = CreateObject("Scripting.FileSystemObject")
For Each oDrive In oFSO.Drives
If oDrive.DriveType = Fixed _
Then getInfo oFSO.GetFolder(oDrive.DriveLetter & ":\")
Next
Sub getInfo(pCurrentDir)
For Each aItem In pCurrentDir.Files
If LCase(Right(CStr(aItem.Name), 3)) = "tmp" _
Then WScript.Echo aItem.Name 'all c:\*.tmp listed
Next
For Each aItem In pCurrentDir.SubFolders
getInfo(aItem) 'passing recursively
Next
End Sub
and run this script and i get line12char1 permission denied error.
This is when executing the following line For Each aItem In
pCurrentDir.Files. any idea why?
Hi pegasus
see below
Const Fixed = 2
================
I'm reluctant to bare with strangers but I'll bear with you this time . . .
The error message "permission denied" means exactly what it says: That you
did not have sufficient rights to access the folder you were trying to open.
Which one is it? Simple - put this statement just before the problem line
and you will see:
wscript.echo pCurrentDir.Path
It is probably the "System Volume Information Folder". To deal with these
situations you must implement your own error handler so that your code skips
gracefully over any folder it cannot open. Putting the statements "On error
resume next" and "On error goto 0" before and after the lines that could
couse a problem is the usual method to do this. Download the help file
script56.chm from the Microsoft site to see how it's done.
Thanks pegasus
it worked. Thanks for being very helpful
regards
Thanks pegasus
regards
============
Thanks for the feedback.
Hi pegasus
How are u?
I'm back and also my script as changed ever since.
See below only a segment code which i need help for
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTmpName = "Report.log"
Set objScript = objFSO.CreateTextFile(strTmpName)
arrComputers = Array("servernameA","servernameB","servernameC") ' If
you want to check multiple PCs
'arrComputers = Array("PC1") if you want to check one PC. It doesn’t
have to be an Array then..
For Each strComputer In arrComputers
objStartFolder = "\\" & strComputer & "\C$\Test\"
I have 2 questions really for the above segment code
1) The list of arguments i'm going to pass to array will be huge as it
will have to search for about 100 servers. Is there a way i can pass
this argument list on to a text file so that the script will read each
line of the text as an array entry and continue with the program
2) objStartFolder = "\\" & strComputer & "\C$\Test\"
Is there a way i can exclude certain folders to search so that it
doesn't choke network. At the minute it is taking around 35 mins to
perform the search if i include "\C$\" rather than "\C$\Test\" .
please guide me. Let me know if u need full script as i can't see
these values being changed anywhere else other than this
Hi pegasus
How are u?
I'm back and also my script as changed ever since.
See below only a segment code which i need help for
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTmpName = "Report.log"
Set objScript = objFSO.CreateTextFile(strTmpName)
arrComputers = Array("servernameA","servernameB","servernameC") ' If
you want to check multiple PCs
'arrComputers = Array("PC1") if you want to check one PC. It doesn�t
have to be an Array then..
For Each strComputer In arrComputers
objStartFolder = "\\" & strComputer & "\C$\Test\"
I have 2 questions really for the above segment code
1) The list of arguments i'm going to pass to array will be huge as it
will have to search for about 100 servers. Is there a way i can pass
this argument list on to a text file so that the script will read each
line of the text as an array entry and continue with the program
2) objStartFolder = "\\" & strComputer & "\C$\Test\"
Is there a way i can exclude certain folders to search so that it
doesn't choke network. At the minute it is taking around 35 mins to
perform the search if i include "\C$\" rather than "\C$\Test\" .
please guide me. Let me know if u need full script as i can't see
these values being changed anywhere else other than this
===========
1) Put your server names into a text file, then use your script to read this
text file one line at a time.
2) You could include or exclude certain folders. Here is a method to include
the specified folders:
aInclude = split("Documents and Settings/Program Files\MS Office/Windows",
"/")
for each sFolder in aInclude
set objStartFolder = oFSO.GetFolder("\\" & strComputer & "\C$\\" &
sFolder)
. . .
next
'And here is how you can exclude the specified folders
sExclude = "/Documents and Settings/Program Files\MS Office/Windows/"
set objStartFolder = oFSO.GetFolder("\\" & strComputer & "\C$")
for each objSubFolder in objStartFolder.subfolders
if instr(1, sExclude, "/" & objSubFolder.name & "/", 1) = 0 then
. . .
end if
next
In each case I selected the forward slash as a delimiter because it cannot
possibly occur in a Windows folder name.
Thanks pegasus for the quick reply. I was reading up on how to read an
argument list from text file into the script and i made following
changes to my script. But now i'm getting invalid parameter or call
when it tries to read the line Set objTextFile = objFSO.OpenTextFile
_. i'm not sure if i can include error handlers here when im defining
parameters to pass into the scripts
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTmpName = "Report.log"
Set objScript = objFSO.CreateTextFile(strTmpName)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
("c:\Servers.txt", ForReading)
strText = objTextFile.ReadAll
objTextFile.Close
Sorry Pegasus
Please ignore my previuos question. it worked just needed a bit more
scratching and a little bit of help from the neighbour(developer)
Sorry Pegasus
==========
Glad to hear you sorted it out. Note that if you do not want
to read your server list one line at a time as I previously suggested
then you could step through an array like so:
aServers = split(objTextFile.ReadAll, vbCRLF)
for each sServer in aServers
wscript.echo "Dealing with server", sServer
..
next
Hi pegasus sorry again
My default windows scripting host is cscript and the script i have
written is a wscript. so i googled and came across a script which can
be added to my existing script to force it to use cscript. ever since
i have done that, nothing has happened i.e. process just runs for a
long time and nothing happens so i just have to kill it
find below my complete script
Rem Script created: 02.12.2009 13:24
Rem Author: captedgar
'Script to search the file path on multiple servers and write to a
log.'
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTmpName = "Report.log"
Set objScript = objFSO.CreateTextFile(strTmpName)
arrComputers = ReadTxtToArray("C:\PCList.txt") ' If you want to check
multiple PCs
'arrComputers = Array("PC1") if you want to check one PC. It doesn't
have to be an Array then..
For Each strComputer In arrComputers
objStartFolder = "\\" & strComputer & "\g$\"
On Error Resume Next
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
On Error GoTo 0
On Error Resume Next
Next
ShowSubfolders objFSO.GetFolder(objStartFolder)
On Error GoTo 0
Next
Dim oShell
Set oShell = CreateObject("Wscript.Shell")
forceUseCScript
Sub forceUseCScript()
If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
oShell.Popup "Launched using wscript. Relaunching...",
3,"WSCRIPT"
oShell.Run "cmd.exe /k " & WScript.Path & "\cscript.exe //NOLOGO
" & Chr(34) & WScript.scriptFullName & Chr(34),1,False
WScript.Quit 0
End If
End Sub
Dim arrTxtFile : arrTxtFile = ReadTxtToArray("C:\PCList.txt")
Function ReadTxtToArray(strInputFilePath)
Const ForReading = 1
' create FSO
Dim objFSO : Set objFSO = CreateObject
("Scripting.FileSystemObject")
' open text file for reading
Dim objFile : Set objFile = objFSO.OpenTextFile(strInputFilePath,
ForReading)
' read the content of the file and split into an array using
vbCrLf as the seperator
' and return the array
ReadTxtToArray = Split(objFile.ReadAll, vbCrLf)
' close the file
objFile.Close
End Function
Sub ShowSubFolders(Folder)
For Each Subfolder in Folder.SubFolders
Set objFolder = objFSO.GetFolder(Subfolder.Path)
Set colFiles = objFolder.Files
On Error Resume Next
For Each objFile in colFiles
fileName = Split(objFile.Name, ".")
fileExt = UCase(fileName(UBound(fileName)))
'See if it is the type of file we are looking for
If fileExt = "tmp" Then
objScript.WriteLine(objFile.path & " was found!") ' If you change
objFile.path to objFile.name that would print just the names - but you
know that ?
'objFile.Delete - We can also delete them all ?
On Error GoTo 0
End If
Next
ShowSubFolders Subfolder
Next
End Sub
MsgBox "Completed!"
Set objFS = Nothing
My questions now is as follows
1) how can i make sure that this script runs with default host always
set to cscript
2) for excluding certain directories during the search, i added your
code from the earlier comment after line 11
sExclude = "/Documents and Settings/"
sExclude2 = "/dev/"
Set objStartFolder = oFSO.GetFolder("\\" & strComputer & "\C$")
for each objSubFolder in objStartFolder.subfolders
If InStr(1, sExclude, "/" & objSubFolder.name & "/", 1) = 0 Then
This came upwith an error called unexpected Next. can u please guide
me pegasus.
forceUseCScript
==============
In my fully tested "exclusion" example I wrote this:
sExclude = "/Documents and Settings/Program Files\MS Office/Windows/"
You then went and changed it to:
sExclude = "/Documents and Settings/"
sExclude2 = "/dev/"
In other words, I created a single variable that hold *all* folders to be
excluded. You did something quite different. I urge you to analyze how my
script works, then adapt it to your own script.
About the script running for a long time and apparently not doing anything:
If you don't have an interactive debugger then you must place a number of
statements like
wscript.echo "Line10"
wscript.echo "Line53"
into your code. You will soon see where it gets stuck.
About making cscript.exe the default interpreter - it's standard Command
Line stuff. The command
cscript /?
will tell you everything you know. This applies to hundreds of console
commands - try a few of them such as "copy", "del", "net" etc. etc.
Sorry again pegasus and this will defnitely be the last sorry for this
question forum.
I have had to start from scratch as nothing was writing to the log
folder. I showed the below script to a developer and he said if the
file doesn;t exist in the first argument parameter you are passing to
array, then the report log will not write and the program will skip
the rest of the execution.
Rem Script created: 02.12.2009 13:24
Rem Author: captedgar
'Script to search the file path on multiple servers and write to a
log.'
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTmpName = "Report.log"
Set objScript = objFSO.CreateTextFile(strTmpName)
arrComputers = ReadTxtToArray("ReleaseServers.txt")
arrComputers = Array("PC1") if you want to check one PC. It doesn't
have to be an Array then..
For Each strComputer In arrComputers
objStartFolder = "\\" & strComputer & "\g$\test1\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
Next
ShowSubfolders objFSO.GetFolder(objStartFolder)
Next
Dim arrTxtFile : arrTxtFile = ReadTxtToArray("ReleaseServers.txt")
Function ReadTxtToArray(strInputFilePath)
Const ForReading = 1
Dim objFSO : Set objFSO = CreateObject
("Scripting.FileSystemObject")
Dim objFile : Set objFile = objFSO.OpenTextFile(strInputFilePath,
ForReading)
ReadTxtToArray = Split(objFile.ReadAll, vbCrLf)
objFile.Close
End Function
Sub ShowSubFolders(Folder)
For Each Subfolder in Folder.SubFolders
Set objFolder = objFSO.GetFolder(Subfolder.Path)
Set colFiles = objFolder.Files
For Each objFile in colFiles
fileName = Split(objFile.Name, ".")
fileExt = UCase(fileName(UBound(fileName)))
'See if it is the type of file we are looking for
If fileExt = "PH" Then
objScript.WriteLine(objFile.path & " was found!")
'objFile.Delete - We can also delete them all ?
End If
Next
ShowSubFolders Subfolder
Next
End Sub
MsgBox "Completed!"
Set objFS = Nothing
On the above script, I now have the following questions,
1) how can i add error handlers so the script will continue to run and
not stop if the file doesn;t exist in any parameters passed to array
from the text file.
2) If i change the drive name from C to another drive called G as
shown above will the script work.
I'm hoping to get my script back up and running so that i can then
think about excluding folders and subfolders.
please advice
please advice
==================
Your code has all of the right elements to function but it is somewhat
confused. and lacks structure. The main program starts at the top (good!),
then it has some more code at the very end (bad). The recursive process is
rather muddled. Your file names are not fully qualified (very bad) and you
sometimes use an "obj" name for a string (great if you want to confuse
people). Your indentation is random, which is great for concealing the
underlying structure of the program. Your functions and subroutines carry no
descriptions, which makes the code hard to maintain.
Here is the code again, this time properly structured and indented. Since it
is fully structured, it will be very easy to include the exclusion code.
Note that it will NOT delete any files - it will simply tell you what it
would do.
If you do not have an interactive debugger, get one now. Working without it
makes it nearly impossible to write a decent VB Script program.
'---------------------------------
'Recursively delete all .tmp files
'8 Dec 2009 FNL
'---------------------------------
strTmpName = "c:\Report.log"
strServers = "c:\ReleaseServers.txt"
strExt = ".tmp"
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Open the output file
On Error Resume Next
Set objScript = objFSO.CreateTextFile(strTmpName)
if err.number <> 0 then Error Err.Description
On Error Goto 0
'Get the list of servers to be processed
arrComputers = ReadTxtToArray(strServers)
'Recursively process each server
For Each strComputer In arrComputers
strStartFolder = "\\" & Trim(strComputer) & "\g$\test1\"
Set objFolder = objFSO.GetFolder(strStartFolder)
ProcessFolder objFolder
Next
MsgBox "Completed!"
'----------------------------------------
'Process the specified folder recursively
'----------------------------------------
Sub ProcessFolder (objFldr)
WScript.Echo "Processing", objFldr.Path
For Each objFile In objFldr.Files
If LCase(Right(objFile.Name, 4)) = strExt _
Then WScript.Echo "Deleting", objFile.path
'objFSO.Delete objFile.path
Next
For Each objSubFolder In objFldr.SubFolders
ProcessFolder objSubFolder
Next
End Sub
'--------------------------------------
'Read the list of servers into an array
'--------------------------------------
Function ReadTxtToArray(strServerList)
Const ForReading = 1
If Not objFSO.FileExists(strInputFilePath) _
Then Error "Cannot find """ & strInputFilePath & """."
Set objFile = objFSO.OpenTextFile(strServerList,ForReading)
ReadTxtToArray = Split(objFile.ReadAll, VbCrLf)
objFile.Close
End Function
'----------
'Error Exit
'----------
Sub Error (msg)
MsgBox msg
WScript.Quit 9
End Sub
Hi pegasus
I have read through the script of your once completely and also
understood the logic that i could derive from it within my
capabilities. Just tried testing them and i get a pop up saying
"Cannot Find". I'm just thinking this has got to do with the
strInputFilePath not defined in the variable declaration section. I
want to edit the script before sending but choose to discuss instead.
Also i have noticed strServerList is not defined as well
please advice
Hi pegasus
I have read through the script of your once completely and also
understood the logic that i could derive from it within my
capabilities. Just tried testing them and i get a pop up saying
"Cannot Find". I'm just thinking this has got to do with the
strInputFilePath not defined in the variable declaration section. I
want to edit the script before sending but choose to discuss instead.
Also i have noticed strServerList is not defined as well
please advice
==========
Oops - made a last minute change. The line must read
Then Error "Cannot find """ & strServerList & """."
HI pegasus
The pop up box still says the same i.e. cannot find and now it's
echoing c:\test\servers.txt i.e. cannot find c:\test\servers.txt.
The servers.txt file has a list of server names in a text file in the
same location as this script and the following are the contents in it
servername1
servername2
servername3
servername4
servername5
.
.
.
servername100
All the above server names replaced by actual server names and
seperated by clicking enter i.e. end of line confirmation
Hi pegasus
do i need to declare strInputFilePath as a string in the variable
decaration. is this is what causing the issue in my previuos comment.
I inserted and then removed by adding wscript.echo pCurrentDir.Path to
check what the value is before the line where it is erroring and then
it came back with expected If error. So i just changed things back to
way it was. I know you've been very patient with me and i have been
equally determined to see the light at the end of the tunnel. so
please bare with this stranger pegasus
Hi pegasus
please bare [bear] with this stranger pegasus
=====
There are two ways to deal with variables:
a) You place the statement "option explicit" at the top of your code. When
you do this then you must declare each and every variable with a Dim or a
ReDim statement. If you forget to declare some variable then execution of
the script will halt with an error message when that variable is used.
b) You do not have the "option explicit" statement in your code. In this
case you can use any variable anywhere in your code, whether you declare it
or not.
For beginners and for complex code it is recommended that you do use the
"option explicit" statement. It won't affect execution of your program in
any way, other than flagging undeclared variables, but it protects you
against some spelling errors in variable names (like the one I tripped
over). It also enforces a certain discipline in declaring and using
variables.
Remember also to use the preferred VB Script prefixes. Obj or o refers to
Objects, str or s for Strings etc. VB Script does not care about them but
using them facilitates maintenance and trouble-shooting. Your code line
objStartFolder = "\\" & strComputer & "\g$\test1\"
obviously breaks this rule: objStartFolder is a string, not an object.
Hi pegasus
Can we pass more then 100 servers as arguments to the array through
the text file. i.e. is there is a limit to the number of arguments
passed to an array?.
I'm thinking of broadening the search(may be useful in future)
> Hi pegasus
>
> Can we pass more then 100 servers as arguments to the array through
> the text file. i.e. is there is a limit to the number of arguments
> passed to an array?.
> I'm thinking of broadening the search(may be useful in future)
I don't know what the limit is but I'm sure it is far, far more than the
number of servers you have. As a practical exercise in VB Scripting you
could do this little test:
- Create a text file
- Using the WriteLine method, write 100,000 times the string "Line " & n
into it where n is your indexing counter.
- Close the file.
- Read it with the ReadAll method.
- Split it into an array.
Hi Pegasus
I would like to thank you for all your advice and patience in
resolving my query. Thanks again
"capt edgar" <capt...@googlemail.com> screv in Newsbeitrag
news:f703ec78-e08e-4bdc...@r14g2000vbc.googlegroups.com...
>
> Hi Pegasus
> I would like to thank you for all your advice and patience in
> resolving my query. Thanks again
Thanks for the feedback.