scan computer for a file and output folder location - vbscript

I need to take a list of computers (IP or PC name) that are all on the same domain in CSV format. Scan each computer for a specific folder name. The folder will be arcXXXof. The x's are a hash and change for each PC. If the folder is found it needs to output the folder path to a CSV and append with each computer scanned. My programming is limited and I only really know Java. Since this will be run from a server it will need local administrative privileges to run on the local machines. My manager suggested I use VBS, but I have never written in that before.
My current snag is getting an error "expected then" Here's my loop.
Sub Recurse(strFolderPath)
Dim objFolder
Set objFolder = objFSO.GetFolder(strFolderPath) 'reads Folders pulled from recursion
Dim objSubFolder
dim folderStart 'grabs the first 2 characters of the file name. Should match 'of' if correct folder
Dim folderEnd 'grabs the last 6 (test) characters of the folder name, should match arc.txt if correct
Global checkEnd
set checkEnd = "arc" 'checks for "arc" at ending
Global checkStart
set checkStart = "of" 'used to check if folder name is correct path
For Each objSubFolder in objFolder 'for every Folder scanned
'Scans the name of the Folder, objSubFolder, for an ending of “arc", and beginning of “of” (testing)
set folderName = objSubFolder.name
Set folderEnd = right(folderName, 3)
set folderStart = left(folderName, 2)
dim folderName
if folderName = testFolderName
then WScript.Echo objSubFolder
'If folderEnd = checkEnd and
'If folderStart = checkStart
'Add Folder location to array, set array to next object
'Then fLocations(i) = object.GetAbsolutePathName(objSubFolder) and i = i+1
else
End If
Next
'recursive for searching new folder
For Each objSubFolder in objFolder.Subfolders
Call Recurse(objSubFolder.Path)
Next

OK, you could use a regex to match the name. Define it up front, in your global scope:
Dim re
Set re = New RegExp
re.IgnoreCase = True
re.Pattern = "^arc\w{3}of$"
I'm using \w, which is equivalent to [a-zA-Z_0-9]. You can change this if you're expecting only digits (\d) or something else for these three chars.
Then, in your Recurse function, test the folder name against it:
For Each objSubFolder in objFolder.SubFolders
' See if this folder name matches our regex...
If re.Test(objSubFolder.Name) Then
' Match. Just display for now...
WScript.Echo objSubFolder.Path
End If
' Test its subfolders...
Recurse objSubFolder.Path
Next
Tip: Remove the On Error Resume Next from your code while you're developing or you might miss all kinds of bugs and cause all kinds of headaches.

Related

Find the owners of all the folders within a given path

