从多台计算机同时写入文本文件

时间:2011-12-29 16:48:06

标签: file text vbscript simultaneous

使用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 个答案:

答案 0 :(得分: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是更好的主意。