Ask:
Hello, Scripting Guy! How do I read a text file on a remote computer?
--BM
For:
Hello, BM. We have to admit that we are using you and your problems to achieve our own evil purposes. Earlier this week we answered questions about how to read the last line of a set of text files; In the answer, we promised to explain how to use FileSystemObject to perform the same function on a remote computer. This is harmless, just to preserve the spirit of this column, and unless someone raises a question about how to handle a text file on a remote computer, we will not respond. So we chose your question.
So, yes, we're using you. But if you think of the pros, your questions are answered. In fact, let's take a look at your question first.
As you know, FileSystemObject (the object used to read and write text files) was originally used for local use, and in fact, any material you read about FileSystemObject will almost painstakingly point out that the object cannot be used on a remote computer. Although this is not entirely true: that is because FileSystemObject can use UNC paths. Assume that the file to be read is in the File share directory (\\atl-fs-01\public\myfile.txt). In this case, opening and reading a text file is as simple as the following code:
Copy Code code as follows:
Const ForReading = 1
Set objFSO = CreateObject ("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
("\\atl-fs-01\public\myfile.txt", ForReading)
StrContents = Objtextfile.readall
Objtextfile.close
WScript.Echo StrContents
As you can see, we first define a constant named ForReading and set its value to 1. The FileSystemObject reference is then created and the OpenTextFile method is invoked, passing two arguments: the UNC path to the file to be manipulated and the constant ForReading. At this point we can do whatever we need for the file: give you a simple example of manipulating a text file: Call the ReadAll method to read the entire contents of a file into a variable named strContents. Then close the file and echo the strContents value, that's it.
Currently, this code works well as long as the file to be operated is in a shared folder. But what if the file is not in a shared folder? In this case, only administrative shares (such as C $) can be used. The following script can read the file MyFile.txt even if the folder C:\Public has not been shared:
Copy Code code as follows:
Const ForReading = 1
Set objFSO = CreateObject ("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile _
("\\atl-fs-01\C$\public\myfile.txt", ForReading)
StrContents = Objtextfile.readall
Objtextfile.close
WScript.Echo StrContents
If you don't use administrative shares, there's probably no way. (unless you really want to do something crazy, like using a Wshcontroller object.) But that will be another matter. )
And that leads to our ulterior motives: how do I traverse all the files in a remote folder and use FileSystemObject to open and read each file? Well, look at the following method:
Copy Code code as follows:
Const ForReading = 1
Set objFSO = CreateObject ("Scripting.FileSystemObject")
StrComputer = "atl-fs-01"
Set objWMIService = GetObject ("winmgmts:\\" & StrComputer & "\root\cimv2")
Set Colfilelist = objWMIService.ExecQuery _
("Associators of {win32_directory.name= ' C:\Logs '} Where" _
& "ResultClass = Cim_datafile")
For each objfile in Colfilelist
strFilePath = "\" & StrComputer & "\c$\logs\" & _
Objfile.filename & "." & Objfile.extension
Set objTextFile = objFSO.OpenTextFile (strFilePath, ForReading)
StrContents = Objtextfile.readall
WScript.Echo StrContents
Objtextfile.close
Next
The purpose of this code is to connect to the remote computer atl-fs-01 and retrieve a collection of all the files in the folder C:\Logs. The tricky point is to build the path to each file because we need to use an administrative shared path similar to the following:
\\atl-fs-01\C$\Logs\MyFile.log
To build the path, we'll use some WMI and hard coded each:
strFilePath = "\" & StrComputer & "\c$\logs\" & _
Objfile.filename & "." & Objfile.extension
And what we're going to do is:
• Start with a pair: \
• Add computer name: \\atl-fs-01
• Add a \ and manage shared paths C$\logs\:\\atl-fs-01\c$\logs\
• Add WMI FileName Property (contains only the filename section, excluding file extensions): \\atl-fs-01\C$\Logs\MyFile
• Add a period between the file name and the file name extension (because the period is not part of the WMI Extension property): \\atl-fs-01\C$\Logs\MyFile.
• Add WMI Properties Extension:\\atl-fs-01\c$\logs\myfile.log
This is slightly more complicated, but it builds the UNC path we need. Also, it replaces the new filename and the new file extension (the Computer name and folder path will never change) each time the loop completes. So we can finally open (and read) each file in the remote folder.
By the way, thanks to BM, thank you for letting us take advantage of your problem. We owe you a favor!