0

I am writing a script to write event log information to a csv. My script was working before. But I changed some stuff, which shouldn't have any effect on writing to the csv. I have tried writing to unicode and to ASCII, based on some research I did on the internet about this issue. Neither makes a difference. The odd thing is that I use the same code later in my script to write other logs (I first write system logs, then I write application logs, etc.), and it works perfectly there. The code I am using is temporary, as I have not got around to writing a way to delete carriage returns from messages (which causes issues with importing the CSV to Excel). So it might fix itself once I do that. But it seems like it is a larger issue than that. Here is the script up until it moves on to other logs:

Set wshShell = WScript.CreateObject( "WScript.Shell" )
strComputerName = wshShell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )

strComputer = "."
strType = "Error"
strPath = "T:\IT resources\Event Logs\ErrorLog" & strComputerName & ".csv"

'Script to convert UTC to human readable. From Script Repository.

Function WMIDateStringToDate(dtmInstallDate)
    WMIDateStringToDate = CDate(Mid(dtmInstallDate, 5, 2) & "/" & _
        Mid(dtmInstallDate, 7, 2) & "/" & Left(dtmInstallDate, 4) _
            & " " & Mid (dtmInstallDate, 9, 2) & ":" & _
                Mid(dtmInstallDate, 11, 2) & ":" & Mid(dtmInstallDate, _
                    13, 2))
End Function

'ForWriting is to write to file from start. ForAppending is to write to file from end of file.

constForWriting = 2
constForAppending = 8
constTristate = 0
boolUnicode = False
chrCarriageReturn = chr(13)
chrNewLine = chr(10)

Set objFSO = CreateObject("Scripting.FileSystemObject")


'This is so that cscript won't encounter a runtime error if the file already exists. Also so that it will write to the already existing file.

If objFSO.FileExists(strPath)=False Then

 Set objErrLog = objFSO.CreateTextFile(strPath,constForWriting,boolUnicode)
  objErrLog.Write "Type,"
  objErrLog.Write "Time Generated,"
  objErrLog.Write "Source Name,"
  objErrLog.Write "Event Code,"
  objErrLog.Write "Category,"
  objErrLog.Write "Message"
  objErrLog.Writeline
 strTimeMin = "01/01/1970/0:00:00"
'19700101000000.000000-480

 Else Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,constTristate)

'Only need this if it writes from the line the file ends on, as opposed to starting on a new line (which I expect it will).

  objErrLog.WriteLine

End If

Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

'Querying Event Logs

Set colLoggedEvents = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'system' AND "_
 & "Type = 'Error'")

'Type='Error' instead of "1" because it is a WQL query, I think. I believe that it is searching the entries in a database that reference the Win32_NTLogEvent objects. So I am searching the values in the database as opposed to the properties of the objects they reference. Or perhaps not. WHen I echo the type property of every object in colLoggedEvents, cscript outputs "Error". So maybe the I'm reading the SDK wrong? At least it seems to be working.

'This is a comparison function which tells where string 2 occurs in string 1. Starts at 1.

constStart = 1
constCompareType = 0

'This loop writes the information to a .csv.

For Each objEvent In colLoggedEvents

 If objEvent.Timegenerated > strTimeMin Then
  strTimeMin = objEvent.TimeGenerated
 Else
 End If
 objErrLog.Write objEvent.Type & ","
 objErrLog.Write WMIDateStringToDate(objEvent.TimeGenerated) & ","
 objErrLog.Write objEvent.SourceName & ","
 objErrLog.Write objEvent.EventCode & ","

 constExist=InStr(constStart,objEvent.Message,chrCarriageReturn,constCompareType)+InStr(constStart,objEvent.Message,chrNewLine,constCompareType)

  If constExist = 0 Then
   objErrLog.Write objEvent.Category & ","
   objErrLog.Write objEvent.Message

  Else
   objErrLog.Write objEvent.Category

  End If

 objErrLog.WriteLine

Next

Any help would be greatly appreciated.

Adam Harvey
  • 55
  • 1
  • 2
  • 10

1 Answers1

2
  1. Loose the misconception that code 'might fix itself'
  2. Give the full error details (number, description, line identified) when asking a question
  3. Assuming that you got a "5 - Invalid procedure call or argument" error on a line starting with "objErrLog.Write" see here for an explanation.
  4. You claim you have tested a variant of your code using Unicode; you didn't, because:

