Jump to content

VBScript remote connection and query to Windows 7 machines


Recommended Posts

Posted

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....

Posted

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 & "."

Posted
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.
Posted

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)

Posted

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 & "."

Posted (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 by umass
Posted
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 #

Posted

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 ]

Posted

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?

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 account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...