I am trying to find the owners of all the folders in a given path. I have the following code:
Set objFSO = CreateObject("Scripting.FileSystemObject")
For Each objFolder In objFSO.GetFolder("C:\Windows").SubFolders
strpath = objFolder.Path
WScript.Echo strpath
Next
My end goal is to put the path and and owner of all the folders from the given path into a text file.
Could someone help me find the owner of a folder and be able to place this owner name into a variable. I could then use this to improve my existing code.
As JoSerra mentioned in the comments you can retrieve the owner of a file or folder via the WMI class Win32_LogicalFileSecuritySetting. The sample code from the Script Center is mostly accurate. I would, however, recommend using double quotes instead of single quotes around the path.
Single quotes (unlike double quotes) are valid characters in a path. If you invoke the statement wmi.Get("Win32_LogicalFileSecuritySetting.Path='" & path & "'") with a path containing a single quote, the call will fail with an "invalid object path" error. Thus it's better to use double quotes and escape backslashes in the path.
path = "C:\some\folder 'with' quotes"
Function Esc(str)
Esc = Replace(str, "\", "\\")
End Function
Set wmi = GetObject("winmgmts:")
Set fs = wmi.Get("Win32_LogicalFileSecuritySetting=""" & Esc(path) & """")
rc = fs.GetSecurityDescriptor(sd)
If rc = 0 Then
WScript.Echo "Owner: " & sd.Owner.Domain & "\" & sd.Owner.Name
Else
WScript.Echo "Couldn't retrieve security descriptor."
End If

Get path of an item in list

My main goal is to check if a folder exists in a zip file.
For that I'm trying to go through the various files and folders. I use the following code for that:
strFile = "C:\Users\temp.zip"
Set objApp = CreateObject("Shell.Application")
Set objContents = objApp.NameSpace(strFile).Items()
For Each objItem in objContents
WScript.Echo objItem.Name
If objItem.IsFolder Then
GetSubFolders(objItem)
End If
Next
Sub GetSubFolders(objSubItem)
Set objFolder = objSubItem.GetFolder
For Each objItem2 in objFolder.Items()
WScript.Echo objItem2.Name
If objItem2.IsFolder Then
GetSubFolders(objItem2)
End If
Next
End Sub
The problem is I can't seem to figure out, how to check which level I am on.
I thought about this:
levelDepth = Len(strFile) - Len(Replace(strFile, "\", ""))
which tells me how "deep" the zip file is. If I could get the full path of objItem and objItem2, then I could use the same method. Subtract the two from each other and get how deep in the zip file the current directory or file is.
The Path property should give you the full path of an item.

unzip file silently vbscript

I found online script that basically unzip every .zip archive in a given path.
sub UnzipAll(path)
set folder = fso.GetFolder(path)
for each file in folder.files
if (fso.GetExtensionName(file.path)) = "zip" then
set objShell = CreateObject("Shell.Application")
objshell.NameSpace(path).CopyHere objshell.NameSpace(file.path).Items
file.delete
end if
next
end sub
This is actually working, but the problem is that I want to unzip "silently" (silently means that I don't want any kind of message from the system when unzipping, like "do you want to overwrite?" ect.).
I've searched a lot on google and I found that you just need to add a few flags on the "CopyHere" method, like this:
objshell.NameSpace(path).CopyHere objshell.NameSpace(file.path).Items, *FLAGHERE*
But the problem is right here. The flags would normally work, but they are completely ignored when unzipping a .zip archive.
So I searched for a workaround, but I didn't find anything helpful.
I managed to do it by myself. Basically you want to unzip 1 file per time and not everyone togheter, and before copying it you just check if it already exists, and evenutally delete it:
set fso = CreateObject("Scripting.FileSystemObject")
sub estrai(percorso)
set cartella = fso.GetFolder(percorso)
for each file in cartella.files
if fso.GetExtensionName(file.path) = "zip" then
set objShell = CreateObject("Shell.Application")
set destinazione = objShell.NameSpace(percorso)
set zip_content = objShell.NameSpace(file.path).Items
for i = 0 to zip_content.count-1
'msgbox fso.Buildpath(percorso,zip_content.item(i).name)+"."+fso.getExtensionName(zip_content.item(i).path)
if (fso.FileExists(fso.Buildpath(percorso,zip_content.item(i).name)+"."+fso.getExtensionName(zip_content.item(i).path))) then
'msgbox "il file esiste, ora lo cancello"
fso.DeleteFile(fso.Buildpath(percorso,zip_content.item(i).name)+"."+fso.getExtensionName(zip_content.item(i).path))
end if
destinazione.copyHere(zip_content.item(i))
next
file.Delete
end if
next
'for each sottocartella in cartella.subfolders
' call estrai(folder.path)
'next
end sub
call estrai("C:\Documents and Settings\Mattia\Desktop\prova")

VBScript to copy file/s beginning with XXX or YYY or ZZZ from directory A to directory B

I have next to zero knowledge on vbs scripting but I have managed to cobble a few together to copy files from one directory to another and delete files in a directory but I've not been able to find anything specifically what I'm now after.
I'm looking to write a vbs script to do the following - copy file/s beginning with XXX or YYY or ZZZ from directory A to directory B.
I've had a look around and cannot quite find what I'm looking for, they all seem far too complex for what I need and involve the latest date or parsing a string within the files etc.
I'm quite sure this is simple but as stated at the top I really do not know what I'm doing so any help would be greatly appreciated.
The following is what I have for copying all files from one directory to another with a progress bar so a amendment to this would be great.
Const FOF_CREATEPROGRESSDLG = &H0&
' copy test 1 to test 2
strTargetFolder = "C:\test2\"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(strTargetFolder)
objFolder.CopyHere "C:\test1\*.*", FOF_CREATEPROGRESSDLG
Not sure as of yet how to get this in one big progress indicator. Currently it will show progress for each individual file.
Const FOF_CREATEPROGRESSDLG = &H0&
strSourceFolder = "C:\test1\"
strTargetFolder = "C:\test2\"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSourceFolder = objFSO.GetFolder(strSourceFolder)
Set objFiles = objSourceFolder.Files
Set objShell = CreateObject("Shell.Application")
Set objTargetFolder = objShell.NameSpace(strTargetFolder)
For Each objSingleFile in objFiles
If (InStr(1,objSingleFile.Name,"xxx",vbTextCompare) = 1) Or _
(InStr(1,objSingleFile.Name,"yyy",vbTextCompare) = 1) Or _
(InStr(1,objSingleFile.Name,"zzz",vbTextCompare) = 1) Then
' The file name starts with one the flagged keywords
objTargetFolder.CopyHere objSingleFile.Path, FOF_CREATEPROGRESSDLG
End If
Next
Keep your strTargetFolder code which is used for the actual copy procedure used at the end of the script. Using the FileSystemObject objFSO we cycle through all the files of the directory c:\test1. Each file name is then checked to see if it starts with either of 3 different strings. The comparison is done using vbTextCompare which essentially has it running case insensitive. If a match is found then, using your original code, copy the file to the target directory with progress.
Currently this is not going to recursively navigate all subfolders for file but you could make a recursive function for that.
Use the FileSystemObject in combination with a regular expression:
src = "C:\test1"
dst = "C:\test2"
Set fso = CreateObject("Scripting.FileSystemObject")
Set re = New RegExp
re.Pattern = "^(XXX|YYY|ZZZ)"
For Each f In fso.GetFolder(src).Files
If re.Test(f.Name) Then f.Copy dst & "\"
Next

Open files with common name part

First of all, please excuse my shortcomings in presenting my issue as I haven't got much knowledge in VBA. Your help would be kindly appreciated.
I am working on a project that would imply putting the content of three different Excel files from three different sub-folders into one Excel file, and then run some macros in order to process the data they contain. Since I've already set the processing macros, my issue relies in importing the content correctly.
The problem I'm facing is that I don't have the exact names of the files I would like to open, and that they would change each month. Therefore, I can't use the "WorkBooks.Open" command that requires a precise name. However, the files have predictable name formats. For instance, one of the sub-folders will be comprised of files named "XXX-jan2013.xls", another one "january2013-XXX" and the last one "XXX-01/2013".
My goal would be to input the month and year manually, for instance “01/2013”, and then open all the files containing "January”, “jan” or “01" in their names.
Here’s what I have so far, with comments:
Sub ChosenDate()
‘It aims at opening a box in which the desired month would be written manually
Dim InputDate As String
‘These are the indications the user will get
InputDate = InputBox(Prompt:="Please choose a month.", _
Title:="Date", Default:="MM/YYYY")
‘In case the person forgets to write what he’s asked to
If InputDate = "MM/YYYY" Or _
InputDate = vbNullString Then
Exit Sub
‘If he does it correctly, I call the second Sub
Else: Call FilesOpening
End If
End Sub
‘So far, everything works fine
Public Sub FilesOpening()
‘This one aims at opening the chosen files
Dim ThisFile As String
Dim Files As String
‘Defining the folder in which the file is, as it can change from a computer to another
ThisFile = ThisWorkbook.Path
‘Here’s where I start struggling and where the macro doesn’t work anymore
‘If I wanted to open all the files of the folder, I would just write that:
Files = Dir(ThisFile & "\*.xls")
‘You never know…
On Error Resume Next
‘Creating the Loop
Do While Files <> vbNullString
Files = Dir
Set wbBook = Workbooks.Open(ThisWorkbook.Path & "\" & Files)
Loop
End Sub
‘But it doesn’t look inside of sub-folders, neither does it consider the date
Sub DataProcess()
‘This one is fine, except I can’t find a way to name the files correctly. Here’s the beginning:
Windows("I don’t know the name.xls").Activate
Sheets("Rapport 1").Select
Cells.Select
Selection.Copy
Windows("The File I Want To Put Data In.xlsm").Activate
Sheets("Where I Want To Put It").Select
Range("A1").Select
ActiveSheet.Paste
Windows("I don’t know the name.xls").Close
‘How can I get the name?
I hope my statement is understandable.
Thank you very much in advance!
Have a nice day,
E.
You need to build a list of the paths and the expected file masks. You can then loop each matching file and do your stuff.
Sub foo()
Dim request As String: request = "01/2013"
'//make a date
Dim asDate As Date: asDate = "01/" & request
Dim dirs(2) As String, masks(2) As String
dirs(0) = "c:\xxx\dir1\"
masks(0) = "*" & Format$(asDate, "mmmmyyyy") & "*.xls"
dirs(1) = "c:\xxx\dir2\"
masks(1) = "*" & Format$(asDate, "mmmyyyy") & "*.xls"
dirs(2) = "c:\xxx\dir3\"
masks(2) = "*" & Format$(asDate, "mmyyyy") & "*.xls"
Dim i As Long
For i = 0 To UBound(dirs)
GetFiles dirs(i), masks(i)
Next
End Sub
Private Function GetFiles(path As String, mask As String)
Dim file As String
'//loop matching files
file = Dir$(path & mask)
Do Until Len(file) = 0
'//process match
process path & file
file = Dir$()
Loop
End Function
Sub process(filePath As String)
MsgBox "processing " & filePath
'workbook.open
End Sub
As "XXX-01/2013" is not a file name I assumed "XXX-012013".
If its another subdirectory just:
dirs(x) = "c:\xxx\dir3\" & Format$(asDate, "mm") & "\"
masks(x) = "*" & year(asDate) & "*.xls"

Resources