The prototype of .CreateTextFile is

object.CreateTextFile(filename:string[, overwrite:bool[, unicode:bool]])

This clashes with your

objFSO.CreateTextFile(strPath,constForWriting,boolUnicode)

The prototype of .OpenTextFile is

object.OpenTextFile(filename:string[, iomode:enum[, create:bool[, format:enum]]])

This clashes with your

objFSO.OpenTextFile(strPath,constForAppending,constTristate)

So fix these blunders (yourself!), test with the file really opened for Unicode, and hope that assumption (3) holds.

Update wrt comments:

Please reflect upon "Give the full error details (number, description, line identified) when asking a question" in the context of:

I get an invalid procedure error after 68 members of colLoggedEvents when I have the file in ASCII.

vs

I get the error when I call the OpenTextFile method

The first statement implies that the 68th member contains characters that can't be written in ASCII/ANSI mode. Really/Correctly using Unicode output format will fix the problem, provided the error log does not contain invalid data.

The second statement indicates that the parameters to the .Open/CreateTextfile methods are still not correct. Did you change both invocations to Unicode?

Update II:

The docs define

TristateTrue -1 Opens the file as Unicode.

Your code wrongly uses:

constTristate = 1 
Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,boolCreate,constTristate) 

Evidence:

>> Set ts = goFS.OpenTextFile("error5.txt", 8, False, 1)
>>
Error Number:       5
Error Description:  Invalid procedure call or argument
>> Set ts = goFS.OpenTextFile("error5.txt", 8, False, -1)
>>
>> <-- no news are good news

Update wrt comment concerning TriStateTrue:

The VBScript doc say:

TristateUseDefault -2 Opens the file using the system default.
TristateTrue       -1 Opens the file as Unicode.
TristateFalse       0 Opens the file as ASCII.

The doc @Adam refered to concerns VBA; but I wouldn't trust it without a check.

Community
  • 1
  • 1
Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
  • Yes, I noticed that I forgot to include the create options. Which I have now fixed. I was in a rush because it was frustrating me yesterday. So I missed that option by mistake. After fixing that problem, changing to unicode makes the problem appear sooner. I get an invalid procedure error after 68 members of colLoggedEvents when I have the file in ASCII. But in Unicode it doesn't get through any. Also, I did not mean that the problem would fix itself. I meant that it may be fixed by doing what I said. Because I'd be changing the relevant section of code anyway. – Adam Harvey Aug 07 '14 at 19:26
  • I meant to say that I get the error when I call the OpenTextFile method. But I accidentally pressed enter before I meant to. So my reply posted and I took too long to edit it. I have checked all of the options for OpenTextFile, and it seems it should all be working now. I have: 'Options for OpenTextFile constForAppending = 8 boolCreate = False constTristate = 1 Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,boolCreate,constTristate) – Adam Harvey Aug 07 '14 at 19:35
  • I definitely changed both to unicode. The createtextfile method reads Set objErrLog = objFSO.CreateTextFile(strPath,boolOverwrite,boolUnicode) with boolOverwrite=False and boolUnicode=True. The OpenTextFile method reads Set objErrLog = objFSO.OpenTextFile(strPath,constForAppending,boolCreate,constTristate), with constForAppending=8, boolCreate=False, and constTristate=1. I have gone over it again and again, making sure that I have the right values. But it is erroring out at the OpenTextFile call. The CreateTextFile call is fine. – Adam Harvey Aug 07 '14 at 20:32
  • @AdamHarvey - Please see Update II. – Ekkehard.Horner Aug 07 '14 at 21:41
  • Well, changing the sign on the tristate fixed it. So thanks for the help. The really odd thing, though, is that on MSDN it says positive 1. I double checked just now to make sure I hadn't somehow misread it 20 times. I'm looking at this page (http://msdn.microsoft.com/en-us/library/aa265347(v=vs.60).aspx). What documentation are you using? – Adam Harvey Aug 11 '14 at 14:56
  • I was just looking at this old post and realized that I should update it. I wasn't paying enough attention to the header on MSDN and was just reading the wrong page. So no need to panic about typoes on there. Though I will admit I have seen some before that are legitimate typoes. – Adam Harvey Oct 24 '14 at 21:06