'Permission denied' error when counting files - vbscript

I'm trying to count (recursivly) the number of files in a folder using VBS.
I have derived the following function but whenever I run it I get an error -
800A0046 - Permission denied
This happens on all of the folders I wish to know the file count of, with all folders either being local or on a mapped drive to which I have full access.
I have passed the folder paths both with and without a trailing slash and the error still occurs.
Can anybody tell me how I can fix this problem?
Function CountFiles(ByVal folder)
Dim parentFolder
Dim subFolder
Dim count
'** Grab an instance of the current parent folder *'
Set parentFolder = FSO.GetFolder(folder)
'** Count the files in the parent folder *'
count = parentFolder.Files.Count
'** Count all files in each subfolder - recursion point *'
For Each subFolder In parentFolder.SubFolders
count = count + CountFiles(subFolder.Path)
Next
'** Return a count of the files *'
CountFiles = count
End Function

By removing the dangerous fat from David's code (lavishly introducing variables (like IntCount), spurious back (folder object) and forth (folder.Path)) you get a clean function:
Option Explicit
Const csFolder = ".\"
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
Function CountFiles(oFolder)
CountFiles = oFolder.Files.Count
Dim oSubFolder
For Each oSubFolder In oFolder.SubFolders
CountFiles = CountFiles + CountFiles(oSubFolder)
Next
End Function
WScript.Echo "Files in", csFolder, CountFiles(goFS.GetFolder(csFolder))
This can be tested (e.g. on "\"):
cscript 30263200.vbs
Files in .\ 146
and checked vs the Properties of the folder shown by the Explorer (trust me, the 146 files are correct).
If you get a "Permission denied" for some other folder, then there is at least one folder in the tree you don't have permission to access. If all
of the starting folders you are interested in cause this error, you have no permissions for any of them.
As there are reasons for the granting of permissions, this probably is a good thing.
Consider to shell out to dir /s /b, which would give you a list of all the folders/files you are entitled to know about without breaking if there are any forbidden ones.

Related

Srcipt vbs, moveFolder return Permission denied

Option Explicit
dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists("C:\Users\michal\Desktop\mv_files_backup") then
fso.MoveFolder "C:\Users\michal.glowacki\Desktop\mv_files_backup\*.*", "\\192.168.10.245\backup\servers\backup_server"
Else
wscript.echo "doesn't exist"
End If
When I try run this script I have error:
Permission denied 800A0046
but when I change MoveFolder to CopyFolder script works correctly. Why I can't use function MoveFolder ?
From MSDN:
If source contains wildcards or destination ends with a path separator
( \ ), it is assumed that destination specifies an existing folder in
which to move the matching files. Otherwise, destination is assumed to
be the name of a destination folder to create. In either case, three
things can happen when an individual folder is moved:
If destination does not exist, the folder gets moved. This is the
usual case.
If destination is an existing file, an error occurs.
If destination is a directory, an error occurs.
An error also occurs if a wildcard character that is used in source
doesn't match any folders. The MoveFolder method stops on the first
error it encounters. No attempt is made to roll back any changes made
before the error occurs.
I've marked in bold the parts that explain your problem. Because your destination doesn't end with a trailing backslash, your script is attempting to create the folder, and failing. Try it with a \ added to the end of the destination and report back if it still doesn't work.
Try this:
fso.MoveFolder "C:\Users\michal.glowacki\Desktop\mv_files_backup", "\\192.168.10.245\backup\servers\backup_server\"

Move files older than x minutes

I want the script to move all files (all file extensions *.*) older than 5 minutes from an INN folder to and ERROR folder. In my example C:\CopyFlow\Directory test\Inn\ to C:\CopyFlow\Directory test\Inn\Error
So I figured how to move files and how to find files older than x-time after looking it up. Howover, putting this together is the issue for me. Does anyone know how I can nail this?
This is what I got so far...
Dim age_threshold
age_threshold = 5
Dim folder_path
folder_path = WScript.Arguments(0)
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.getFolder(folder_path)
Dim old_file_not_found
old_file_found = 0
For Each file in f.Files
Dim age
age = DateDiff("n", file.DateLastModified, Now)
If age > age_threshold Then
old_file_found = 1
.MoveFile "C:\CopyFlow\Directory test\Inn\*.*", "C:\CopyFlow\Directory test\Inn\Error"
Exit for
end if
Next
WScript.Quit
I'm used to batch, so this is a little bit greek to me (source http://www.evalesco.com/check-any-file-older-x-minutes-directory).
Now where do I set (dim?) my INN and ERROR folder in this script? And I'm pretty sure the if age followed by .movefile is wrong, so I probably need a little correction there.
Update Whats missing in the image is a backslash after error (\error\) in the move.file line.
You can't call methods without an object providing the method, so .MoveFile should be fso.MoveFile. However, in its current form the script would move all files from C:\CopyFlow\Directory test\Inn if any of the files in the folder passed as argument to the script is older than 5 minutes.
What you need to do is pass C:\test\inn as the argument to the script, and move only those files that actually are older:
If age > age_threshold Then
file.Move "C:\test\inn\error\"
End If

Vbscripting to search for file via user input, calling functions to ask a series of questions to do tasks

First of all I'm really new into programming i have all these ideas on what i want to do but cannot seem to figure it out. Anyways i want a vbscript or batch file, anything at this point that when executed will ask for user input and say (Name of the file you want to search for). When i type in say hello.txt and hit enter it will then ask me another question saying where do you want me to look for these files. Then if i type in C:\ or any given drive letter it will search the entire drive letter directory including folders inside of folders if im not specific on actual path. Example c:\Program Files (x86)\ it will then search that directory and all of the folders in that directory and not the entire C:\ drive. I'm thinking to achieve this i need to call a function somehow that when i type something in a certain way it calls a function that runs a specific set of code. Example the second question asked file location so i type its location and it runs the code but replaces the location with the location i entered, this way its not only working for the location written into the code and can update and replace the line of code with user input of the location entered. Otherwise having it ask those questions were competently pointless if it doesn't have the ability to be able to replace parts of the code to adapt to user input and be more efficient, and not having to re write the script every single time you wanted to search for a new file.
Sorry lot of rambling on but i have looked everywhere found things like this but nothing close would be greatly appreciated if someone could help me out or point me in the rite direction.
This is what i have tryed for user input nothing close to what i want but here it is.
Dim Input
Input = InputBox("Enter your name")
MsgBox ("You entered: " & Input)
It ask for your name and then says the name you entered i need this concept but when i type that in it calls a function and executes it. Hope someone knows what I'm talking about. Thanks
Here's a script to do that. I'll add comments to it later to explain what each part does. Right now it just outputs everything to a message box, but you can do what you want with it.
// Comments added
Dim fso, userfile, userdir, fileslist()
Set fso = CreateObject("Scripting.FileSystemObject")
ReDim fileslist(-1) ' Find results will be stored in this dynamic array
userfile = InputBox("Enter file to search for") ' Get file to search for
userdir = InputBox("Enter search directory") ' Get search directory
If Len(userfile) < 1 Then ' Check length of file name to ensure something was entered.
MsgBox "No file name entered", 4096 + 16 ' Message box. 4096 = "System modal", essentially always on top.
ElseIf Len(userdir) < 1 Then ' Check length of dir
MsgBox "No directory entered", 4096 + 16 ' 16 = exclamation/error
ElseIf Not fso.FolderExists(userdir) Then ' Make sure search directory actually exists
MsgBox "Folder " & userdir & " doesn't exist", 4096 + 16
Else
FindFile userfile, userdir ' Call FindFile sub, with the user's file and dir args passed to it
If UBound(fileslist) >= 0 Then ' After sub completes, check whether any results were found.
MsgBox Join(fileslist, vbCrLf), 4096, "Results" ' If so, output the whole array ("join"), one result per line (delimited with vbcrlf)
Else
MsgBox "File " & userfile & " not found", 4096 + 48 ' Otherwise file not found, message stating so
End If
End If
Sub FindFile(searchname, searchdir) ' Two parameters: file name, search directory
On Error Resume Next ' Enable error handling so we don't crash out on access denied errors
Dim file, folder, subfolder
For Each file In fso.GetFolder(searchdir).Files ' Process each file (as a file object) in the search directory
If LCase(searchname) = LCase(file.Name) Then ' See if file name matches. Using LCase to convert both to lowercase for case insensitivity.
ReDim Preserve fileslist(UBound(fileslist) + 1) ' If match found then increase array size by 1
fileslist(UBound(fileslist)) = file.Path ' Store the file path in newly added array entry
End If
Next
' Now the recursive bit. For any subfolders in current search directory, call FindFile again
' with (1) the same file name originally passed in as "searchname", and (2) a new search
' directory of the subfolder's name. FindFile then starts again on this new directory: finds files,
' adds matches to the fileslist array, then does the same on each subfolder found. This
' is how it searches each subfolder (and subfolders of subfolders... etc) in a directory
For Each subfolder In fso.GetFolder(searchdir).SubFolders
FindFile searchname, subfolder.Path
Next
On Error GoTo 0
End Sub

Renaming folders with VBScript

I need to be able to often renaming multiple folders in ASP. None of the methods that I've found are working for me. Here is the current method that I am trying-
Set FS = CreateObject("Scripting.FileSystemObject")
FS.MoveFolder "/images/715", "/images/V14"
This, as well as others that I've tried, always gives me a "path not found" error. I know that the directory that the script is in has these folders in it because I've been renaming them manually. Does the script need to know the full path? What if I don't know what the full path may be?
Update:
The script runs in a directory named "/ifp". I also tried this, with and without the "/ifp" and both forward and back slashes, and it also gave path not found. Once this works on my testing server I send it to the guy with the production server so I can't use any static directory names other than the "/images/????"
Dim sCurPath
sCurPath = CreateObject("Scripting.FileSystemObject").GetAbsolutePathName(".")
FS.MoveFolder sCurPath & "\ifp\images\715", sCurPath & "\ifp\images\V14"
Use absolute paths (C:\images\715). It would look like this:
Set FS = CreateObject("Scripting.FileSystemObject")
FS.MoveFolder "C:\images\715", "C:\images\V14"
If you are using a -nix system then keep in mind that the first / is the root directory - ensure you do indeed have an images folder in the root directory path.
Also note that in order to rename the folder there cannot be trailing \'s after the folder names and the script must be run on the local machine.
If you keep getting path errors, you're passing it incorrectly somehow. Build in some error checking to see what is going wrong:
Dim tmpPath = "\ifp\images\715"
Dim newPath = "\ifp\images\V14"
If FS.FolderExists(sCurPath & tmpPath) Then
Response.Write("The folder exists.")
FS.MoveFolder sCurPath & tmpPath, sCurPath & newPath
Else
Response.Write("The folder " & sCurPath & tmpPath & " does not exist.")
End If

Rename and Move Folders Using VB

I have the following script which works great if I need to rename files in a folder but now I want to move and rename folders from one mapped drive to another mapped drive. Can someone help me to modify the script to do so? I am failry new to VB so pardon if I can't firgure this out but it took me a little while to figure this one out and now I am not sure how to modify this script. Thank you in advance!
The folders by default are labeled A.1234, A.5678, and so on and will always have a different number assigned to them. I will keep the numbers in the label as they are PO numbers. So my end result desired is Ack~1234, Ack~5678, and so on.
Dim fso, f, f1, fc, s Set
fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder("Y:\Test")
Set fc = f.Files
For Each f1 in fc
f1.move f1.ParentFolder & "\" & replace(f1.Name, "A.", "Ack~")
Again these folders exist on the root of a mapped drive and need to move to another mapped drive with the new names. If more info is needed please do not hesitate to ask.
UPDATE
I modified the script below to give an idea of what I'm looking to do.
Dim fso, objFol
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFol = fso.GetFolder("Z:\")
Set objFolders = objFol.Folders
For each folder in objFolders
fso.Movefolder folder, "Y:\" & Replace(fso.Name, "A.", "Ack~")
Next
This give me an error stating it does not support "Folder". There will be any number of folders in the Z drive and I need to move them all to the Y drive. Sorry if I didn't explain properly in the previous post.
The move command is taking a string, for which you're providing the parent folder of the file, so the file isn't moving. I think it'll be sufficient to provide a different folder location. For example:
Dim fso, f, f1, fc, s
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder("Y:\Test")
Set fc = f.Files
For Each f1 in fc
f1.move "Z:\TargetFolder\" & replace(f1.Name, "A.", "Ack~")
Note: I've not tested this, but if there are problems then just ask
Additional Stuff after update:
The following code will allow you to move folders, and do the replacements you need to the folder name string.
Dim fso, objFol, objMoveFol, strPathBuild
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFol = fso.GetFolder("Y:\Test")
For Each objMoveFol In objFol.SubFolders
'Replace the root folder locations in the path
strPathBuild = Replace(objMoveFol, "Y:\Test", "Z:\TargetFolder\")
'Do the required other fiddle
strPathBuild = Replace(strPathBuild, "A.", "Ack~")
fso.Movefolder objMoveFol, strPathBuild
Next
Make sure you're really careful with this sort of thing, as getting is wrong can be fairly spectacular.

Resources