2011-12-29 52 views
0

使用VBScript,是否有任何方法可以允許多個計算機同時寫入文本文件?我需要同時從多臺計算機運行腳本。該腳本將執行DEFRAG並將結果保存到文本文件。之後,腳本將從DEFRAG日誌文件中讀取數據,並提取碎片百分比,然後將其寫入另一個MASTER日誌文件,該文件旨在包含企業中每臺計算機的這些結果。如果我一次只能從一臺計算機運行腳本,那麼一切都可以找到並且很花哨。但是,一旦我使用分發點將腳本導出到企業中,該腳本就可以正常工作,直到多臺計算機同時嘗試訪問MASTER日誌文件爲止。那時候我遇到了訪問被拒絕的錯誤等等。這裏就是我這麼遠......從多臺計算機同時寫入文本文件

strDrivePreCheckStarted = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

a=("===================================================================================") 
b=(" Script started on " & strDrivePreCheckStarted) 

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") 
Set colSettings = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem", , 48) 
For Each objComputer in colSettings 
    CompNam = objComputer.Name 
    If CompNam = "" Then 
     CompNam = "ComputerNameNotFound" 
    End If 
    CompMfr = replace(objComputer.Manufacturer,",","") 
    If CompMfr = "" Then 
     CompMfr = "ComputerMfrNotFound" 
    End If 
    CompMdl = objComputer.Model 
    If CompNam = "" Then 
     CompNam = "ComputerModelNotFound" 
    End If 
Next 

Set dClient = GetObject("winmgmts://" & CompNam & "/root/ccm:SMS_Client") 
Set result = dClient.ExecMethod_("GetAssignedSite") 
mClient = result.sSiteCode 
If mClient = "OLD" Then 
    mClient = "SMS" 
End If 
If mClient = "NEW" Then 
    mClient = "SCCM" 
End If 
If mClient = "" Then 
    mClient = "UNKNOWN" 
End If 

c=(" Computer: " & "[" & mClient & "] " & CompNam & " (" & CompMfr & " " & CompMdl & ")") 

Set FSO = CreateObject("Scripting.FileSystemObject") 
Set wshShell = CreateObject("WScript.Shell") 
Set objShell = WScript.CreateObject("WScript.Shell") 
Set strWinDir = FSO.GetSpecialFolder(0) 
Set strSys32 = FSO.GetSpecialFolder(1) 
Set strTempDir = FSO.GetSpecialFolder(2) 
strLogsDir = "\\fileserver\shared\logs\" 

Const ForReading = 1, ForWriting = 2, ForAppending = 8 
Const OverwriteExisting = False 

If FSO.FileExists(strLogsDir & CompNam & ".TXT") Then 
    WScript.Quit 
