umass Posted October 18, 2011 Posted October 18, 2011 Hey all, I have written a script that connects to a computer remotely by using the SWbemLocator and SWbemServices. Given that I'm querying both Windows XP and Windows 7 machines, I have to set the folder directories to C:\Documents and Settings and C:\Users, respectively. The script runs fine for Windows XP machines, but it returns "Path not found" for Windows 7 machines. I have checked and there is a C:\Users directory in the Win7 machines, so I don't know what wrong. I'm thinking that the connection establishment for win7 machines is different from winXP, but I haven't found any other options. Here is a snippet of the code that shows how I'm connecting: Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer _ (ComputerName & "domain", "root\cimv2", "admin", "password") objSWbemServices.Security_.ImpersonationLevel = 3 When I connected to a Win7 machine using the code above to find out what operating system was running on them it worked fine, but when I try to query files and folders, it returns the "Path not found" error. Let me know if you have faced a similar problem, or if you could give me any hints. Thanks....
Steve21 Posted October 18, 2011 Posted October 18, 2011 Can you post the full code, will need that bit really. Thanks, Steve
umass Posted October 18, 2011 Author Posted October 18, 2011 Here it is. Basically what I'm trying to do is to query every audio, video and image file in remote computers that are listed in the Active Directory (Windows Server 2008). The full code is bellow. Option Explicit Dim strComputer, objOut, totalSize Dim strFolderToSearch, objFso, objFolder, SubFolder Dim strXP, str7, colOperatingSystems, stringArray, objSWbemLocator, objSWbemServices Dim strComputerArray, FileTypeArray Dim objConnection, objCommand, objRecordSet Dim searchStr, Folder Dim FileType(36), Ftype, objOut2 Dim objPing, objStatus, stat const bytesToKB = 1024 const bytesToMB = 1048576 const bytesToGB = 1073741824 Const ADS_SCOPE_SUBTREE = 2 strXP = "XP" str7 = "7" 'FILE TYPES FOR AUDIO, VIDEO AND IMAGE FileType(0) = "WMA" FileType(1) = "MP3" FileType(2) = "AWB" FileType(3) = "FLAC" FileType(4) = "M4P" FileType(5) = "OGG" FileType(6) = "RAW" FileType(7) = "WAV" FileType(8) = "AAC" FileType(9) = "ALAC" FileType(10) = "MPC" FileType(11) = "3GP" FileType(12) = "MPEG" FileType(13) = "MPG" FileType(14) = "IFF" FileType(15) = "JPEG" FileType(16) = "JFIF" FileType(17) = "PNG" FileType(18) = "GIF" FileType(19) = "JPG" FileType(20) = "TIFF" FileType(21) = "BMP" FileType(22) = "PSD" FileType(23) = "PGF" FileType(24) = "TGA" FileType(25) = "PSP" FileType(26) = "WMV" FileType(27) = "ASF" FileType(28) = "ASX" FileType(29) = "3G2" FileType(30) = "FLV" FileType(31) = "SWF" FileType(32) = "AVI" FileType(33) = "ALAW" FileType(34) = "ULAW" FileType(35) = "MKV" Set objFso = CreateObject("Scripting.FileSystemObject") Set objOut = objFso.CreateTextFile("Media.csv", True) Set objOut2 = objFso.CreateTextFile("os.txt", True) Call GetCompName() Function GetCompName() Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Provider" Set objCOmmand.ActiveConnection = objConnection objCommand.CommandText = _ "Select Name, Location from 'LDAP://domain' " _ & "Where objectClass='computer'" objCommand.Properties("Page Size") = 1000 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE Set objRecordSet = objCommand.Execute objRecordSet.MoveFirst searchStr = "str" Do Until objRecordSet.EOF if InStr(lcase(objRecordSet.Fields("Name").Value), lcase(searchStr)) = 1 then strComputer = objRecordSet.Fields("Name").Value Call Check_comp_status(strComputer) if (stat=1) then Call checkOS(strComputer) else objOut.WriteLine strComputer & " machine is offline." end if End if stat = 0 'reset stat objRecordSet.MoveNext Loop objOut.WriteLine "***End of List***" Wscript.Echo "DONE!!" wscript.quit End Function Function Check_comp_status(ComputerName) Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._ ExecQuery("select Replysize from Win32_PingStatus where address = '" & ComputerName & "'") For Each objStatus in objPing If IsNull(objStatus.ReplySize) Then stat = 0 Else stat = 1 End If Next Set objPing=Nothing Set objStatus=Nothing End Function Function checkOS(ComputerName) 'Check OS of every computer name, set strFolderToSearch to appropriate directory 'then call SearchDocs with appropriate computerName and strFolderToSearch parameters Dim objOperatingSystem Dim objOS Dim counter Dim numerr, abouterr On Error Resume Next Err.Raise 6 numerr = err.number abouterr = Err.description Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer _ (ComputerName & "domain", "root\cimv2", "admin", "password") objSWbemServices.Security_.ImpersonationLevel = 3 If Err.Number Then objOut.WriteLine "An error occurred with " & ComputerName _ & ": error = " & abouterr & " number = " & err.number Err.Clear End if Set colOperatingSystems = objSWbemServices.ExecQuery _ ("Select * from Win32_OperatingSystem") For Each objOperatingSystem in colOperatingSystems objOS = objOperatingSystem.Caption Next stringArray = Split(objOS) for counter=0 to UBound(stringArray) if (stringArray(counter)=strXP) then Folder = "C:\Documents and Settings" objOut2.WriteLine ComputerName & " " & stringArray(counter) & " " & Folder Exit for End if if (stringArray(counter)=str7) then Folder = "C:\Users" objOut2.WriteLine ComputerName & " " & stringArray(counter) & " " & Folder Exit for End if next Call SearchDocs(Folder, ComputerName) End Function Function SearchDocs(FolderName, ComputerName) Dim FileSize, counter, count, colFiles, objFile FileSize = 0 strFolderToSearch = FolderName Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & strFolderToSearch & "'} Where " _ & "ResultClass = CIM_DataFile") Set objFolder = objFso.GetFolder(strFolderToSearch) Set colFiles = objFolder.Files counter = 0 For count = 0 to Ubound(FileType)-1 Ftype = FileType(count) 'On Error Resume Next For Each objFile In colFiles REM If Err.Number Then REM continue REM End if if UCase(objFso.GetExtensionName(objFile.name)) = FileType(count) Then 'Wscript.Echo "found " & objFile.Name & " in" & Subfolder.Path & "." counter = counter + 1 FileSize = FileSize + objFile.Size 'Wscript.Echo "found " & objFile.name & " in " & objFolder.Path & " ." End if Next if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine ComputerName & "," & FileType(count) & "," & counter _ & "," & objFolder.Path & "," & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine ComputerName & "," & FileType(count) & "," & counter _ & "," & objFolder.Path & "," & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine ComputerName & "," & FileType(count) & "," & counter _ & "," & objFolder.Path & "," & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine ComputerName & "," & FileType(count) & "," & counter _ & "," & objFolder.Path & "," & totalSize & " GB" end if end if counter=0 ShowSubfolders objFso.GetFolder(strFolderToSearch) Next End Function Sub ShowSubFolders(Folder) Dim FileSize, counter, colFiles, objFile For Each Subfolder in Folder.SubFolders Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & Folder & "'} Where " _ & "ResultClass = CIM_DataFile") counter = 0 FileSize = 0 'Wscript.Echo Subfolder.Path Set objFolder = objFso.GetFolder(Subfolder.Path) Set colFiles = objFolder.Files On Error Resume Next For Each objFile in colFiles If Err.Number Then continue End if if UCase(objFso.GetExtensionName(objFile.name)) = Ftype Then 'Wscript.Echo "found " & objFile.Name & " in " & Subfolder.Path & "." 'totalSize = objFso.GetFile(Subfolder.Path & "\" & objFile.Name) FileSize = FileSize + objFile.Size counter = counter + 1 End if Next if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine strComputer & "," & Ftype & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine strComputer & "," & Ftype & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine strComputer & "," & Ftype & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine strComputer & "," & Ftype & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " GB" end if end if counter = 0 ShowSubFolders Subfolder Next End Sub 'Wscript.Echo "total number of " & FileType & " files found = " & counter & "."
SYNACK Posted October 18, 2011 Posted October 18, 2011 Looks like its digging through the user folder in 7, what user context are you running it in? By default I think that even admin users are locked out of user folders. Your script may need to take ownership and add the running account to the subfolder permissions. It may work running as a member of the backup operators group.
umass Posted October 19, 2011 Author Posted October 19, 2011 Hey Synack...thanks for your response. What do you mean by "what user context are you running it in"? And how do I go about having my script take ownership, or running it as a member of the backup operators group? (I'm new to VBScript btw...so pardon my ignorance)
umass Posted October 19, 2011 Author Posted October 19, 2011 Just an update: I found a huge mistake. I found out that I can't just use FSO to get into the folder of a remote computer.I read some documentations and found out that I have to use administrative shares such as C$, to get the folder information. I wrote a test code and it seems to be working fine up until the following line "For each objFile in colFiles" in the ShowSubFolders sub. The error was Error:0x8007013D, Code:8007013D, Source:(null). Here is the code: Option Explicit Dim strComputer, objSWbemLocator, objFile, objOut, totalSize, FileSize Dim counter, strFolderToSearch, FileType, objFso, objFolder, SubFolder Dim strXP, str7, objSWbemServices Dim strComputerArray, FileTypeArray const bytesToKB = 1024 const bytesToMB = 1048576 const bytesToGB = 1073741824 Dim M, F, C, L, T, P M = "Machine" F = "File Type" C = "Count" L = "Directory" T = "Total Size" 'will change strComputer to an array that stores all the finaid computer names 'then call SearchDocs with each strComputer array index strComputer = "compName" 'Will create an array of all kinds of picture and media files then send it as a parameter 'to searchDocs with each FileType array index FileType = "MP3" Set objFso = CreateObject("Scripting.FileSystemObject") Set objOut = objFso.CreateTextFile("Media2.csv", True) objOut.WriteLine M & "," & F & "," & C & "," & L & "," & T Call SearchDocs(strComputer) Function SearchDocs(ComputerName) FileSize = 0 Dim colFiles strFolderToSearch = "Users" Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer _ (ComputerName , "root\cimv2", "admin", "password") objSWbemServices.Security_.ImpersonationLevel = 3 Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & strFolderToSearch & "'} Where " _ & "ResultClass = CIM_DataFile") Set objFolder = objFso.GetFolder("\\compName\C$\" & strFolderToSearch) Set colFiles = objFolder.Files counter = 0 For Each objFile In colFiles if UCase(objFso.GetExtensionName(objFile.name)) = FileType Then 'Wscript.Echo "found " & objFile.Name & " in" & Subfolder.Path & "." counter = counter + 1 FileSize = FileSize + objFile.Size Wscript.Echo "found " & objFile.name & " in " & objFolder.Path & " ." End if Next if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " GB" end if end if ShowSubfolders objFso.GetFolder("\\compName\C$\" & strFolderToSearch) End Function Sub ShowSubFolders(Folder) Dim colFiles For Each Subfolder in Folder.SubFolders Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & Folder & "'} Where " _ & "ResultClass = CIM_DataFile") counter = 0 FileSize = 0 Wscript.Echo Subfolder.Path Set objFolder = objFso.GetFolder(Subfolder.Path) Set colFiles = objFolder.Files 'On Error Resume Next For Each objFile in colFiles REM If Err.Number Then REM continue REM End if if UCase(objFso.GetExtensionName(objFile.name)) = FileType Then Wscript.Echo "found " & objFile.Name & " in " & Subfolder.Path & "." 'totalSize = objFso.GetFile(Subfolder.Path & "\" & objFile.Name) FileSize = FileSize + objFile.Size counter = counter + 1 End if Next if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " GB" end if end if ShowSubFolders Subfolder Next End Sub 'wscript.quit 'Wscript.Echo "total number of " & FileType & " files found = " & counter & "."
Arthur Posted October 19, 2011 Posted October 19, 2011 ^ Would it be possible to use CODE tags in your posts?
mac_shinobi Posted October 19, 2011 Posted October 19, 2011 ^ Would it be possible to use CODE tags in your posts? Edit nevermind yeah code tags lol. Also commenting your code would be good
umass Posted October 19, 2011 Author Posted October 19, 2011 (edited) Yeah i should definitely do that. I'll comment it and I'll re-post it. I actually have a bunch of irrelevant comments there, but I'll clean it up a little. What do you mean by code tags though? (sry im a newb here...) Thanks Edited October 19, 2011 by umass
mac_shinobi Posted October 19, 2011 Posted October 19, 2011 Yeah i should definitely do that. I'll comment it and I'll re-post it. I actually have a bunch of irrelevant comments there, but I'll clean it up a little. What do you mean by code tags though? (sry im a newb here...) Thanks when you post code on the forum it helps if you use the tags so when you post it up it looks neater and easier to read ie [ CODE ]code goes here [ /CODE ] The code button in advanced view has the hash symbol ie #
umass Posted October 19, 2011 Author Posted October 19, 2011 Ok. I've added some comments, hope it helps understanding the flow of the code. [ CODE ] Option Explicit Dim strComputer, objSWbemLocator, objFile, objOut, totalSize, FileSize Dim counter, strFolderToSearch, FileType, objFso, objFolder, SubFolder Dim strXP, str7, objSWbemServices Dim strComputerArray, FileTypeArray 'variables used for computing file size const bytesToKB = 1024 const bytesToMB = 1048576 const bytesToGB = 1073741824 Dim M, F, C, L, T, P M = "Machine" F = "File Type" C = "Count" L = "Directory" T = "Total Size" strComputer = "finaid254" 'remote computer name to be queried FileType = "MP3" 'file type to look for Set objFso = CreateObject("Scripting.FileSystemObject") Set objOut = objFso.CreateTextFile("Media2.csv", True) objOut.WriteLine M & "," & F & "," & C & "," & L & "," & T Call SearchDocs(strComputer) Function SearchDocs(ComputerName) FileSize = 0 Dim colFiles strFolderToSearch = "Users" 'remote computer directory to be queried 'Connect to remote computer Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer _ (ComputerName, "root\cimv2", "SARIS\faadmin", ";4y'#h4ny`") objSWbemServices.Security_.ImpersonationLevel = 3 'set folder to be queried Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & "\\" & ComputerName & "\C$\" & strFolderToSearch & "'} Where " _ & "ResultClass = CIM_DataFile") 'Get folder with Administrative share 'C$' Set objFolder = objFso.GetFolder("\\" & ComputerName & "\C$\" & strFolderToSearch) Set colFiles = objFolder.Files counter = 0 For Each objFile In colFiles if UCase(objFso.GetExtensionName(objFile.name)) = FileType Then 'Wscript.Echo "found " & objFile.Name & " in" & Subfolder.Path & "." counter = counter + 1 'count how many files of a certain extension there are FileSize = FileSize + objFile.Size 'calculate total size of all files Wscript.Echo "found " & objFile.name & " in " & objFolder.Path & " ." End if Next 'This if-statement will just write the computername, filetype, file count, the directory 'and the total size to an output file if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine ComputerName & FileType & counter _ & objFolder.Path & totalSize & " GB" end if end if ShowSubfolders objFso.GetFolder("\\finaid254\C$\" & strFolderToSearch) End Function 'This Sub traverses all subfolders of a primary directory, counts files, computes 'tota size per location and writes all the data to an output file Sub ShowSubFolders(Folder) Dim colFiles For Each Subfolder in Folder.SubFolders Set colFiles = objSWbemServices.ExecQuery _ ("ASSOCIATORS OF {Win32_Directory.Name=" & _ "'" & Folder & "'} Where " _ & "ResultClass = CIM_DataFile") counter = 0 FileSize = 0 Wscript.Echo Subfolder.Path Set objFolder = objFso.GetFolder(Subfolder.Path) Set colFiles = objFolder.Files For Each objFile in colFiles if UCase(objFso.GetExtensionName(objFile.name)) = FileType Then Wscript.Echo "found " & objFile.Name & " in " & Subfolder.Path & "." FileSize = FileSize + objFile.Size counter = counter + 1 End if Next if (counter>0) and (FileSize>0) then if (FileSize < bytesToKB) then totalSize = FileSize objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " bytes" end if if (FileSize >= bytesToKB) and (FileSize < bytesToMB) then totalSize = FileSize / bytesToKB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " KB" end if if (FileSize >= bytesToMB) and (FileSize < bytesToGB) then totalSize = FileSize / bytesToMB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " MB" end if if (FileSize >= bytesToGB) then totalSize = FileSize / bytesToGB objOut.WriteLine strComputer & "," & FileType & "," & counter _ & "," & Subfolder.Path & "," & totalSize & " GB" end if end if ShowSubFolders Subfolder Next End Sub [ /CODE ]
umass Posted October 20, 2011 Author Posted October 20, 2011 hey, Some updates: Everything is working well now. I've used the administrative share $C along with the computer name and directory. Also, I noticed that since I'm running the script from the command prompt, if I don't run the cmd as an administrator it brings me back to the "Path not found" issue for some reason. My only issue now is Time Efficiency. The full algorithm that searches for all sorts of files is a O(n^3) complexity and of course it will take a very long time to query about 111 computers. The algorithm is that complex because of the number of loops I'm using. For that reason I wanted to ask, if I tell the script to search for a specific file type, do I have to tell it to search folders and subfolders, or would it do it automatically?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now