嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎蒞臨 TechNet 專欄,Microsoft Scripting Guys 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

還有,別忘了瞧瞧全新經過改良的嗨,Scripting Guy!過往文件

今天的問題:如何讀取遠端電腦上的文字檔?


如何讀取遠端電腦上的文字檔?

嗨,Scripting Guy!如何讀取遠端電腦上的文字檔?

-- BM

BM,您好。我們要向您告解一下:我們利用了您和您的問題來滿足我們邪惡的目的。本週稍早,我們回答了一個有關讀取一組文字檔中最後一行的問題,在我們的解答當中,我們保證會說明要如何使用 FileSystemObject 在遠端電腦上執行相同的技巧。這都還好,問題出在,為了保有這個專欄的精神,我們得等到有人問要怎麼處理遠端電腦上的文字檔案才能履行諾言。我們於是選上您的問題。

所以,我們的確是在利用您。可是往好的方面想,至少您會得到解答。就讓我們先從您的問題開始。

如您所知,FileSystemObject (用來讀取和寫入文字檔的物件) 是設計用在本機上,實際上,您讀到關於 FileSystemObject 的一切大都殘酷地指出您不能在遠端電腦上使用此物件。結果,這並不全真:因為 FileSystemObject 能夠使用 UNC 路徑。假設您想要讀取的檔案位於檔案共用上 (\\atl-fs-01\public\myfile.txt),這樣一來,開啟和讀取文字檔就像這樣簡單:

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

如您所見,我們開始先定義一個叫做 ForReading 的常數,並將值設為 1。跟著建立 FileSystemObject 參考,並呼叫 OpenTextFile 方法,來傳遞兩個參數:即剛剛提到的檔案的 UNC 路徑,還有 ForReading 常數。此時我們可以任意處置這個檔案:為了給您一個使用文字檔的例子,我們呼叫 ReadAll 方法將檔案的整個內容讀入一個叫做 strContents 的變數。接著我們關閉該檔案,回應 strContents 的值,就這樣。

只要所提的檔案是位於共用資料夾中,一切都不會有問題。但要是檔案不是在共用資料夾中呢?要是這樣,您唯一的資源就是使用系統管理共用 (像 C$)。這個指令碼會讀取 MyFile.txt 檔案,即使 C:\Public 資料夾未共用也一樣:

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

假如您沒有使用系統管理共用,那麼可能就沒輒了 (除非您豁出去,使用 WSHController 物件,不過今天先不討論)。

這讓我們想到接下來的意圖:我們要如何循環處理遠端資料夾中的所有檔案,然後使用 FileSystemObject 來開啟和讀取每個檔案呢?這是其中一個方法:

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

我們在這邊所做的,是連接到 atl-fs-01 遠端電腦,並擷取 C:\Logs 資料夾中所有檔案的集合。耍技巧的地方是在建構每個檔案的路徑,因為我們必須使用類似下面的系統管理共用路徑:

\\atl-fs-01\C$\Logs\MyFile.log

為了建構路徑,我們用點 WMI並寫死系統管理共用路徑C$\Logs\:

strFilePath = "\\" & strComputer & "\C$\Logs\" & _
    objFile.FileName & "." & objFile.Extension

我們所做的是:

  • 以兩個 \ 為開頭- \\
  • 加入電腦的名稱:\\atl-fs-01
  • 加入一個 \ 和系統管理共用路徑 C$\Logs\:\\atl-fs-01\C$\Logs\
  • 加入 WMI FileName 屬性 (這只是名稱,減去副檔名):\\atl-fs-01\C$\Logs\MyFile
  • 在檔名和副檔名之間加入英文句號 (因為句號不是 WMI Extension 屬性的一部分):\\atl-fs-01\C$\Logs\MyFile.
  • 加入 WMI 的屬性 Extension\\atl-fs-01\C$\Logs\MyFile.log

這有點複雜,不過會建置我們所需的 UNC 路徑。另外,每次跑迴圈,它都會取代新檔名和新的副檔名 (電腦名稱和資料夾路徑永遠不會變)。因此我們最後就能開啟 (並讀取) 遠端資料夾中的每個檔案了。

順帶一提,感謝您讓我們利用您的問題,BM。我們欠您一次人情!


如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首