Else 
    If FSO.FileExists(strLogsDir & CompNam & "_CHKDSK.LOG") Then 
     WScript.Quit 
    Else 
     If FSO.FileExists(strLogsDir & CompNam & "_DEFRAG.LOG") Then 
      WScript.Quit 
     Else 

      strCHKDSKStarted = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

      d=("  CHKDSK Started: " & strCHKDSKStarted) 

      If FSO.FileExists(strSys32 & "\chkdsk.exe") Then 
       strCHKDSKReturn = objShell.Run("%COMSPEC% /c chkdsk.exe C: > " & chr(34) & strLogsDir & CompNam & "_CHKDSK.LOG" & chr(34), 0, True) 
      End If 

      If FSO.FileExists(strLogsDir & CompNam & "_CHKDSK.LOG") Then 
       Set ChkDskLog = FSO.OpenTextFile(strLogsDir & CompNam & "_CHKDSK.LOG", ForReading, True) 
       Do While ChkDskLog.AtEndOfStream <> True 
        Curline = ChkDskLog.ReadLine 
        If InStr(Curline, "KB in bad sectors.") Then 
         Curline = Trim(Curline) 
         strKBpos = InStr(1, Curline, "KB")-2 
         strBadKB = Left(Curline, strKBpos) 
         strBadKB = Trim(strBadKB) 
         If strBadKB > 0 Then 
          ChkDskFail = "Failed" 
          e=("  " & strBadKB & "KB Of Bad Sectors Found In Used Space") 
          f=("  Drive has Failed Integrity Check") 
         Else 
          ChkDskFail = "Passed" 
          e=("  " & strBadKB & "KB Of Bad Sectors Found In Used Space") 
          f=("  Drive has Passed Integrity Check") 
         End If 
        End If 
       Loop 
       If strBadKB = "" Then 
        ChkDskFail = "Failed" 
        e=("  Check Disk Log Existed But Was Incomplete: " & Date & " @ " & Time) 
        f=("  Drive has Failed Integrity Check") 
       End If 
      Else 
       ChkDskFail = "Passed" 
       e=("  No Bad Sectors Found in Used Space") 
       f=("  Drive has Passed Integrity Check") 
      End If 
      ChkDskLog.Close 

      strCHKDSKFinished = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

      g=("  CHKDSK Finished: " & strCHKDSKFinished) 

      strDEFRAGStarted = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

      h=("  DEFRAG Started: " & strDEFRAGStarted) 

      If FSO.FileExists(strSys32 & "\defrag.exe") Then 
       strDEFRAGReturn = objShell.Run("%COMSPEC% /c defrag.exe C: -a -v > " & chr(34) & strLogsDir & CompNam & "_DEFRAG.LOG" & chr(34), 0, True) 
      End If 

      If FSO.FileExists(strLogsDir & CompNam & "_DEFRAG.LOG") Then 
       Set DefragLog = FSO.OpenTextFile(strLogsDir & CompNam & "_DEFRAG.LOG", ForReading, True) 
       Do While DefragLog.AtEndOfStream <> True 
        CurLine = DefragLog.ReadLine 
        If InStr(CurLine, "Total fragmentation") Then 
         FragPosition = InStr(1,CurLine," %",1)-2 
         CurLine = CurLine 
         strFragAmount = Right(CurLine,4) 
         strFragAmount = Left(strFragAmount,2) 
         strFragAmount = Ltrim(strFragAmount) 
        End If 
       Loop 
      Else 
       DefragFail = "Failed" 
       i=("  Log File Could not be Located. Please try Again.") 
       j=("  Drive has Passed Defragmentation Check") 
      End If 
      If strFragAmount = "" Then 
       DefragFail = "Failed" 
       i=("  An Unknown Error has Occured. Please try Again.") 
       j=("  Run 'DEFRAG -v' from this machine manually.") 
      Else 
       If strFragAmount < 30 Then 
        DefragFail = "Passed" 
        i=("  Drive is " & strFragAmount & "% Fragmented") 
        j=("  Drive has Passed Defragmentation Check") 
       End If 
       If strFragAmount >= 30 Then 
        DefragFail = "Failed" 
        i=("  Drive is " & strFragAmount & "% Fragmented") 
        j=("  Drive has Failed Defragmentation Check") 
       End If 
      End If 
      DefragLog.Close 

      strDEFRAGFinished = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

      k=("  DEFRAG Finished: " & strDEFRAGFinished) 

      strDrivePreCheckFinished = (Year(Date) & "-" & AEZiR(Month(Date)) & "-" & AEZiR(Day(Date)) & " @ " & AEZiR(Hour(Time)) & ":" & AEZiR(Minute(Time)) & ":" & AEZiR(Second(Time))) 

      l=(" Script finished on " & strDRIVEPreCheckFinished) 
      m=("===================================================================================") 

      Set TXTLog = FSO.CreateTextFile(strLogsDir & CompNam & ".TXT", True) 
      TXTLog.WriteLine(strDrivePreCheckStarted & "," & mClient & "," & CompNam & "," & CompMfr & "," & CompMdl & "," & strCHKDSKStarted & "," & strBadKB & "KB" & "," & ChkDskFail & "," & strCHKDSKFinished & "," & strDEFRAGStarted & "," & strFragAmount & "%" & "," & DefragFail & "," & strDEFRAGFinished & "," & strDrivePreCheckFinished) 
      TXTLog.Close 

      If FSO.FileExists(strLogsDir & "_FDE.CSV") Then 
       Set CSVLog = FSO.OpenTextFile(strLogsDir & "_FDE.CSV", ForAppending, True) 
       CSVLog.WriteLine(strDrivePreCheckStarted & "," & mClient & "," & CompNam & "," & CompMfr & "," & CompMdl & "," & strCHKDSKStarted & "," & strBadKB & "KB" & "," & ChkDskFail & "," & strCHKDSKFinished & "," & strDEFRAGStarted & "," & strFragAmount & "%" & "," & DefragFail & "," & strDEFRAGFinished & "," & strDrivePreCheckFinished) 
      Else 
       Set CSVLog = FSO.CreateTextFile(strLogsDir & "_FDE.CSV", True) 
       CSVLog.WriteLine("Pre-Check Started,Management Client,Asset Tag,Computer Manufacturer,Computer Model,CHKDSK Started,CHKDSK Bad Sectors,CHKDSK Results,CHKDSK Finished,DEFRAG Started,DEFRAG Amount,DEFRAG Results,DEFRAG Finished,Pre-Check Finished") 
       CSVLog.WriteLine(strDrivePreCheckStarted & "," & mClient & "," & CompNam & "," & CompMfr & "," & CompMdl & "," & strCHKDSKStarted & "," & strBadKB & "KB" & "," & ChkDskFail & "," & strCHKDSKFinished & "," & strDEFRAGStarted & "," & strFragAmount & "%" & "," & DefragFail & "," & strDEFRAGFinished & "," & strDrivePreCheckFinished) 
      End If 
      CSVLog.Close 

      If FSO.FileExists(strLogsDir & "_FDE.LOG") Then 
       Set InstallLog = FSO.OpenTextFile(strLogsDir & "_FDE.LOG", ForAppending, True) 
       InstallLog.WriteLine(b) 
       InstallLog.WriteLine(c) 
       InstallLog.WriteLine(d) 
       InstallLog.WriteLine(e) 
       InstallLog.WriteLine(f) 
       InstallLog.WriteLine(g) 
       InstallLog.WriteLine(h) 
       InstallLog.WriteLine(i) 
       InstallLog.WriteLine(j) 
       InstallLog.WriteLine(k) 
       InstallLog.WriteLine(l) 
       InstallLog.WriteLine(m) 
      Else 
       Set InstallLog = FSO.CreateTextFile(strLogsDir & "_FDE.LOG", True) 
       InstallLog.WriteLine(a) 
       InstallLog.WriteLine(b) 
       InstallLog.WriteLine(c) 
       InstallLog.WriteLine(d) 
       InstallLog.WriteLine(e) 
       InstallLog.WriteLine(f) 
       InstallLog.WriteLine(g) 
       InstallLog.WriteLine(h) 
       InstallLog.WriteLine(i) 
       InstallLog.WriteLine(j) 
       InstallLog.WriteLine(k) 
       InstallLog.WriteLine(l) 
       InstallLog.WriteLine(m) 
      End If 
      InstallLog.Close 

      FSO.DeleteFile(strLogsDir & CompNam & "_CHKDSK.LOG") 
      FSO.DeleteFile(strLogsDir & CompNam & "_DEFRAG.LOG") 

     End If 
    End If 
End If 

Function AEZiR(plngValue) 
    Dim pstrValue 
    Dim plngChars 
    Dim i 
    pstrValue = CStr(plngValue) 
    plngChars = Len(pstrValue) 
    If plngChars < 2 Then 
     For i = 1 to plngChars Step -1 
      pstrValue = "0" & pstrValue 
     Next 
    End If 
    AEZiR = pstrValue 
End Function 

我缺少什麼?這個任務甚至可以用VBScript嗎?先謝謝你。

回答

1

既不VBScript中,也不FileSystemObject對象提供鎖定,有人/別的東西已經做到這一點:

  • 一個[腳本]語言與正確的文件鎖
  • 數據存儲(DBMS),允許同時進行訪問
  • 誰使用信號量(如重命名的文件)程序員來控制文件訪問

在我看來,第三個選項是最差的,因爲 程序員必須做好所有的工作,並採取所有的風險/責任 。使用數據庫將解決開箱即用的訪問控制問題;使用合適的語言將允許標準/非破解 解決方案。

但是,如果你喜歡住在一個有趣的時代 - 這是 代碼結構我想嘗試逃脫:

While it make sense to continue (# of tries, timeout, successfully written) 
    rename FileIsFree.log to FileIsLocked.log 
    If success 
    open FileIsLocked.log 
    write to FileIsLocked.log 
    close FileIsLocked.log 
    rename FileIsLocked.log to FileIsFree.log 
    break/exit 
    End If 
End While 
If Not successfully written 
    Panic 
End If 

新增: 有些耐人尋味: discussion code

我希望你能得出結論,使用DBMS是更好的主意。

+0

首先,感謝您的超快速回復!所以,你提到的最後一個選項似乎是最簡單的方法。然而,這仍然允許腳本運行,然後等待(或類似的東西),並檢查是否可以寫入當前打開的文件,然後完成並關閉? – 2011-12-29 18:15:42

+0

您能否詳細說明上述結構?我真的只是在學習vbscript。再次感謝你。 – 2011-12-29 20:45:40

相關問題